このドキュメントは、現在の実装に合わせて更新した運用仕様です。過去の 仕様.MD を置き換える目的で作成しています。
renote/ # リポジトリルート
├─ public_html/ # Web公開ルート(実装済)
│ ├─ index.php # ログイン画面
│ ├─ about.php # サービス紹介ページ(公開)
│ ├─ child_dashboard.php # 子どもダッシュボード
│ ├─ child_challenge.php # 出題・回答(DB Mode)
│ ├─ practice.php # 出題・回答(Legacy Mode)
│ ├─ log_view.php # 子ども用ログ閲覧(Legacy/共通)
│ ├─ child_log_view.php # 子ども用ログ閲覧(DB Modeラッパー)
│ ├─ parent_log_view.php # 保護者/管理者ログ閲覧
│ ├─ guardian_question_settings.php # 出題条件設定(DB Mode)
│ ├─ guardian_learning_plan.php # 指導計画ボード
│ ├─ admin_dashboard.php # 管理者ダッシュボード
│ ├─ admin_problem_intake.php # 管理者問題投入(検査→登録)
│ ├─ admin_standard_problem_list.php # 標準問題一覧(検索/昇格)
│ ├─ admin_tuning_review.php # 単元チューニングレビュー
│ ├─ img.php # 非公開データ配信(qimg/abg/img)
│ ├─ api/db/ # DBモードAPI群
│ ├─ config/ # 共通設定・初期化
│ ├─ assets/ # 共通CSS/共通部品
│ ├─ lib/ # 共通ロジック(AI一次判定キュー等)
│ ├─ images/ # 画像アセット(公開用)
│ └─ specification.html # 本仕様書(HTML版)
├─ dev/ # 開発用ツール(非公開、実装済)
├─ private(_stg)/ # 非公開データ領域(環境に応じて切替)
├─ bin/ # 更新/反映/スナップショット用スクリプト
├─ tools/ # DB初期化・seed投入・運用補助
└─ problem_assets/ # 問題画像専用領域(未実装・導入予定)
※ 未実装項目:
- problem_assets/ への問題画像移設
- 問題画像キー3分離(question/base/model)のDB正式化
このセクションは「現行実装で利用中の主要ファイル」を対象に記載します。導入予定のみの項目は明示的に(未実装)と記載します。
| ファイル/ディレクトリ | 主目的 | 変更時の影響範囲 |
|---|---|---|
config/bootstrap.php | 共通初期化 | 全画面(ログイン後/前を含む) |
config/config.php | PRIVATE_DIR と各種設定ロード | データ保存先全体、STG表示、ユーザー読込 |
config/users_sqlite.php | ユーザーDBアクセス | ログイン、ユーザー一覧、親子管理 |
config/mariadb.php | MariaDB接続ヘルパー | DBモードAPI・移行スクリプト |
api/db/status.php | DBモード確認API | STGでのMariaDB接続確認・件数確認 |
assets/style.css | 全体スタイル | 全画面のレイアウト/視認性 |
dev/build_child_graph_data.php | 学習グラフ集計JSON生成 | child_dashboard / parent_log_view のグラフ表示整合 |
config/ # 設定・初期化のルート
├─ bootstrap.php # 共通初期化処理
├─ config.php # PRIVATE_DIR決定/ユーザー・教科ロード
├─ mariadb.php # MariaDB接続ヘルパー
├─ session.php # セッション管理
└─ settings/ # 設定分割ファイル群
├─ auth.php # 認証関連設定
├─ base_display.php # ロゴ/STG表示/LINE関連パス設定
└─ paths.php # DB・ログ等のパス生成定義
api/ # DBモード確認API
└─ db/
├─ curriculum_catalog_service.php # 標準カリキュラム取得サービス
├─ guardian_question_settings_preview.php # 出題設定プレビューAPI
├─ guardian_question_settings_save.php # 出題設定保存API
├─ guardian_question_settings_service.php # 出題設定共通サービス
├─ problem_bank_promotion_service.php # 問題昇格サービス
├─ problem_queue_service.php # AIキュー補助サービス
├─ problems_preview.php # 取込済み問題のプレビューJSON
└─ status.php # MariaDB接続・件数確認JSON
assets/ # 共通アセット
├─ child_footer.php # 子画面共通フッター
├─ child_header.php # 子画面共通ヘッダー
├─ parent_footer.php # 親画面共通フッター
├─ parent_header.php # 親画面共通ヘッダー
└─ style.css # 全体共通スタイル
dev/ はリポジトリ直下(public_html の1つ上)に配置し、Web直アクセスさせません。必要なWeb導線(ユーザー切替/セッション破棄)のみ public_html/dev/ に薄いラッパーを置きます。
dev/ # 開発/デバッグ補助(非公開)
├─ .htaccess # 開発ディレクトリ保護
├─ ai_tuning/run_tuning_loop.php # 単元別チューニング自動反復
├─ build_child_graph_data.php # 学習ログJSONを集計し graph_stats.json を生成
├─ UI仕様.html # UI仕様メモ
├─ kill_session.php # セッション破棄用ツール
├─ migrate_users_to_sqlite.php # users.json→SQLite移行
├─ run_ai_first_review_queue.php # AI一次判定キュー処理(cronから実行)
├─ lib/ai_first_review_worker.php # 非公開ワーカー本体(一次判定実行)
├─ show_stgmode.php # STG表示補助
└─ stg_switch_user.php # STG検証用ユーザー切替
(補足)
- dev/phpmyadmin_local/ # ローカルDB確認用の同梱ツリー(運用では非公開)
- public_html/dev/*.php # Web導線ラッパー(実体は ../dev/*.php を読み込む)
lib/ # 共通ロジック
├─ ai_first_review.php # 互換シム(queue専用ライブラリへの委譲)
└─ ai_first_review_queue.php # 公開側で使うAI一次判定キュー投入/結果反映処理
images/ # 画像アセット
├─ flow_of_study.png # サービス導線イメージ
├─ introduction_1.png # 紹介ページ用画像
├─ logotype.svg # 通常環境ロゴ(タイプ)
├─ logotype_stg.png # STG環境ロゴ(PNG)
├─ logotype_stg.svg # STG環境ロゴ(SVG)
├─ mainlogo.svg # 通常環境メインロゴ
├─ newIcon.png # 新着/更新系アイコン
├─ ok1Icon.png # 初回OKアイコン
├─ ok2Icon.png # 修正OKアイコン
├─ notlogedin.png # 未ログイン表示画像(PNG)
├─ notlogedin.svg # 未ログイン表示画像(SVG)
├─ okIcon.png # 汎用OKアイコン
└─ waitIcon.png # 待機アイコン
ユーザーや問題・ログの実体は、Webルート配下ではなく PRIVATE_DIR に保存します。
config/config.php が起動時に保存先を決定し、通常環境と STG 環境を切り替えます。
ここで示す構成は現行運用(実装済)です。問題画像専用領域 problem_assets/ への移設は次期改修(未実装)です。
{PRIVATE_DIR}/ # 非公開データルート
├─ users.json # 旧ユーザーマスタ(移行元として保持)
├─ users_prod.sqlite # 本番環境ユーザーマスタ(SQLite)
├─ users_test.sqlite # STG/テスト環境ユーザーマスタ(SQLite)
├─ key/ # 秘密情報ファイル
│ ├─ encryption_key.txt # ID/氏名復号の共通キー
│ ├─ line_channel_token.txt # LINE Messaging APIアクセストークン
│ ├─ line_user_id.txt # LINE送信先ユーザーID
│ └─ mariadb_credentials.php # MariaDB接続情報(wsl / xserver_stg / prod)
├─ parent/{parent_dir_uuid}/ # 保護者単位データ
│ ├─ subjects.json # 教科定義
│ ├─ {subject}.db # 親用問題DB
│ └─ {subject}_settings.txt # 親用教科設定
├─ child/{child_dir_uuid}/ # 子ども単位データ
│ ├─ {subject}.db # 子用問題DB(必要に応じて)
│ ├─ {subject}_settings.txt # 子用教科設定
│ ├─ graph_stats.json # child_dashboard グラフ表示用の集計JSON
│ └─ logs/ # 学習ログルート
│ ├─ {subject}/ # 教科別ログ
│ │ ├─ {timestamp}_{subject}_{tryNo}.json # 回答ログ本体
│ │ └─ img/{timestamp}_{subject}_{tryNo}_q{n}.(jpg|png|gif|webp) # 回答画像
│ └─ _pending/{session_id}/ # 回答中断時の一時退避
│ └─ q{n}.(jpg|png|gif|webp) # 一時退避画像
├─ queue/ai_first_review/ # AI一次判定ジョブキュー
│ ├─ in/ # 未処理ジョブ
│ ├─ processing/ # 処理中ジョブ
│ ├─ done/ # 処理済みジョブ
│ └─ failed/ # 失敗ジョブ(再実行対象)
└─ _pending/{session_id}/ # 修正提出中断時の一時退避
└─ rev_{lineNo}.(jpg|png|gif|webp) # 修正回答の一時退避画像
補足(key 配下): line_channel_token.txt / line_user_id.txt は現行コードで使用中です。
practice.php の回答保存時サマリー送信、および log_view.php の修正提出通知送信で読み込まれます。
mariadb_credentials.php は DBモードの接続先を環境別に切り替えるために使います。
ログイン可能ユーザーのマスタ。トップレベルは admins / parents / children の配列。
| 区分 | キー | 型 | 必須 | 説明 |
|---|---|---|---|---|
| 共通 | id_enc | string | 必須 | 暗号化済みログインID |
| 共通 | name_enc | string | 必須 | 暗号化済み表示名 |
| 共通 | password_hash | string | 必須 | password_hash() 形式 |
| 共通 | disabled | bool | 任意 | true のユーザーは読み込み対象外 |
| parents | dir_uuid | string | 必須 | parent/{dir_uuid} の対応先 |
| parents | maxchildren | number | 任意 | 子アカウント上限(未設定時 0 扱い) |
| parents | string | 任意 | 保護者通知先メールアドレス | |
| parents | child_label | string | 任意 | 子ども画面向けの保護者呼称 |
| children | parent_id_enc | string | 必須 | 親ログインID(暗号化) |
| children | dir_uuid | string | 必須 | child/{dir_uuid} の対応先 |
| children | enabled_subjects | string[] | 任意 | 有効教科キー配列(未設定時 空配列) |
| children | line_channel_token | string | 任意 | 子どもごとのLINEチャネルアクセストークン |
| children | line_user_id | string | 任意 | 子どもごとのLINE通知先ユーザID |
親ごとの教科定義。トップレベルは教科キー(例: english)の連想配列。
| キー | 型 | 必須 | 説明 |
|---|---|---|---|
| label | string | 任意 | 画面表示名(例: 英語) |
| title | string | 任意 | ページタイトル |
| hint_heading | string | 任意 | 補助見出し |
| answer_modes | object | 任意 | Legacy回答UIの有効設定。text(テキストエリア)、image_upload(画像添付)、handwriting(手書き回答)をbooleanで保持し、未設定項目は互換性のため有効として扱う |
| enabled | bool | 任意 | false の教科は読み込み時に除外 |
practice.php / child_challenge.php が作成し、log_view.php が修正提出時に同じJSONを更新します。practice.php / child_challenge.php と log_view.php では、子ども向け画面上で「{保護者呼称}へのメッセージ」(未設定時は「保護者」)として入力したコメントを child_comment に保存し、parent_log_view.php で参照できます。
| キー | 型 | 説明 |
|---|---|---|
| user_id | string | 子ログインID |
| user_name | string | 子表示名 |
| subject | string | 教科キー |
| subject_label | string | 教科表示名 |
| subject_title | string | 教科タイトル |
| start_no / ratio / count / try_no | number | 出題条件 |
| datetime / shown_at / submitted_at | string | 日時(Y-m-d H:i:s) |
| intro_message | string | 導入メッセージ |
| child_comment | string | 子どもが入力したコメント(任意) |
| child_comment_at | string | 子どもコメント保存日時(Y-m-d H:i:s) |
| ai_first_review | object | AI一次判定結果(status/model/scored_at/summary/items を保持) |
| questions | array | 問題ごとの回答ログ配列 |
| revised_at | string | 修正提出があった場合のみ追加 |
| parent_summary | string | 保護者の総評コメント(保存時に上書き) |
| review_ok | bool | 「修正不要」チェック状態 |
| ok_count_first / ok_count_revised | number | 保護者がOK判定した問題数(初回採点/修正後採点、同一問題の二重計上なし) |
| parent_comment_at | string | 保護者コメント保存日時(Y-m-d H:i:s) |
questions[] の各要素:
| キー | 型 | 説明 |
|---|---|---|
| index | number | 表示順(1始まり) |
| line_no | number | 問題DB行番号 |
| question | string | 表示問題文 |
| answer | string | 初回回答 |
| col0 / col1 | string | DB先頭列の退避 |
| is_ja_q | number(0/1) | 和文→英文問題かどうか |
| question_image_url | string | 問題画像URL(DB/snapshot問題で設定される場合) |
| answer_overlay_url | string | 図形問題向けのオーバーレイURL(運用上は下敷き用途と混在するため注意) |
| image_overlay_file | string | 子どもの初回回答レイヤ(透過PNG) |
| revised_answer | string | 修正回答がある場合 |
| revised_image_overlay_file | string | 子どもの再回答レイヤ(透過PNG) |
| (補足) 現行の画像保持 | - | 現行実装では問題側キーは question_image_url / answer_overlay_url の2系統です。子ども回答側は image_overlay_file / revised_image_overlay_file の2系統で保持します。 |
| parent_comment | string | 保護者コメント |
| parent_ok | bool | 保護者のOK判定 |
| parent_ok_stage | string(first/revised) | OK判定時点(初回回答/修正回答) |
child_dashboard.php のグラフ描画で使用する集計済みJSONです。dev/build_child_graph_data.php で、既存の回答ログJSONから再生成します。parent_log_view.php で保護者が採点保存(コメント保存)またはログ削除した際は、対象の子どもIDに対して同スクリプトを自動実行し、graph_stats.json を即時更新します。
dev/build_child_graph_data.php の集計時は、まず questions[].parent_ok + parent_ok_stage を優先使用します。ok_count_first / ok_count_revised は補助値として扱い、parent_ok_stage が存在しない旧ログ形式でのみ使用します(初回/修正後の二重計上を防ぐため)。さらに旧形式(点数情報なし)では questions[].parent_comment から次のルールで復元します:
「ok を含む1行コメント」= 初回正答、
「ok を含み2行以上のコメント」= 修正後正答、
それ以外 = 誤答。
| キー | 型 | 説明 |
|---|---|---|
| version | number | フォーマットバージョン(現行: 1) |
| generated_at | string | 生成日時(Y-m-d H:i:s) |
| records | array | 回答ログ単位の集計行 |
| summary | object | 全教科/教科別の平均正答率サマリー |
records[] の各要素:
| キー | 型 | 説明 |
|---|---|---|
| subject | string | 教科キー |
| answered_at | string | 回答日時(Y-m-d H:i:s) |
| question_count | number | その回の問題数 |
| ok_first | number | 初回回答でOKになった問題数 |
| ok_revised | number | 修正後回答でOKになった問題数 |
| is_scored | bool | その回答ログが保護者採点済みかどうか |
運用目安:graph_stats.json は「表示用に1ファイルをそのまま読む」用途では実装が単純で扱いやすいですが、レコードが 1,000 件超で今後も増加し、かつ更新頻度が上がる場合は SQLite などのRDBへの格納を検討します。判断基準は次の通りです。
本プロジェクトでは、まず graph_stats.json を一次生成物として維持しつつ、必要になった段階で「集計元をSQLite化し、表示用JSONをキャッシュとして生成する」段階移行を推奨します。
users_prod.sqlite または users_test.sqlite)から admin / parent / child をロードします。prod_admins/prod_parents/prod_children、STG: test_admins/test_parents/test_children)。dev/migrate_users_to_sqlite.php で既存 users.json からSQLiteへ移行できます(users.json 自体は変更しません)。password_hash / password_verify で照合します。admin_dashboard.php に遷移します。admin_docs_index.php(現行仕様/実装計画の一覧ページ)への導線を設けます。docs/standard_curriculum_catalog_spec.html への直接導線を設けます。実体仕様の保守用原本は docs/standard_curriculum_catalog_spec.md とします。.md は生テキストではなく admin_markdown_viewer.php 経由で開き、見出し・表などをレンダリング表示します(同一タブ遷移)。parent_dashboard.php に遷移します。child_dashboard.php に遷移し、「新しい問題」「過去の回答」の2導線を表示します。index.php では、about.php / specification.html への導線は STG_MODE 時のみ表示します(本番では非表示)。RENOTESESSID_{HOST} 形式でホスト単位に分離します(例: renote.homes / wsl.renote.homes)。child_dashboard.php 下部に「これまでのきろく」を表示します。全教科のグラフを先頭に表示し、その下に教科別グラフ(回答数/累積問題数、正答率推移)を表示します。assets/vendor/chart.umd.min.js が配置されている場合のみ読み込みます。未配置時はグラフ非表示の案内メッセージを表示します。YY年m月d日~ 形式で表示します。{subject}_settings.txt)が、log_view.php の「初回回答順」で最新となるログの出題設定(開始No/英訳割合/出題数)と異なる場合に NEW アイコンを表示します。log_view.php の教科選択画面でも、各教科ボタンに最新ログ状態(NEW / OK / なし)を表示します。判定ルールは同ページ内の各教科ログ一覧と共通です。log_view.php / parent_log_view.php のログ一覧「点数」は、分母をログごとの実出題数(count)で算出します(count 欠落時のみ questions 配列件数を代替)。分子は questions[].parent_ok=true 件数を優先し、旧ログでは ok_count_first + ok_count_revised を使用します。YY年m月d日~ 形式です。about.php はログイン不要で閲覧できる公開ページです。assets/style.css の紹介ページ用クラス(.intro-*)で定義します。dev/show_stgmode.php を通じて STG 環境表示と整合させます。config/users_sqlite.php の app_init_users_tables() で、環境に応じたテーブル名で同一スキーマを作成します。
| 論理テーブル | 本番テーブル名 | STGテーブル名 | 用途 |
|---|---|---|---|
| admins | prod_admins | test_admins | 管理者アカウント |
| parents | prod_parents | test_parents | 保護者アカウント |
| children | prod_children | test_children | 子どもアカウント |
| カラム | 型 | 制約/既定値 | 説明 |
|---|---|---|---|
| id_enc | TEXT | PRIMARY KEY | 暗号化済みログインID |
| name_enc | TEXT | NOT NULL DEFAULT '' | 暗号化済み表示名 |
| password_hash | TEXT | NOT NULL DEFAULT '' | パスワードハッシュ |
| disabled | INTEGER | NOT NULL DEFAULT 0 | 無効フラグ(0/1) |
| カラム | 型 | 制約/既定値 | 説明 |
|---|---|---|---|
| id_enc | TEXT | PRIMARY KEY | 暗号化済みログインID |
| name_enc | TEXT | NOT NULL DEFAULT '' | 暗号化済み表示名 |
| password_hash | TEXT | NOT NULL DEFAULT '' | パスワードハッシュ |
| dir_uuid | TEXT | NOT NULL DEFAULT '' | 保護者データディレクトリUUID |
| maxchildren | INTEGER | NOT NULL DEFAULT 0 | 作成可能な子アカウント上限 |
| disabled | INTEGER | NOT NULL DEFAULT 0 | 無効フラグ(0/1) |
| カラム | 型 | 制約/既定値 | 説明 |
|---|---|---|---|
| id_enc | TEXT | PRIMARY KEY | 暗号化済みログインID |
| name_enc | TEXT | NOT NULL DEFAULT '' | 暗号化済み表示名 |
| parent_id_enc | TEXT | NOT NULL DEFAULT '' | 紐づく保護者の暗号化ID |
| password_hash | TEXT | NOT NULL DEFAULT '' | パスワードハッシュ |
| dir_uuid | TEXT | NOT NULL DEFAULT '' | 子どもデータディレクトリUUID |
| enabled_subjects_json | TEXT | NOT NULL DEFAULT '[]' | 有効教科一覧のJSON配列 |
| disabled | INTEGER | NOT NULL DEFAULT 0 | 無効フラグ(0/1) |
| deleted | INTEGER | NOT NULL DEFAULT 0 | 削除フラグ(0/1) |
| deleted_at | TEXT | NOT NULL DEFAULT '' | 削除日時(Y-m-d H:i:s) |
subjects.json を基準にします。parent_subject_edit.php から教科ごとにテキストエリア・画像添付・手書き回答を有効/無効にできます。設定は practice.php の新規回答と log_view.php の修正回答へ反映し、無効な入力は画面非表示に加えて保存処理でも受け付けません。過去に保存された回答・画像の閲覧には影響しません。practice.php のLegacy問題文は、HTMLエスケープ後に __文字__ を下線、**文字** を太字として表示します。guardian_question_settings.php を使用し、parent_settings_edit.php の意図(保護者が出題条件を設定)を継承します。enabled_subjects で管理します。guardian_question_settings.php の「スナップショット確定」は JSON 保存に加えて guardian_question_settings テーブルへ同条件をUPSERT保存します。/api/db/guardian_question_settings_preview.php(プレビュー生成)と /api/db/guardian_question_settings_save.php(上書き保存)を提供します。処理本体は /api/db/guardian_question_settings_service.php で共通化します。guardian_question_settings.php では unit 選択時に反転有効/無効と反転モード名が確定し、{反転モード名} [%] の比率セレクトへ動的反映されます。parent_dashboard.php の「出題設定管理」カードは、Legacy Mode では parent_settings_edit.php、DB Mode では guardian_question_settings.php へ遷移します。guardian_question_settings.php の先頭に「子ども1行 + 教科ボタン群」の一覧を表示し、選択ボタンで対象設定へ入る導線を提供します。未作成 / あり / なし を判定表示します。curriculum_subjects / curriculum_sections / curriculum_units)で管理します。docs/problem_generation/english_curriculum_registry_v1.md を参照し、自由タグは当面使いません。admin_curriculum_catalog.php(管理者)と guardian_curriculum_catalog.php(保護者)を追加します。owner_scope で制御し、standard は全ユーザー参照可、guardian は作成元 household のみ参照可とします。問題数 / tag / 難易度 / 反転比率 を設定します(例: be動詞疑問文 10問 + 一般動詞否定文 10問)。単元ごとに固める / 単元を混ぜる を選択でき、snapshotの filters.question_order_mode に保存します。admin_english_generation.php で、主目標・既習単元・除外単元・場面から英語の小規模生成条件を作ります。共通管理者ダッシュボードの導線は DB Mode 時だけ表示します。単文は翻訳ペア、長文は本文+設問+模範解答+引用根拠+別解として扱い、長文は反転しません。主目標と含有文法タグを区別し、条件は english_profile としてキュー・生成・独立レビューへ引き継ぎます。構造検査だけでは正式問題へ昇格させません。詳細は docs/problem_generation/english_generation_profile_v1.md。problems レコードとして保持し、child 固有問題がある場合のみ legacy_child_login_id で上書きします。出題・プレビュー・学習計画は「同一 household の subject に属する shared 問題 + child 固有問題」を合成して扱います。英訳⇔和訳)を持てる設計とします。child_challenge.php は {child}/snapshots/{subject}_snapshot.json が存在する場合、その問題セットを優先して出題します。practice.php / child_challenge.php の回答送信時には、AI一次判定ジョブをキュー投入し、回答ログJSONにはまず ai_first_review.status=pending を保存します。回答送信処理はここで完了し、子ども画面は判定完了待ちを行いません。bash dev/run_ai_first_review_queue_cron.sh を定期実行して処理します(スクリプト内部で php dev/run_ai_first_review_queue.php --once --max-jobs=N を実行)。判定後は同一ログJSONの ai_first_review を ok/error/skipped へ更新します。child_challenge.php は snapshot/DB の unit_key と answer_mode を参照し、数学の calculation/factorization を数式表示します。factorization は各問題には式のみを表示し、同unitの先頭で1回だけ「次の式 + 家庭設定文言(既定: 次の式を因数分解せよ)」を見出し表示します。数学の回答欄は1行テキスト入力に加えてタップ式の数式入力パッド(x/y、+、-、( )、2乗/3乗、×、1字消し、クリア)を表示し、子どもが記号キーボードを開かずに入力できます。入力直下にはリアルタイムの数式プレビュー(上付き指数・掛け算記号)を表示し、見た目を数式として確認できます。problems.answer_mode / problems.prompt_format が未追加の旧スキーマでは安全な既定値(text / plain)へフォールバックして動作します。question_image_url / answer_overlay_url の2キー運用です。意味が混在しやすいため、入力時の取り違えに注意します。question_image_path / answer_base_image_path / model_overlay_image_path)へ移行し、意味の異なる画像を同一キーへ混在させない仕様に変更予定です。public_html 外(例: ../problem_assets/)へ配置し、直接URL公開を禁止します。配信は認可付きの img.php 経由へ統一予定です。answer_mode / prompt_format / extras に応じて出し分けます。通常の英語問題では text 入力を中心とし、画像付き問題や図形問題のみ image 系UIを表示します。録音回答(audio)とリスニング問題は将来拡張として追加予定です。ペン / 消しゴム / 線分 / 円 / 円弧 を提供します。*_image_overlay_file)→初期ベース画像の順でベースを選択し、初期の問題画像レイヤーを再重畳しないことで「再編集時に最初からになる」事象を防止します。guardian_question_settings.php には「今日のポイント」入力欄を設け、スナップショット保存時に intro_message として保存します。child_challenge.php はこの値を優先表示します。guardian_question_settings.php には家庭共通の「因数分解の表示文言」入力欄を設け、household_display_settings.factorization_prompt_text へ保存します。未設定時は既定文言(を因数分解せよ)を使用します。reference_pairs ボタン表示)は家庭共通ではなく、子ども × 教科 単位で保持します(guardian_question_settings.show_reference_list)。section(学習領域)/ unit(到達目標)/ tags(出題形式・語彙条件・難易度など)を基本とします。英語の 単文/長文/単語 は unit ではなく form_* タグとして扱います。form_word)」「単文翻訳(form_sentence)」「長文読解(form_passage)」の3系列を主軸として計画・出題します。section=be動詞/一般動詞/前置詞/関係代名詞/単語... を主軸にし、unit=肯定文/否定文/疑問文... を割り当てます。語彙レベルや出題形式は eiken_* / form_* タグで制御します。section=数と式/関数/図形/資料の活用 を主軸にし、unit=因数分解/展開/一次方程式/一次関数... を割り当てます。図形の手書き回答は geometry_overlay 系unitで検証します。admin_problem_intake.php で OpenAI API問題生成(モデル選択可)と JSON/CSV検査を実行し、reject を除外して admin_problem_bank_items へ登録できます。生成時は説明文プレフィックス混入防止・英語unitのanswer_mode=text固定・prompt_format=plain既定・既存タグへの正規化を行います。標準問題は一度 admin_problem_bank_items に集約し、レビュー後に正式問題へ昇格します。次の式を因数分解してください や 答えは〜 のような出題文テンプレート混入を検査で排除します。calculation/factorization は、answer_mode=formula を固定し、prompt_primary を式のみ、prompt_secondary を答えのみ(ヒント文禁止)として検査します。factorization は非自明問題のみ許可し、prompt_primary が2次以上、prompt_secondary が2因子以上の積の形でない場合は reject とします。factorization の検査では、prompt_secondary を展開して prompt_primary と係数一致するかを確認します。不一致は reject とし、同一因子の繰り返し(例: (x-1)(x-1))は正当な因数分解として許容します。生成/検査前には「〜を因数分解した形」などの指示文混入を除去してから評価します。admin_problem_bank_items 既存データとの重複照合も実施します。完全一致は reject、記号/空白差分レベルの実質重複は warn として既存IDを表示します。{PRIVATE_DIR}/state/... を優先し、書き込み不可環境では dev/state/... または /tmp/renote_state/... へ自動フォールバックします。admin_tag_manager.php を追加し、tags(正規タグ)と tag_aliases(エイリアス→正規タグ)を管理できます。admin_problem_intake.php の検査前にタグエイリアス正規化を適用します。admin_standard_problem_list.php を追加し、admin_problem_bank_items の target_type=standard を対象に、各カラムのフィルタ/ソート、1ページ件数指定、ページネーション(最初/前/番号/次/最後)を上下に表示します。現在の絞り込みに一致する final_status=pass のみを household 共通の正式問題へ昇格する導線を持ちます。tags_json / extras_json / prompt_format / answer_mode を problems と problem_tags に反映します。英語の reference_pairs も extras_json に保持したまま昇格します。prompt_format(plain / latex / mixed)を導入し、表示側はこの値をトリガーとして数式レンダリングを切り替えます。既存DBは一律 plain を自動補完します。reject は検査ルールに基づく自動判定で、登録時に自動除外されます。api_status は理由付きの warn 表示とし、final_status は local_status を維持します(未実行だけで一律warn昇格しない)。unit_key ではなく units.unit_name を表示し、内部では対応するキーを使用します(例: be_interrogative は「be動詞(疑問文)」として表示)。admin_problem_intake.php では API生成/検査/登録の送信時に待機モーダル(スピナー)を表示し、長時間処理中の誤操作を防止します。admin_problem_intake.php の送信処理は、ブラウザ差異で action が欠落しないよう hidden に確定値を補完してから送信します(生成ボタン押下時に未実行へ戻る事象を防止)。dev/ai_tuning/run_tuning_loop.php を追加し、OpenAI生成→ローカル検査→moderation→品質検査(任意)→失敗理由の次サイクル反映、をCLIで自動反復できるようにします。結果は {PRIVATE_DIR}/state/ai_tuning_report_*.json へ出力します。admin_tuning_review.php を追加し、単元ターゲットごとに 30問生成・一覧レビュー(pending/ok/ng)・コメント保存を行えるようにします。ng コメントは次回生成時のフィードバック文として自動反映されます。単元表示は unit_key ではなく日本語 unit_name を優先し、全ターゲット一括生成(例: 5問ずつ)と、失敗ターゲットのみ継続実行後にエラー表示する部分成功モードに対応します。レビュー判定UIはプルダウンではなくラジオボタン(pending/ok/ng)を使用し、grammar_tag/form_tag はターゲット一覧・問題一覧の両方でチップ表示します。さらに、OpenAIによるAIレビュー(全target/対象target)を実行して reviewer_decision を自動採点し、必要に応じて ok 以外を一覧から除外できます。数学ターゲットから math_core は除外し、因数分解は「完全因数分解」まで要求します。なお local_status=reject の問題は AIレビュー結果に関係なく ng 固定です。実行環境互換のため、JSON配列判定は array_is_list 非対応PHPでも動く互換実装を使用します。レビューで ok 判定された問題は画面上のボタンから admin_problem_bank_items へ直接登録でき、同一チューニングitemの二重登録は回避します。guardian_learning_plan.php を追加し、保護者が子ども×教科ごとの指導計画を管理できます。MVPでは、単元ごとの計画ステータス(未着手/進行中/一旦完了)・期間(短期/長期)・目標反復回数・優先度・停止/再開・メモ・表示順を保存します。加えて「総合テスト」1枠を持ち、対象unitをカンマ区切りで指定できます。実績は回答ログと問題行番号から単元を逆引きして、出題回数(セッション回数/問題数)・最終実施日時・回答記入率(暫定の出来映え指標、正誤判定ではない)を表示します。推奨単元(上位3件)は、状態・優先度・記入率の簡易スコアで提示します。次段階の強化方針は docs/learning_plan_board_spec.md と docs/learning_plan_board_implementation_plan.md を基準に進めます。各教科とも、section を大分類、unit を学習目標、tags を出題形式・条件として扱います。
本番で使う標準教科/section/unit/tagsの実体一覧は docs/standard_curriculum_catalog_spec.md を保守用正本とし、docs/standard_curriculum_catalog_spec.html は閲覧用の派生ドキュメントとして扱います。本節は基本方針の要約として維持します。
| section | unit(例) | tags(例) |
|---|---|---|
| be動詞 | 肯定文 / 否定文 / 疑問文 | form_sentence, form_passage, eiken_5〜eiken_3 |
| 一般動詞 | 肯定文 / 否定文 / 疑問文 | form_sentence, verb_regular, verb_irregular |
| 前置詞 | 場所 / 時間 / 方向 | form_sentence, preposition_place, preposition_time |
| 関係代名詞 | 主格 / 目的格 / 所有格 | form_sentence, form_passage, grammar_relative_pronoun |
| 単語 | 英検5級 / 4級 / 3級 | form_word, noun_countable, noun_uncountable, adjective |
| section | unit(例) | tags(例) |
|---|---|---|
| 数と式 | 正負の計算 / 文字式 / 一次方程式 | form_formula, calc_add_sub, word_problem, grade_7 |
| 式の変形 | 展開 / 因数分解 | form_formula, expansion_basic, factor_trinomial, grade_8〜grade_9 |
| 関数 | 比例・反比例 / 一次関数 / 二次関数 | form_graph, graph_read, slope, vertex |
| 図形 | 平面図形 / 相似 / 三平方 | form_diagram, proof, geometry_numeric, geometry_overlay |
| 資料の活用 | 代表値 / 確率 | form_table, mean_median_mode, probability_basic |
| section | unit(例) | tags(例) |
|---|---|---|
| 物理 | 力と運動 / 電流と回路 / 光・音・圧力 | calc, graph_read, experiment, ohm_law |
| 化学 | 物質の性質 / 化学変化 / 酸・アルカリとイオン | concept, equation, ion, neutralization |
| 生物 | 植物 / 動物 / 細胞・遺伝 | diagram, classification, term_fill |
| 地学 | 天気 / 地層・地震・火山 / 天体 | chart_read, observation, concept |
| section | unit(例) | tags(例) |
|---|---|---|
| 漢字・語句 | 漢字の読み / 漢字の書き / 語彙・慣用句 | form_word, kanji_reading, kanji_writing, idiom |
| 文法 | 品詞 / 文節・文の成分 / 敬語 | grammar, sentence_structure, honorific |
| 読解 | 説明文読解 / 物語文読解 | form_passage, main_idea, character_feeling |
| 古典 | 古文の基礎 / 漢文の基礎 | classical, kanbun, reading |
| 表現 | 作文・記述 | writing, opinion, structure |
| section | unit(例) | tags(例) |
|---|---|---|
| 地理 | 世界の地域 / 日本の地域 / 地図・統計資料 | map, climate, data_read, graph |
| 歴史 | 古代〜中世 / 近世〜近代 / 現代史 | timeline, person, cause_effect, world_relation |
| 公民 | 政治 / 経済 / 国際社会 | constitution, market, tax, human_rights |
| カテゴリ | tags(例) |
|---|---|
| 出題形式 | form_word, form_sentence, form_passage, form_formula, form_graph, form_table, form_diagram |
| 難易度 | diff_1〜diff_5 |
| 学年 | grade_7, grade_8, grade_9 |
| テスト種別 | regular_test, comprehensive_test, entrance_exam_prep |
全教科の拡充作業を外部LLM(ChatGPT)へ依頼した際の旧テンプレートは docs/archive/chatgpt_curriculum_catalog_request.md に退避しています。現在は履歴資料として扱います。
practice.php の回答保存時、通知は次の順で送信されます。
children.line_channel_token + children.line_user_id が設定されていればそれを使用。未設定時のみ旧来の {PRIVATE_DIR}/key/line_channel_token.txt / line_user_id.txt をフォールバック使用。curl_init が利用可能な環境でのみ実行し、未導入環境では通知送信をスキップして回答保存は継続します。parent_children_edit.php のLINE設定入力欄は、登録済み値を平文表示せず ******** を表示する。保存時に ******** のままなら既存値を維持し、空欄にして保存した場合のみクリアする。parents.email が設定されていれば、同一サマリーをメール送信。件名は RFC 2047(UTF-8 Base64)でエンコードし、本文は Content-Transfer-Encoding: base64 で送る。php dev/migrate_users_to_sqlite.phpusers_prod.sqlite + prod_*、STG/テスト環境では users_test.sqlite + test_* を生成します。users.json はバックアップ用途のため一切更新・削除しません。php tools/mariadb/reset_initial_schema.phpphp tools/mariadb/import_legacy_seed.phpphp tools/mariadb/add_english_units_seed.phpphp tools/mariadb/add_math_units_seed.phpfactorization は問題文テンプレート(「〜を因数分解せよ」)を含めず、prompt_primary に式のみを保存します。php tools/mariadb/add_geometry_overlay_seed.phpphp tools/mariadb/add_english_grammar_tags_seed.phpdefault unit廃止の移行: php tools/mariadb/migrate_remove_default_units.php(英語: sentence_translation / 数学: math_core)tools/codex_worker/run_codex_review.sh(入力JSONを ok/ng 判定へ変換)。非ログインシェルでも動作するようユーザーローカルPATH(~/.npm-global/bin など)を補完します。キュー監視運用向けに tools/codex_worker/watch_trigger_queue.sh も提供し、/mount/xserver などの共有ディレクトリ上でトリガーJSONを順次処理できます。docs/problem_generation/chatgpt_problem_generation_guide.md(対話型ChatGPTで生成し、OpenAI APIで生成後自動チェックする運用、JSON/CSVフォーマット、difficulty基準、1,000問あたり概算コストを定義)docs/problem_generation/target_units_plan.md(30問検証→1,000問拡張の対象リスト)docs/learning_plan_board_spec.md(単元順序中心・実績可視化中心・自動進級判定なしの方針)docs/learning_plan_board_implementation_plan.md(M1〜M4の段階実装計画。英語の同時並行学習可視化は設計課題として pending 管理)docs/learning_plan_rethink_20260812.md(標準カリキュラム→子どもの計画→今回の出題→学習実績を一続きにし、英語は並行レーンを前提とする方針)php dev/ai_tuning/run_tuning_loop.php --subject=math --unit=factorization --target=100 --batch=50 --cycles=3bin/renote_snapshot_data.sh(stg/prod 指定)。更新/デプロイ前に private(_stg)/backups/deploy_snapshots/ へ運用データ(*.json / *.sqlite + MariaDB dump)を保存し、5世代ローテーションします。bin/renote_update_stg.sh。スナップショット取得後に origin/main を適用します(git fetch + git reset --hard)。bin/renote_deploy_prod.sh / bin/renote_deploy_prod_tag.sh。反映対象は public_html のみ(rsync --delete)で、実行前に作業ツリーのclean確認・排他ロック・スナップショット取得を行います。units / tags / problem_tags / guardian_question_settings / challenge_snapshots を含みます。admin_problem_bank_items テーブル(投入ワークフロー用)をアプリ側で自動作成します。config/config.php で STG_MODE を定義します。dev/show_stgmode.php)を有効化し、.page-container / .container 背景へ薄い STG_MODE 透かしを斜め反復表示します。private_dir に加えて、利用中のユーザーDBファイルパスとテーブル名も表示します。Legacy Mode と DB Mode を1クリックでトグル切替できるようにします。非STG環境では常に従来動作です。public_html の親ディレクトリを優先します。{PRIVATE_DIR}/state/runtime_mode.txt に保持し、ログアウト後も前回モードを復元します。private_dir 自動探索は現行構成(WSL / genkikko.xsrv.jp / 相対配置)を対象とし、旧 genkikko.net/private_stg は探索対象から除外します。DB Mode 時の子ども導線は child_challenge.php、Legacy Mode 時は practice.php を利用します。dev/show_stgmode.php の STG バーから、about.php(紹介ページ)と specification.html(現行仕様)へ直接遷移できます。akari / genkikko / admin)を表示し、押下で対象ユーザーへセッションを切り替えて各ロールのダッシュボードへ遷移できます(dev/stg_switch_user.php)。遷移先は /admin_dashboard.php / /parent_dashboard.php / /child_dashboard.php の絶対パスを使用します。target="_blank")。version を持たせます。読み込み側スクリプトは旧バージョン検知時に、即座に最新スキーマへマイグレーション(インメモリまたは保存時)してから処理を継続する方針とします。practice.php で回答送信時にセッション切れ等が発生して pending 復元経路に入ると、保存実行時刻(サーバー受信)が大きく遅延して見える事例が確認されました。さらに、旧実装では保存時に「その時点の設定値(開始No/割合/出題数)」で問題を再生成していたため、送信中に保護者が出題設定を変更すると「問題と回答の不一致」が起こり得ました。対策として、回答フォームに出題時点の問題スナップショット(question_payload_json)と出題条件(start_no/ratio/count)を同梱し、保存時はPOST値を優先してログ化する仕様へ変更しました。specification.html を必ず更新します(ドキュメント先行または同時更新)。docs/development_policy.md を正本として運用し、変更時は実運用に合わせて更新します。child_ / guardian_ / admin_ を使い、子どもの実施導線は challenge を標準語とします(例: child_challenge.php)。