# 言問散歩 Vol.16 全員経営営業アプリ 設計仕様書

**作成：** 2026-06-06  
**作成者：** CTO（エンジニアリング大臣）  
**目的：** CEO要望「月曜（2026-06-09）にモックで実使用できる全員経営営業アプリ」への技術回答  
**前提データ：** meiten-master.json（202店・nba優先度/claimedBy/vol16フィールド対応済）+ targets.json（Vol.16 目標¥1,800,000）  
**決裁ゲート：** 本文末尾に明記（3〜5点・CEO決裁が要るもの）

---

## 0. 結論（1画面サマリ）

**推奨アーキ：選択肢A（vanilla HTML単一ファイル + hq-server.py書込API + Googleスプレッドシート正本 + Cloudflare Tunnel公開https）**

| 項目 | 結論 |
|---|---|
| アーキ推奨 | A（既存HTML拡張）→月曜デモはTailnet限定・公開は来週CEO決裁後 |
| 月曜デモ形態 | Tailnet内（hq-server.py:8788）でモック動作。社員到達はデモ後に決裁 |
| 正本データ | Googleスプレッドシート（id: 17cmBSwKrH_fTGGg4VblIC8ukqPCMssDISMGWZ_zR6l8）+ ローカルJSON補完 |
| 書込API | hq-server.pyに4エンドポイント追加（claim/unclaim/visit-log/vol16-update） |
| 認証 | 月曜デモ：担当者名セレクトボックス（12名リスト）。重認証は後フェーズ |
| Codex投入 | 金夜〜日で3単位を夜勤製造ライン |

---

## 1. アーキ選定（月曜実現性で判断）

### 比較（CEO要望の5軸で評価）

| 軸 | A: HTML+hq-server拡張 | B: Glide | C: Next.js+Supabase |
|---|---|---|---|
| 多人数同時編集 | Googleスプレッドシート正本・複数人が書込API経由で追記 → 競合は「最後の追記が勝つ」行単位・実用上十分 | Sheets正本・Glideが管理 → 同等 | 完全対応 → overengineering |
| 真実源（SoR） | Sheetsが正本・HTMLはAPI越しに読む | Sheets正本 → 同等 | Supabase等 → 別DB |
| 社員のスマホ到達 | **Tailnet限定**（デモ段階）→ Cloudflare Tunnel（https公開）でCEO決裁後に解決 | Glide SaaSなので即到達 | デプロイ要 |
| 認証（誰が操作したか） | セレクトボックス12名（月曜デモ）→ 後でGoogle OAuth追加 | Google OAuth標準 | 完全実装可 |
| 月曜実現性 | **最高**（既存資産を拡張・Codex実装可） | 中（Glideのアプリ構築6〜8時間・アカウント制約リスク） | 低（新スタック・工数大） |
| 運用コスト | 月0円（hq-serverは既存・Cloudflare Tunnel無料枠あり） | 月$49〜$99（要確認・費用ゲート） | Vercel/Supabase月$20〜 |

### overengineering チェック

- Glide：月曜モックの「担当宣言+記録+Vol.16進捗」3機能に対してGlideアカウント設定・シート接続・UIビルドを一から行うのは、**既存HTMLを拡張するより工数が大きく確実性が低い**。Glide有料プランは費用ゲートでもある。月曜デモ後にCEO判断して移行を検討する価値はあるが、初期実装には採用しない。
- Next.js/Docker/Supabase：明確な過剰実装。採用禁止。

### 推奨：選択肢A

**理由：** 既存 `meiten-db.html`（700行・vanilla・動作実証済）を拡張するだけで月曜デモが成立する。書込APIはhq-server.pyが既にPOSTハンドラを持つため追記コスト小。Googleシート正本はOAuth Desktop App方式（`ops/token_drive.json`）で既に読み書き可能。Codex夜勤ラインで金夜〜日に実装完了させる現実的なパスが最も明確。

---

## 2. アーキテクチャ詳細

