# 学習プラットフォーム API への要件（こちら側から必須のもの）2026-10-09

- 読み手: キヨさん、およびキヨさんが使う AI
- 対象: SPI 対策コース（11 月販売予定）で使う学習プラットフォームの API（AI 動画講義・インタラクティブ Web テキスト・確認問題）
- 目的: 販売（Stripe 中心の体制）・会員・学習データ・運用と矛盾なくつながるよう、API 側で最初から満たしてほしいことを伝える。画面（フロント）の作りには立ち入らない。
- 関連: 「販売管理を Stripe 中心で組む案」（2026-10-09・同じ置き場）

---

## 1. 前提（事実）
- 会員の正本は本番 D1 `educare-poc` の `users`。会員サイトと管理画面が同じ D1 を読んでいる。名寄せで統合された会員は `users.status='merged'` として残り、統合先が記録される。
- 販売は Stripe 中心に組み替える方針。値段・決済・返金は Stripe、**「誰がどの教材を見てよいか」の判定（権利）は自社**が持つ。権利は新しい権利表（`entitlements`）に付け、教材の閲覧判定をそこへ切り替える。
- 会員サイトには既に教材用の表（`courses`・`lessons`・`lesson_progress`・`course_previews`、公開範囲の `access_policy`、版の `revision`）がある（ステージングで稼働中・本番には未投入）。
- SPI の受験と確認問題の結果は、SPI・SCOA の分析 DB（D1 `educare-content-ledger`）で問題の版ごとに集計する仕組みを作っている。会員を特定できる列はそこに入れない。
- D1 は 10/4〜10/5 に読み取りの日次上限を超えて会員サイトが止まった（原因は全件読みと OFFSET によるページ送り）。書き込みも日によって上限の 7〜9 割に達している。

## 2. 必須の要件（M）と推奨（S）

### A. 会員と認証
| ID | 要件 | 必須度 |
|---|---|---|
| A-1 | 会員は既存の `users.id` をそのまま使う。独自の会員表・独自のログインを作らない。認証は会員サイトと同じセッションで行う。 | M |
| A-2 | 統合済み（`merged`）の会員を受けたら統合先の会員として扱う。進捗・回答の付け替えに耐える持ち方にする。 | M |
| A-3 | 退会したら、その会員の進捗・回答を消すか、会員と結び付かない形にできる。（10/7 の個人情報保護委員会の注意喚起で、不要になった個人データの消去が改めて求められている） | M |

### B. 販売・権利とのつなぎ
| ID | 要件 | 必須度 |
|---|---|---|
| B-1 | **値段を教材側に持たない**。値段は Stripe と販売台帳が持つ。 | M |
| B-2 | コース・レッスンに**変わらない ID** を付ける。販売は「コース ID の集合」で売り、権利もコース単位で付ける。 | M |
| B-3 | 本文・動画・確認問題を返す**すべての API で、サーバー側で閲覧可否を判定**する。判定は自社の権利判定 1 か所を呼ぶ（API ごとに独自の判定を書かない）。画面で隠すだけは不可。 | M |
| B-4 | 無料で見せるレッスン（お試し）をレッスン単位で指定できる。無料部分も会員登録が前提（未登録のお試しは作らない方針）。 | M |
| B-5 | コースとレッスンに**下書き／公開**の状態を持ち、**公開版と編集中の版を分ける**（公開中の中身を壊さずに次の版を作れる）。 | M |
| B-6 | 「このコースは公開済みで、全レッスンに本文があるか」を返せる（販売開始前の検査に使う）。 | M |
| B-7 | 購入者がいる、または販売中のコースは、公開版を消したり下書きに戻したりできない（止めるなら販売停止が先）。 | M |
| B-8 | 管理者が下書きを本番と同じ見た目で確認できる（URL を他人に渡されても見えない方式）。 | M |

### C. 中身の配信
| ID | 要件 | 必須度 |
|---|---|---|
| C-1 | 有料の動画・画像・テキストは、URL を知っていても権利が無ければ見られない（期限つきの署名 URL など）。 | M |
| C-2 | 動画などの置き場は Educare の Cloudflare アカウント（Praxia）の中にする。他事業のアカウントや個人のアカウントに置かない。 | M |
| C-3 | AI 動画講義・テキストは事前に作ったものを配る。会員の個人データを外部の AI に送らない作りにする（送る必要が出たら事前に相談）。 | M |

### D. 学習データ
| ID | 要件 | 必須度 |
|---|---|---|
| D-1 | 確認問題の回答を **1 問 1 行**で残す: 会員 ID・問題 ID・**問題の版**・選んだ答え・正誤・回答時刻・所要時間。版が分からない回答を作らない。 | M |
| D-2 | 確認問題の問題 ID を、既存の SPI 問題バンクの ID・単元と対応付けられるようにする（分析 DB で単元ごとの弱点を出すため）。 | S |
| D-3 | 進捗（レッスンの開始・完了・動画の視聴位置）を API で返す。マイページの学習記録で使う。 | M |
| D-4 | テスト会員（`users.is_test_account=1`）の記録を区別できる（集計から外すため）。 | M |

### E. 運用・コスト・安全
| ID | 要件 | 必須度 |
|---|---|---|
| E-1 | D1 の節約: 一覧は keyset 方式でページ送り（**OFFSET は使わない**）、表の全件読みをしない、必要な索引を張る。 | M |
| E-2 | 進捗の書き込みは間引く（視聴位置を毎秒送らない。一定間隔か、離脱・完了時にまとめて）。 | M |
| E-3 | 1 回の処理時間は 5,000ms 以内（全 Worker に入れる予定の上限）。 | M |
| E-4 | 管理画面や AI からの**読み取り（GET）は、管理用の service token で通る**ようにする（AI が動作確認できるように）。書き込み・削除は人に限る。 | S |
| E-5 | ステージングで先に動かしてから本番へ出す。表の追加（migration）は本番 D1 に先に当ててからコードを出す。 | M |
| E-6 | 主な操作（レッスン開始・完了・確認問題の回答・購入導線の押下）を計測イベントとして送れる（流入 → 会員 → 購入の計測に使う）。 | S |

## 3. 早めに決めたいこと（キヨさんに確認）
1. 既存の教材の表（`courses`・`lessons`・`lesson_progress`）を使うか、別の表を作るか。別にする場合も、B-2（変わらない ID）と B-3（判定 1 か所）は守りたい。
2. 動画の置き場（Cloudflare Stream か R2 か）と、署名 URL の方式。
3. 確認問題を既存の SPI 問題バンクから出すか、プラットフォーム専用に作るか（D-2 に影響）。
