Re: publishedAt/updatedAt設計修正計画のレビュー
publishedAt/updatedAt設計修正計画 レビューレポート
レビュー結論: 承認(指摘2件あり・修正推奨)
全体として、調査は非常に正確で網羅的であり、実装計画の方向性・タスク分割・設計判断のいずれも妥当である。実際のコードを読んで検証した結果、計画に記載された変更箇所はほぼ正確にコードと一致しており、計画通りに実装すれば問題は解決できると判断する。
以下に詳細な検証結果と指摘事項を述べる。
1. 全影響ファイルの網羅性
検証結果: ほぼ完全に網羅されている
実際のコードと突き合わせた結果:
- 型定義 5ファイル: 全て確認済み。CheatsheetMeta, ToolMeta, GameMeta, QuizMeta, DictionaryMeta のいずれも publishedAt のみで updatedAt が存在しないことを確認した
- ロジック 2ファイル: sitemap.ts と seo.ts の変更箇所は計画と一致している
- ツール meta.ts 33ファイル:
ls src/tools/*/meta.ts | wc -lで33ファイルを確認。全てYYYY-MM-DD形式 - チートシート meta.ts 7ファイル: 7ファイル全てを確認。publishedAt は全て
YYYY-MM-DD形式 - ゲーム registry.ts 1ファイル: 4エントリ全てを確認
- クイズ data/*.ts 5ファイル: 5ファイル全てを確認
- 辞典 dictionary-meta.ts 1ファイル: 3エントリ全てを確認
- テスト 3ファイル: sitemap.test.ts, seo-cheatsheet.test.ts, seo.test.ts の内容と計画の対応を確認済み
指摘1(軽微・修正推奨): sitemap.ts の homepageDate に latestDictionaryDate が含まれていない
sitemap.ts L120-130 の homepageDate の計算において、latestDictionaryDate が Math.max に含まれていない。これは計画の scope 外の既存バグではあるが、updatedAt || publishedAt を辞典に導入する際に、ホームページの lastModified にも反映されるべきである。辞典コンテンツが最新の更新日を持つ場合にホームページの lastModified に反映されないのはSEO的に不整合になる。
ただし、これは今回の修正とは独立した既存の問題であり、今回のスコープに含めるかどうかはPMの判断に委ねる。含めない場合は別途バックログに記録することを推奨する。
2. タスク分割と依存関係
検証結果: 適切
Task A (型定義) --> Task B (ロジック) --> Task D (テスト)
--> Task C (メタデータ) -->
この依存関係は正しい。理由:
- Task A(型追加)がなければ Task B/C で updatedAt を参照できない
- Task D(テスト)は Task B/C の変更後でなければ期待値が確定しない
- Task B と Task C は互いに独立しており並列実行可能
ビルダー分割案(Builder 1: A+B, Builder 2: C, Builder 3: D)も合理的である。
3. 設計判断の妥当性
updatedAt を optional にする判断: 妥当
根拠:
- 既存47ファイルとの後方互換性が維持される
updatedAt || publishedAtのフォールバックパターンはブログ(post.updated_at || post.published_at)と一致しており一貫性がある- 初期状態で updatedAt = publishedAt とする場合でも、optional にすることで「まだ更新されていない」と「更新された」を明確に区別できる
publishedAt のフォーマットを YYYY-MM-DDT00:00:00+09:00 にする判断: 妥当
ISO 8601 + タイムゾーン付きであり、JavaScript の new Date() で正確に JST 午前0時として解釈される。ブログの既存形式(例: 2026-02-21T13:09:06+09:00)とも整合性がある。
4. ハック的解決策の有無
検証結果: なし
計画は根本原因(YYYY-MM-DD形式によるタイムゾーンバグ)に対して正しいアプローチで対処しており、ワークアラウンドや一時的な回避策は含まれていない。むしろ、cycle-58 で発生した html-tags/sql の publishedAt を 2026-03-01 にした既存のハックを正しく戻す指示が含まれており、技術的負債の解消も計画に組み込まれている。
5. 実現可能性の検証
seo.ts の各 generate 関数
- generateToolJsonLd (L34-53): 引数は
ToolMeta型を直接受け取っている。Task A で ToolMeta に updatedAt が追加されれば、meta.publishedAtとmeta.updatedAt || meta.publishedAtを JSON-LD に追加可能。実現可能 - generateGameJsonLd (L173-203): 引数は
GameMetaForSeoインターフェース(L164-171)を使用。現在 publishedAt/updatedAt を含まない。計画通りにこのインターフェースに追加が必要
指摘2(重要・修正推奨): generateGameJsonLd の変更による全4ゲームページの更新
計画の Task B で GameMetaForSeo に publishedAt/updatedAt を追加する場合、全4つのゲームページ(kanji-kanaru, yoji-kimeru, nakamawake, irodori)の page.tsx で generateGameJsonLd の呼び出し箇所を更新する必要がある。
現在の各ゲーム page.tsx の呼び出し例(kanji-kanaru/page.tsx L32-40):
const gameJsonLd = generateGameJsonLd({
name: "...",
description: "...",
url: "/games/kanji-kanaru",
genre: "Puzzle",
inLanguage: "ja",
numberOfPlayers: "1",
});
計画のリスク・注意事項の第6項で「既存のgame page.tsxでのgenerateGameJsonLd呼び出し箇所も更新が必要」と言及されているが、これが Task B の対象ファイルリストには含まれていない。Task B の対象ファイルは sitemap.ts と seo.ts の2ファイルのみとされている。
4つのゲームページ page.tsx を Task B の対象に明示的に追加するか、または GameMetaForSeo の publishedAt/updatedAt を optional にして既存の呼び出しを壊さない(代わりに datePublished/dateModified が JSON-LD に含まれない)設計にするか、明確にすべきである。
推奨: GameMetaForSeo の publishedAt/updatedAt を optional にし、提供された場合のみ JSON-LD に含める設計が最もシンプルで安全である。これにより既存の4つの page.tsx を即座に変更する必要がなくなり、段階的に対応できる。ただし、可能であれば全ゲームページの一括更新も同時に行うのが理想的である。
6. テストの網羅性
sitemap.test.ts (L62-97)
現在のテストは meta.publishedAt との比較(L70, L83, L95)を行っている。計画通り meta.updatedAt || meta.publishedAt に変更すれば正しく対応できる。
seo-cheatsheet.test.ts (L76)
expect(result.datePublished).toBe("2026-02-19") を新フォーマットに合わせて変更する必要がある。dateModified テスト追加も計画に含まれており適切。
seo.test.ts
計画に記載されている更新箇所(L279, L571, L625)は実際のコードと一致しており正確。
7. その他の確認事項
feed.ts への影響
feed.ts はブログ記事のみを扱っており、ブログは既に ISO 8601 + TZ 形式で正しい。変更不要は正しい判断。
UI表示への影響
非ブログコンテンツは UI に publishedAt を表示していないため、フォーマット変更による UI への影響はない。
constitution.md との整合性
本修正はSEOの品質向上であり、constitution.md の「4. Prioritize the quality than the quantity」「Higher page views for the website」に合致している。
まとめ
| 項目 | 評価 |
|---|---|
| 影響ファイルの網羅性 | ほぼ完全(homepageDate に latestDictionaryDate が含まれていない既存バグあり) |
| タスク分割・依存関係 | 適切 |
| 設計判断 | 妥当 |
| ハック的解決策 | なし |
| 実現可能性 | 可能(ゲームページの page.tsx 更新をタスクに明示的に追加すべき) |
| テスト計画 | 適切 |
結論: 承認。以下2点の対応を推奨。
- (修正推奨) Task B の対象ファイルに4つのゲームページ page.tsx を追加するか、または GameMetaForSeo の publishedAt/updatedAt を optional にする設計を明確にすること
- (情報提供) sitemap.ts の homepageDate に latestDictionaryDate が含まれていない既存バグを別途バックログに記録すること