```
[社員スマホ]
    ├─ デモ段階：Tailscale接続 → http://100.76.239.118:8788/meiten-sales.html
    └─ 公開段階：https://<tunnel>.trycloudflare.com/meiten-sales.html  ← CEO決裁後

[hq-server.py :8788]
    ├─ GET  /meiten-sales.html    → 単一HTMLファイル配信
    ├─ GET  /api/meiten-data      → meiten-master.json + visit_logs読込（統合JSON）
    ├─ POST /api/claim            → 担当宣言/解除 → Sheets claims書込
    ├─ POST /api/visit-log        → アクション記録追加 → Sheets visit_logs書込
    ├─ POST /api/vol16-update     → 商談status/amount更新 → Sheets vol16_deals書込
    └─ GET  /api/vol16-summary    → Vol.16進捗集計（targets.json + Sheetsデータ）

[Googleスプレッドシート 正本 id: 17cmBSwKrH_fTGGg4VblIC8ukqPCMssDISMGWZ_zR6l8]
    ├─ stores        : meiten-master（既存 or 移行）
    ├─ visit_logs    : アクション記録（全員追記）
    ├─ claims        : 担当宣言（storeId / rep / claimedAt / active）
    ├─ vol16_deals   : 商談進捗（storeId / status / amount / rep / updatedAt）
    └─ field_intel   : 情報追加（誰でも）

[meiten-master.json  ローカル正本]
    └─ 読取専用ソース（Sheetsへの完全移行はPhase 2）
       月曜デモはJSONから読んでAPIが差分マージ
```

**月曜デモ時の簡略構成：**
- Googleシート書込はPython側（hq-server.py）が担当。フロントは `/api/*` のみ叩く。
- meiten-master.jsonはローカル読取で十分。シートへの完全移行はデモ後。

---

## 3. データモデル（追加・拡張フィールド）

### 3-1. stores シート（meiten-master.jsonから展開）

既存202フィールドを継承。以下を追加：

| フィールド | 型 | 説明 |
|---|---|---|
| claimedBy | string | 担当宣言者の名前（空=未宣言） |
| claimedAt | datetime | 宣言日時 |
| lastVisitDate | datetime | 最終接触日（visit_logsから自動集計） |
| visitCount | int | 累計アクション数 |
| vol16status | string | Vol.16商談状態（未着手/商談中/受注/NG） |
| vol16amount | int | Vol.16確定金額 |

### 3-2. visit_logs シート（新規・全員経営の核心）

| フィールド | 型 | 説明 |
|---|---|---|
| visitId | string | UUID（クライアント生成） |
| storeId | string | FK → stores.storeId |
| storeName | string | 店舗名（非正規化・検索性のため） |
| rep | string | 担当者名（12名リストから選択） |
| visitedAt | datetime | アクション日時 |
| type | string | 種別：挨拶/訪問/商談/受注/情報/電話 |
| summary | string | 自由メモ |
| nextAction | string | 次アクション（任意） |
| nextActionDate | date | 期日（任意） |
| vol16statusChange | string | このアクションでvol16 statusが変わった場合 |
| vol16amountChange | int | このアクションでvol16 amountが変わった場合 |
| createdAt | datetime | 記録日時 |

### 3-3. claims シート（担当宣言・ロック管理）

| フィールド | 型 | 説明 |
|---|---|---|
| storeId | string | FK → stores |
| rep | string | 宣言者 |
| claimedAt | datetime | 宣言日時 |
| active | boolean | true=有効宣言 |
| releasedAt | datetime | 解除日時（active=false時） |

**宣言ロックルール：** active=trueのレコードが存在する店は、別の担当者が「宣言」ボタンを押せない。UI上でグレーアウト+現担当者名表示。解除は宣言者本人のみ（または Admin）。

### 3-4. vol16_deals シート（商談進捗・積み上げ集計の正本）

| フィールド | 型 | 説明 |
|---|---|---|
| storeId | string | FK → stores |
| storeName | string | 非正規化 |
| rep | string | 担当者 |
| status | string | 未着手/商談中/受注確定/NG |
| amount | int | 金額（円）。受注確定のみ集計対象 |
| pipelineAmount | int | 商談中の見込み金額 |
| updatedAt | datetime | 最終更新 |
| updatedBy | string | 更新者 |

