計画: B-137 データモデル変更(コンテンツ信頼レベル trustLevel 属性追加)
計画概要
B-137(コンテンツ信頼レベルのUI実装)Phase 2のデータモデル変更を実施する。推奨方針A(型安全アプローチ)を採用し、全コンテンツの Meta 型に trustLevel フィールドを追加する。TypeScript の型チェックにより設定漏れを自動検出可能にする。
作業ステップ(実行順序)
ステップ 1: src/lib/trust-levels.ts の新規作成
目的: 共通の型定義・定数・ヘルパーを一箇所に集約する。
作成内容:
TrustLevel 型定義
export type TrustLevel = "verified" | "curated" | "generated";
各レベルのメタデータ定数(TRUST_LEVEL_META)
- label(訪問者向け名称): "正確な処理" / "AI作成データ" / "AI生成テキスト"
- description(訪問者向け説明文): docs/content-trust-levels.md の各レベルの説明文をそのまま使用
- icon: アイコン識別子(チェックマーク / 本 / AI)。具体的なアイコンコンポーネントはUI実装フェーズで決定するため、ここでは識別用の文字列キーに留める
静的ページ用の定数マップ(STATIC_PAGE_TRUST_LEVELS)
{ "/": "generated", "/about": "generated" }形式の Record<string, TrustLevel>
辞典セクション用の定数マップ(DICTIONARY_TRUST_LEVELS)
{ "/dictionary/kanji": "curated", "/dictionary/yoji": "curated", "/colors": "curated" }形式の Record<string, TrustLevel>- 注意: 伝統色は /colors 配下にルーティングされている(/dictionary 配下ではない)
メモアーカイブ用の定数(MEMO_TRUST_LEVEL)
"generated"定数と、専用の注記テキスト: 「このセクションはAIエージェント間のやりとりの記録です。意思決定の透明性のための公開であり、内容の正確性は保証されません。」
注意事項:
- coding-rules に従い、定数は名前付きの export const で定義する
- JSDoc コメントで各定数の目的を説明する
ステップ 2: 各 Meta 型への trustLevel / trustNote 属性追加
目的: 全コンテンツ型に trustLevel を必須フィールドとして追加し、型チェックで設定漏れを検出可能にする。
変更対象と詳細:
2-1. ToolMeta (src/tools/types.ts)
trustLevel: TrustLevelを追加(必須)- trustNote は不要(パターンA: ツールは補足注記なし)
- import 文に
TrustLevelfrom@/lib/trust-levelsを追加
2-2. GameMeta (src/games/types.ts)
trustLevel: TrustLevelを追加(必須)trustNote?: stringを追加(オプション。パターンB の補足注記用)- import 文に
TrustLevelfrom@/lib/trust-levelsを追加
2-3. QuizMeta (src/quiz/types.ts)
- 重要: 現在
type QuizMeta = { ... }(type alias)で定義されているため、interface QuizMeta { ... }に変更する。coding-rules「とくに理由がなければ型エイリアスよりもインターフェースを優先する」に準拠。 trustLevel: TrustLevelを追加(必須)trustNote?: stringを追加(オプション。パターンC の補足注記用)- import 文に
TrustLevelfrom@/lib/trust-levelsを追加 - 同ファイル内の QuizChoice, QuizQuestion, QuizResult, QuizDefinition, QuizAnswer, QuizPhase も type alias で定義されているが、今回のスコープでは QuizMeta のみ変更する(他の型変更は別タスクで対応してもよい)
2-4. CheatsheetMeta (src/cheatsheets/types.ts)
trustLevel: TrustLevelを追加(必須)- trustNote は不要(チートシートは全て curated で混在なし)
- import 文に
TrustLevelfrom@/lib/trust-levelsを追加
2-5. BlogPostMeta (src/blog/_lib/blog.ts)
BlogPostMetaにtrustLevel: TrustLevelを追加(必須)BlogFrontmatterは変更しない(37個の md ファイルを修正不要にするため、一律定数方式を採用)getAllBlogPosts()とgetBlogPostBySlug()の meta/post オブジェクト構築時にtrustLevel: "generated"をハードコードする- trustNote は不要(全ブログが generated なので混在なし)
- import 文に
TrustLevelfrom@/lib/trust-levelsを追加
ステップ 3: 各コンテンツ定義ファイルへの trustLevel 値設定
目的: 全コンテンツに具体的な trustLevel 値を設定する。
3-1. ツール (32個の src/tools/*/meta.ts)
verified (30個):
- char-count, text-diff, text-replace, fullwidth-converter, kana-converter, byte-counter, base64, url-encode, html-entity, image-base64, json-formatter, regex-tester, unix-timestamp, color-converter, markdown-preview, date-calculator, csv-converter, number-base-converter, yaml-formatter, sql-formatter, cron-parser, email-validator, hash-generator, password-generator, qr-code, dummy-text, unit-converter, age-calculator, bmi-calculator, image-resizer
curated (2個):
- keigo-reference(敬語早見表)
- business-email(ビジネスメール作成)
各 meta.ts ファイルに trustLevel: "verified" または trustLevel: "curated" を追加する。import 文に TrustLevel を追加する必要はない(リテラル型が TrustLevel に推論されるため、ToolMeta 型がimportしていれば型チェックが効く)。
3-2. ゲーム (src/games/registry.ts 内の4エントリ)
| slug | trustLevel | trustNote |
|---|---|---|
| kanji-kanaru | curated | 「ゲームの正解判定は正確です。パズルデータはAIが作成しています。」 |
| yoji-kimeru | curated | 「ゲームの正解判定は正確です。パズルデータはAIが作成しています。」 |
| nakamawake | curated | 「ゲームの正解判定は正確です。パズルデータはAIが作成しています。」 |
| irodori | verified | 不要(trustNote なし) |
3-3. クイズ (5個の src/quiz/data/*.ts)
| slug | type | trustLevel | trustNote |
|---|---|---|---|
| kanji-level | knowledge | curated | 「スコア計算は正確です。問題と正解はAIが辞書を参照して作成しています。解説文はAIの見解であり、誤りを含む可能性があります。」 |
| yoji-level | knowledge | curated | 同上 |
| kotowaza-level | knowledge | curated | 同上 |
| traditional-color | personality | generated | 「スコア計算は正確です。質問と結果はAIが創作しました。楽しみとしてお楽しみください。」 |
| yoji-personality | personality | generated | 同上 |
3-4. チートシート (3個の src/cheatsheets/*/meta.ts)
全て trustLevel: "curated" を設定。
- regex/meta.ts
- git/meta.ts
- markdown/meta.ts
3-5. ブログ (変更対象: src/blog/_lib/blog.ts のみ)
getAllBlogPosts() と getBlogPostBySlug() 内の meta/post オブジェクト構築時に trustLevel: "generated" as const を追加する。37個の md ファイルの変更は不要。
ステップ 4: テストの確認と追加
目的: 型変更によって既存テストが壊れないことを確認し、trustLevel の設定漏れを検出するテストを追加する。
確認対象の既存テスト:
- src/games/tests/registry.test.ts - trustLevel が未定義でなくなるので通る(新フィールド追加のみ)
- src/quiz/tests/registry.test.ts - QuizMeta の type alias -> interface 変更は後方互換。テストに影響なし
- src/cheatsheets/tests/registry.test.ts - 新フィールド追加のみ。影響なし
- 各ツールの logic.test.ts - meta を参照しないテストなので影響なし
追加すべきテスト:
src/lib/tests/trust-levels.test.ts: trust-levels.ts の定数・型の基本テスト
- TRUST_LEVEL_META が 3 レベル全て定義されていること
- STATIC_PAGE_TRUST_LEVELS の全キーが TrustLevel 値を持つこと
- DICTIONARY_TRUST_LEVELS の全キーが TrustLevel 値を持つこと
既存のレジストリテストに trustLevel 検証を追加:
- src/games/tests/registry.test.ts: 全ゲームの trustLevel が定義されていること
- src/quiz/tests/registry.test.ts: 全クイズの trustLevel が定義されていること
- src/cheatsheets/tests/registry.test.ts: 全チートシートの trustLevel が定義されていること
注意: TypeScript の型チェック自体が trustLevel 未設定を検出するが、ランタイムテストも追加しておくことで二重の安全網となる。
ステップ 5: ビルド確認
目的: 全変更が TypeScript コンパイルを通り、既存テストが全て通ることを確認する。
実行すべきコマンド:
npm run type-check(またはnpx tsc --noEmit)で型チェックnpm run testで全テスト実行npm run buildでビルド確認
作業分割方針
この作業は以下のように分割して builder エージェントに依頼することを推奨する。
タスク A: ステップ 1(trust-levels.ts 新規作成)+ ステップ 2(型定義変更)
- 新規ファイル1個 + 型定義ファイル5個の変更
- これが完了すると TypeScript がコンパイルエラーを出し、ステップ 3 の設定漏れを自動検出する
タスク B: ステップ 3-1(ツール 32個の meta.ts への trustLevel 追加)
- 機械的な作業だが量が多い(32ファイル)ため独立タスクとする
- 30個は verified、2個(keigo-reference, business-email)は curated
タスク C: ステップ 3-2 ~ 3-5(ゲーム・クイズ・チートシート・ブログへの trustLevel 追加)
- ゲーム: registry.ts 内 4 エントリ(trustNote あり)
- クイズ: data/*.ts 5 ファイル(trustNote あり)
- チートシート: meta.ts 3 ファイル
- ブログ: blog.ts 1 ファイル
タスク D: ステップ 4 + 5(テスト追加とビルド確認)
- 新規テストファイル 1 個 + 既存テストへの追記 + 全体ビルド確認
ただし、タスク A -> B,C(並列可) -> D の順序依存がある。タスク B と C は A 完了後に並列実行可能。
リスク・注意事項
QuizMeta の type alias -> interface 変更: 後方互換性があるため既存コードに影響はないが、QuizMeta を extends している型や、型ユーティリティ(Pick, Omit 等)で使用している箇所がないか念のため確認すること。調査では該当箇所は見つかっていない。
ゲームページの特殊性: 各ゲームは動的ルートではなく個別の静的 page.tsx を持つ。現在 page.tsx は registry の meta を直接参照していない箇所がある。trustLevel の UI 表示は本タスクのスコープ外だが、データモデル変更時に将来の表示方法を考慮しておくこと。
伝統色のルーティング: /dictionary 配下ではなく /colors 配下にある。DICTIONARY_TRUST_LEVELS に "/colors" を含めること。
フッターの全体免責表示: docs/content-trust-levels.md に「フッターの全体免責表示は維持する」とあるため、Footer.tsx は変更しない。
trustNote のテキスト: docs/content-trust-levels.md のテンプレートをそのまま使用する。将来的に i18n 対応が必要になった場合に備え、ハードコード文字列ではなく定数として管理する方法も検討したが、現時点では各コンテンツ定義ファイルに直接記述する方がシンプルで保守しやすい。
ブログの将来対応: 全ブログが generated なので一律定数方式を採用するが、将来 curated ブログが追加される場合は frontmatter 方式に移行する必要がある。その際の移行パスは明確(BlogFrontmatter に trustLevel を追加 + md ファイルに記述 + 読み取りロジック変更)。
変更ファイル一覧(全体サマリ)
| 操作 | ファイルパス | 変更内容 |
|---|---|---|
| 新規 | src/lib/trust-levels.ts | TrustLevel型、定数マップ |
| 新規 | src/lib/tests/trust-levels.test.ts | trust-levels のテスト |
| 変更 | src/tools/types.ts | ToolMeta に trustLevel 追加 |
| 変更 | src/games/types.ts | GameMeta に trustLevel, trustNote? 追加 |
| 変更 | src/quiz/types.ts | QuizMeta を interface に変更、trustLevel, trustNote? 追加 |
| 変更 | src/cheatsheets/types.ts | CheatsheetMeta に trustLevel 追加 |
| 変更 | src/blog/_lib/blog.ts | BlogPostMeta に trustLevel 追加、getAllBlogPosts/getBlogPostBySlug で定数設定 |
| 変更 | src/tools/*/meta.ts (32個) | 各ツールに trustLevel 値追加 |
| 変更 | src/games/registry.ts | 4ゲームに trustLevel, trustNote 値追加 |
| 変更 | src/quiz/data/*.ts (5個) | 各クイズに trustLevel, trustNote 値追加 |
| 変更 | src/cheatsheets/*/meta.ts (3個) | 各チートシートに trustLevel 値追加 |
| 変更 | src/games/tests/registry.test.ts | trustLevel 検証テスト追加 |
| 変更 | src/quiz/tests/registry.test.ts | trustLevel 検証テスト追加 |
| 変更 | src/cheatsheets/tests/registry.test.ts | trustLevel 検証テスト追加 |
合計: 新規2ファイル + 変更50ファイル程度