**Vol.16集計ロジック：**
```
achieved = vol16_deals where status=受注確定 の amount合計
pipeline = vol16_deals where status=商談中 の pipelineAmount合計
remaining = target(¥1,800,000) - achieved
```

---

## 4. 画面設計

### 4-1. 全体構造（シングルHTML・4画面 + ヘッダーナビ）

```
[ヘッダー固定]
  ロゴ "言問散歩 営業"  |  担当者選択ドロップダウン  |  ダーク切替
  [タブ] 優先リスト | ダッシュボード | 活動フィード

[タブ①：優先リスト]  ← 既存meiten-db.htmlを営業モードに拡張
[タブ②：Vol.16ダッシュボード]  ← 新規
[タブ③：活動フィード]  ← 新規

[店舗詳細シート（ボトムシート・オーバーレイ）]  ← 既存を拡張
```

---

### 4-2. タブ①：優先リスト（既存拡張）

**コンセプト：** nba優先度（P0/P1/P2/P3）順に全202店を表示。商談中は別フィルタにせず、優先リストに統合してstatusバッジで視覚化（CEO要望⑤）。

**カード1枚に表示する情報：**
```
[P0] 花やしき ★★★  [商談中 ¥50,000]
     継続広告主 / 浅草 / 観光
     担当: 阿部  最終接触: 3日前
     [宣言する] or [宣言中: 阿部] [記録する]
```

**フィルタ（クイックビュー）：**
- 全て | 担当宣言なし | 自分の担当 | 商談中 | Vol.16候補 | 要フォロー（nextActionDate < 今日）

**優先度バッジの意味（nba.priority）：**
- P0（赤）: 最優先・即アタック。202店中3店。
- P1（橙）: 高優先・今週中。63店。
- P2（黄）: 通常優先。46店。
- P3（灰）: 余裕があれば。90店。

**Vol.16 statusバッジ（CEO要望⑤：リストに統合）：**
- 商談中（青バッジ）: 優先度順に並べたまま色で区別
- 受注確定（緑バッジ）
- NG（灰バッジ）

---

### 4-3. 店舗詳細シート（ボトムシート・既存拡張）

**現状のボトムシートに以下を追加：**

**セクション1：アクション（新規）**
```
[担当宣言する]  →  宣言済み: 阿部 (2026-06-07) [解除]
```

**セクション2：アクション記録（新規）**
```
[+ 記録を追加]
  ↓ インラインフォーム展開
  種別: [挨拶▼] [訪問▼] [商談▼] [受注▼] [情報▼] [電話▼]
  メモ: _________________________
  次アクション: _________ 期日: ___
  Vol.16: [変更なし▼]  金額: _____
  [保存する]
```

**セクション3：Vol.16 商談状態（新規）**
```
状態: [商談中▼]  見込み: ¥50,000
      → [未着手▼][商談中▼][受注確定▼][NG▼] で即更新 → Vol.16集計に反映
```

**セクション4：過去アクション履歴（新規）**
```
2026-06-05  阿部  商談  「社長と面談。前向きな反応。見積もり希望」  → 電話フォロー
2026-06-01  金井  挨拶  「店頭で散歩渡した」
```

**セクション5：情報追加（既存拡張）**
```
[+ 情報を追加]  （全員が自由記述）
種別: [飲食中▼][知人情報▼][SNS▼][現地観察▼]
内容: _________________________
```

---

### 4-4. タブ②：Vol.16ダッシュボード（新規・全員閲覧）

**コンセプト：** 目標¥1,800,000に対するリアルタイム積み上げ。商談進捗を更新すると自動反映（CEO要望⑥）。

```
┌─────────────────────────────────────┐
│  Vol.16 売上目標                      │
│                                      │
│  目標  ¥1,800,000                    │
│  ┌──────────────────────────────┐   │
│  │  受注確定  ■■■■■□□□□□□□  ¥0  │
│  │  商談中    ■□□□□□□□□□□□ ¥390k│
│  └──────────────────────────────┘   │
│  残額  ¥1,800,000  (達成率 0%)       │
│                                      │
│  ───── 担当者別内訳 ─────          │
│  阿部  受注 ¥0   商談中 ¥100k        │
│  石井  受注 ¥0   商談中 ¥190k        │
│  金井  受注 ¥0   商談中 ¥100k        │
│                                      │
│  ───── 商談中一覧（優先度順） ─────│
│  P1 花やしき    ¥50k   阿部  更新5d  │
│  P1 うぶけや    ¥50k   石井  更新3d  │
│  ...（10件）                         │
└─────────────────────────────────────┘
```

**進捗バーの集計ロジック：**
- 受注確定バー：vol16_deals where status=受注確定 の amount合計
- 商談中バー：vol16_deals where status=商談中 の pipelineAmount合計
- 残額 = ¥1,800,000 - 受注確定合計
- 到達率 = 受注確定 / 目標 × 100

---

### 4-5. タブ③：活動フィード（新規・全員経営の可視化）

**コンセプト：** 誰が何をしたかが時系列で流れる。チームの活動が「見える化」される。

```
[今日]
  ● 阿部 → 花やしき「商談。社長と面談、前向き」  14:30
  ● 金井 → うぶけや「訪問。担当者不在、名刺置いてきた」  11:00

[昨日]
  ● 石井 → 駒形どじょう「挨拶。散歩渡した」  16:45
  ● 宮内 → かっぱ橋珈琲店「情報。SNSでリニューアル告知を発見」  09:15

[2026-06-05]
  ...
```

**フィルタ：** 全員 / 自分のみ / 担当店のみ

---

## 5. 月曜までの工程（Codex夜勤ラインへの発注単位）

### 全体タイムライン

```
2026-06-06（金）22:00〜  Codex Unit 1 投入
2026-06-07（土）朝  Unit 1 成果確認・Unit 2 投入
2026-06-07（土）夜  Unit 2 成果確認・Unit 3 投入
2026-06-08（日）朝  Unit 3 成果確認・統合テスト
2026-06-08（日）14:00  CTO動作確認 + デモ準備
2026-06-09（月）  実使用
```

---

### Unit 1：hq-server.py 書込API 4エンドポイント（金夜）

**Codex発注プロンプト（コピーして投入）：**

```
既存ファイル C:\Users\daito\company\ops\hq-server.py に、
以下の4エンドポイントを追加してください。

前提：
- Googleスプレッドシート ID: 17cmBSwKrH_fTGGg4VblIC8ukqPCMssDISMGWZ_zR6l8
- 認証: C:\Users\daito\company\ops\token_drive.json (OAuth Desktop App方式・drive.fileスコープ)
- gspread ライブラリを使用（pip install gspread google-auth）
- 既存サーバーの構造（BaseHTTPRequestHandler）を維持し追記のみ

エンドポイント仕様：

1. GET /api/meiten-data
   - C:\Users\daito\company\projects\kototoi-sanpo-editorial\meiten-business\data\meiten-master.json を読み込む
   - Sheetsの claims シート（storeId, rep, claimedAt, active）を読み込む
   - Sheetsの visit_logs シート を読み込む（シートがなければ空配列）
   - Sheetsの vol16_deals シート を読み込む（シートがなければ空配列）
   - JSONをマージして返す：{ stores: [...], claims: [...], visit_logs: [...], vol16_deals: [...] }
   - CORS: Access-Control-Allow-Origin: *

2. POST /api/claim
   - body: { storeId, rep, action: "claim" | "unclaim" }
   - Sheets "claims" シートに追記（action=claimなら active=true の新レコード）
   - action=unclaimなら対象storeId の active=true レコードを active=false に更新
   - 成功: { ok: true }
   - シートが存在しない場合は自動作成（headers: [storeId, rep, claimedAt, active, releasedAt]）

3. POST /api/visit-log
   - body: { visitId, storeId, storeName, rep, visitedAt, type, summary, nextAction, nextActionDate, vol16statusChange, vol16amountChange }
   - Sheets "visit_logs" シートに1行追記（createdAt=サーバー現在時刻を付与）
   - シートが存在しない場合は自動作成
   - 成功: { ok: true }

4. POST /api/vol16-update
   - body: { storeId, storeName, rep, status, amount, pipelineAmount, updatedBy }
   - Sheets "vol16_deals" シートで storeId が一致する最新レコードを更新（なければ新規追加）
   - updatedAt=サーバー現在時刻
   - 成功: { ok: true, summary: { achieved, pipeline, remaining } }
   - 集計: achieved = status=受注確定 の amount合計, pipeline = status=商談中 の pipelineAmount合計, remaining = 1800000 - achieved

5. GET /api/vol16-summary
   - Sheets vol16_deals と C:\...\data\targets.json を読んで集計
   - 返す: { target: 1800000, achieved: 0, pipeline: 390000, remaining: 1800000, byRep: [{rep, achieved, pipeline}], deals: [{storeId, storeName, status, amount, rep, updatedAt}] }

エラー処理: 例外は {ok:false, error:"..."} で返す（500で落とさない）
```

**入出力：** `C:\Users\daito\company\ops\hq-server.py` を更新  
**工数目安：** Codexで40〜60分

---

### Unit 2：meiten-sales.html（営業アプリ本体）（土昼）

**Codex発注プロンプト：**

```
以下の仕様で C:\Users\daito\company\projects\kototoi-sanpo-editorial\meiten-business\meiten-sales.html を新規作成してください。

既存参照: C:\...\meiten-business\meiten-db.html（UIトークン・ライト/ダーク・ボトムシート・絞り込みの実装を流用）

仕様:

【全体構造】
- 単一HTML・vanilla JS・外部CDN不要
- ヘッダー（固定）: タイトル「言問散歩 営業」、担当者セレクト（後述）、ダーク切替
- タブナビ（固定・ヘッダー下）: [リスト] [ダッシュボード] [フィード]
- データ取得: 起動時に GET /api/meiten-data を叩いてメモリに持つ（30秒ごとに再取得）

【担当者セレクト（認証代替）】
- ヘッダー右に「担当者選択」セレクトボックス
- 選択肢: 阿部, 石井, 金井, 加藤, 満田, 宮内, 杉本, 山田（CEO）
- localStorage に保存し次回自動復元
- 未選択（初回）は赤枠で「担当者を選んでください」を強調表示

【タブ①：優先リスト】
- storesをnba.priorityScore降順でソート（高いほど上）
- 各カードに表示: 優先度バッジ(P0赤/P1橙/P2黄/P3灰)、店舗名、label、area.ward、最終接触日（visit_logsから）、アクション件数
- vol16 があれば status バッジ（商談中=青, 受注確定=緑, NG=灰）と金額を表示
- claimedBy があれば「担当: ○○」を表示（自分なら太字、他人なら薄字）
- 検索（店舗名・地区でフィルタ）
- クイックビュー: [全て] [担当なし] [自分の担当] [商談中] [P0/P1のみ]
- カードタップ → ボトムシート展開

【ボトムシート（店舗詳細）】
店舗名・住所・カテゴリ・優先度の基本情報（既存流用）に加えて:

セクション「担当」:
  - claimedBy が空 → [この店を担当する] ボタン → POST /api/claim { storeId, rep: 選択中の担当者, action:"claim" } → 成功でローカル状態更新
  - claimedBy が自分 → 「あなたが担当中」+ [担当を外す] ボタン → POST /api/claim action:"unclaim"
  - claimedBy が他人 → 「○○さんが担当中」グレー表示（宣言ボタン非表示）

セクション「記録を追加」:
  常時展開フォーム（折り畳みなし）:
  - 種別ボタン（横並びチップ選択）: 挨拶 / 訪問 / 商談 / 受注 / 情報 / 電話
  - メモ textarea（3行）
  - 次アクション input（任意）
  - 期日 date input（任意）
  - Vol.16更新チェックボックス: オンにすると status セレクト + 金額 input が出現
  - [保存する] → POST /api/visit-log → 成功でフィード更新

セクション「Vol.16状態」:
  - 現在のstatus（未着手/商談中/受注確定/NG）をセレクト表示
  - 金額 input（商談中=見込み, 受注確定=確定額）
  - [更新する] → POST /api/vol16-update

セクション「過去の記録」:
  - visit_logs のうちこの storeId のものを visitedAt 降順で5件表示
  - 「rep : type : summary (nextAction)」形式

【タブ②：Vol.16ダッシュボード】
- GET /api/vol16-summary を叩いてデータを使用
- 目標 ¥1,800,000 を大きく表示
- 受注確定バー（緑）と商談中バー（青）の積み上げプログレスバー（width=金額/目標*100%）
- 残額を赤字で大きく表示
- 担当者別テーブル: 担当者名 / 受注合計 / 商談中合計
- 商談中一覧（優先度順）: 店名 / 見込み額 / 担当者 / 最終更新
- [更新] ボタンで再取得

【タブ③：活動フィード】
- visit_logs を visitedAt 降順で表示
- 日付でグループ化（今日・昨日・日付）
- 各エントリ: 「担当者 → 店舗名『メモ』type 時刻」形式
- フィルタ: [全員] [自分のみ]

【UIトークン（meiten-db.htmlから継承）】
:root に同じ CSS変数（--bg, --card, --ink, --accent, --good, --bad, --warn, --info）
ライト/ダーク切替ボタン＋localStorage保存

出力: 単一HTMLファイル（外部依存なし）
```

**入出力：** `meiten-sales.html` 新規作成（700〜1200行）  
**工数目安：** Codexで60〜90分

---

### Unit 3：統合テスト + vol16_deals 初期データ投入スクリプト（土夜）

**Codex発注プロンプト：**

```
以下の2つのスクリプトを作成してください。

【スクリプト1】vol16_init.py
目的: meiten-master.json の vol16 フィールドを持つ10店分を Googleスプレッドシートの vol16_deals シートに一括投入する。

仕様:
- 読込: C:\Users\daito\company\projects\kototoi-sanpo-editorial\meiten-business\data\meiten-master.json
- 認証: C:\Users\daito\company\ops\token_drive.json (gspread OAuth方式)
- 対象シートID: 17cmBSwKrH_fTGGg4VblIC8ukqPCMssDISMGWZ_zR6l8
- シート名: vol16_deals
- シートが存在しない場合は作成
- headers: [storeId, storeName, rep, status, amount, pipelineAmount, updatedAt, updatedBy]
- vol16フィールドを持つ全store を1行ずつ投入:
  - status: vol16.status（受注済→受注確定, 商談中→商談中）
  - amount: vol16.status=受注確定なら vol16.amount else 0
  - pipelineAmount: vol16.status=商談中なら vol16.amount else 0
  - rep: vol16.rep（空なら空文字）
  - updatedBy: "初期投入"
- 実行後に集計サマリを出力: 受注確定合計, 商談中合計, 残額

【スクリプト2】api_test.py
目的: hq-server.py の新APIエンドポイントを動作確認する。

仕様:
- BASE_URL = "http://localhost:8788"
- テスト1: GET /api/meiten-data → stores数, claims数, visit_logs数を表示
- テスト2: POST /api/claim { storeId:"MTN-063", rep:"テスト太郎", action:"claim" } → レスポンス表示
- テスト3: POST /api/visit-log { visitId:"TEST-001", storeId:"MTN-063", storeName:"テスト店", rep:"テスト太郎", visitedAt:"2026-06-09T10:00:00", type:"挨拶", summary:"APIテスト", nextAction:"", nextActionDate:"", vol16statusChange:"", vol16amountChange:0 } → レスポンス表示
- テスト4: GET /api/vol16-summary → achieved/pipeline/remaining を表示
- テスト5: POST /api/claim { storeId:"MTN-063", rep:"テスト太郎", action:"unclaim" } → 宣言解除

出力先: C:\Users\daito\company\projects\kototoi-sanpo-editorial\meiten-business\mvp\vol16_init.py
出力先: C:\Users\daito\company\projects\kototoi-sanpo-editorial\meiten-business\mvp\api_test.py
```

**工数目安：** Codexで20〜30分

---

## 6. リスクと代替（Cloudflare間に合わない時）

### リスク①：Cloudflare Tunnel が月曜に間に合わない

**発生確率：** 中（設定は10分程度だが、CEO決裁が先に必要なため）

**代替：** 月曜デモは **Tailnet限定** で実施。CEOと編集長はTailscaleで接続済みのため動作確認可能。社員への配布は火曜以降にCEO決裁後。

**Cloudflare Tunnel は無料で動く：**
```bash
# Windows (Codex に実行させる or CTO手動)
winget install cloudflare.cloudflared
cloudflared tunnel --url http://localhost:8788
# → https://xxxxxx.trycloudflare.com が発行される（無料・要登録不要の一時URL）
```

### リスク②：hq-server.py の Sheets 書込が失敗

**発生確率：** 低〜中（OAuth token_drive.json のスコープが drive.file のみの場合、既存シート以外への書込が拒否される可能性）

**代替1：** 月曜デモはローカルJSON（meiten-master.json + インメモリ配列）だけで動かすフォールバックモードを実装。記録はlocalStorageに保存し、後でシートに手動移行。

**代替2：** Sheetsを使わず、hq-server.py がJSONファイルに直接書き込む（visits.jsonl形式）。永続化は確保しつつSheets連携はPhase 2に先送り。

### リスク③：Glide への移行判断（将来）

月曜デモ後に「社員スマホへの本格展開」でGlide有料プランの費用対効果判断が発生する（費用ゲート）。Glideの場合は月¥7,000〜¥14,000（要確認）vs 自前HTML+Cloudflare=月0円。自前の場合の追加工数（認証・UI改善）と費用を比較して判断。

---

## 7. CEO決裁点（3〜5点）

以下の判断はCTOが代わりに決められない。月曜デモ後に判断を仰ぐ順番で列挙。

### 決裁①：月曜デモの実施形態 ← 今すぐ決裁が要る

- **A案（推奨）：** Tailnet限定でデモ（社員未配布・CEO+編集長+CTO内輪確認）→ 火曜以降に社員展開
- **B案：** 金曜夜にCloudflare Tunnel設定 → 月曜から社員全員に配布

**CTO推奨：** A案。B案はCloudflare公開=外部連絡ゲート（社員のスマホに届く=本番運用開始）であり、CEO確認なく動かすべきではない。月曜はまずTailnetで動作確認し、「このUIで行く」を確認してから全社公開。

### 決裁②：社員のスマホへの公開 ← 外部公開ゲート

Cloudflare Tunnel（または社員Tailscale参加）によるhttps公開は、**社外のデバイスにアプリを届ける行為 = 外部連絡ゲート**に該当する。

- 選択肢A: Cloudflare Tunnel（無料・設定10分・https://xxx.trycloudflare.com）
- 選択肢B: 社員全員がTailscale参加（無料・設定は社員側作業が要る）
- 選択肢C: Glide SaaS移行（費用ゲート込み・月$49〜$99）

**CTO推奨：** A（Cloudflare Tunnel）が最小手順で最速。URLを社員にLINE/チャットで配布するだけ。

### 決裁③：Glide移行の判断 ← 費用ゲート（将来）

月曜デモ後に「自前HTML+Cloudflare vs Glide有料プラン」の本格判断が発生する。

- 自前HTML：月0円・機能追加はCodex工数が要る
- Glide Maker：月$49程度（要確認）・機能追加がノーコード・言問手形と同じスタック

**CTO判断（暫定）：** まず自前で走らせて6週間後に「使われているか」を計測してから判断。使われていない機能に課金しない。

### 決裁④：担当者マスターの確定 ← 人事情報

現在の担当者マスター（11名：阿部/石井/金井/加藤/満田/宮内/杉本 + 山田CEO等）はソースファイルが不完全。アプリの「担当者選択」に誰を入れるか確定が要る。

**CTO確認事項：** 対象は石井上長配下の営業担当のみか、CEO山田も含めるか。パート/契約社員は入れるか。

### 決裁⑤：Vol.16目標金額の確定 ← 経営判断

`targets.json` の `target: 1800000` は「提案値」とノートされている。ダッシュボードの「目標¥1,800,000」を正式採用するかCEOが確定させる。変更する場合はtargets.jsonを更新するだけで即反映。

---

## 8. Codex発注パッケージ（コピー&ペースト用まとめ）

週末のCodex夜勤ラインへの投入順序：

```
【発注1: 金夜22:00】
タスク: hq-server.py に5エンドポイント追加
ファイル: C:\Users\daito\company\ops\hq-server.py
詳細: 本仕様書 §5 Unit 1 のプロンプトを使用

【発注2: 土朝（Unit1確認後）】
タスク: meiten-sales.html 新規作成
ファイル: C:\Users\daito\company\projects\kototoi-sanpo-editorial\meiten-business\meiten-sales.html
詳細: 本仕様書 §5 Unit 2 のプロンプトを使用
参照: meiten-db.htmlのCSS変数・ボトムシートの実装を取り込む指示を含める

【発注3: 土夜（Unit2確認後）】
タスク: 初期データ投入 + APIテストスクリプト
ファイル: meiten-business\mvp\vol16_init.py + api_test.py
詳細: 本仕様書 §5 Unit 3 のプロンプトを使用

【日曜: 統合・確認】
- CTO が hq-server.py 起動 → api_test.py 実行 → vol16_init.py 実行 → ブラウザで meiten-sales.html を確認
- 不具合は Codex に追加修正発注（Unit 4 として投入）
- Tailnet で CEO に事前確認リンクを送付: http://100.76.239.118:8788/meiten-sales.html
```

---

## 9. 世界水準UIの要件（web-designerへの引き渡しメモ）

月曜モック後、UIの本格仕上げを `web-designer` に渡す前提で要件を明記する。

**必須：**
- ライト/ダーク両対応（meiten-db.htmlのトークンを継承）
- スマホ最適化（iOS Safari・Android Chrome）。タップターゲット最小44px。
- P0/P1/P2/P3の優先度バッジは色と形の両方で区別（色覚多様性対応）
- 進捗バー（Vol.16ダッシュボード）はアニメーション付き（mount時に伸びる）
- 活動フィードは最新が上・時刻はrelative（「3分前」「昨日」）

**指針：**
- 「営業ツール」の文脈。情報密度を高く・余白は機能的に使う。
- 担当宣言ボタンは「宣言した人が見える」カード全体を軽く塗り替えるデザイン。
- Vol.16ダッシュボードは「残額」を最も大きなフォントで。動機付けのため。
- フィードは「チームが動いている感」を出す。アイコン・色・タイムスタンプで読む気になるデザイン。

---

## 10. overengineering チェック（最終）

| 要素 | 判定 | 理由 |
|---|---|---|
| Next.js / Vite / TypeScript | 過剰 | vanilla HTMLで十分。型安全より月曜デモの方が重要 |
| Docker / k8s | 過剰 | 禁止 |
| WebSocket（リアルタイム） | 過剰 | 30秒ポーリングで十分 |
| JWT / セッション認証 | 過剰（月曜デモ段階） | セレクトボックス選択で十分。社員に悪意はない |
| Supabase / PlanetScale | 過剰 | Googleスプレッドシートで十分 |
| Glide（月曜デモ段階） | 過剰 | 既存HTML拡張の方が確実・速い |
| 担当者ロック（楽観的ロック） | 適正 | 担当宣言の重複防止は必須要件 |
| 30秒ポーリング | 適正 | シンプル・確実・実装コスト最小 |

---

*本仕様書：CTO作成。CEO決裁5点の回答をもってCodex発注着手可。*  
*決裁①（デモ形態）は最優先で確認すること。*
