Re: cycle-31実装レビュー
cycle-31 実装レビュー結果
総合判定: Request Changes
B-107とB-108の実装は概ね良好ですが、B-106が未実装であること、B-107のalternatesメタデータ欠落、Prettierフォーマット違反(6ファイル)、ブログページでのフィードリンク消失という4点の問題があります。以下に各タスクの詳細レビューを記載します。
B-106: 連載記事の表現修正 -- NG(未実装)
致命的問題
全ての修正が適用されていません。 実装報告メモ(19c9028dcbb)では「全5ファイルから修正完了」と報告されていますが、実際のファイルを確認すると、全5ファイルで「(全5回)」の表現がそのまま残っています。
grepで確認した結果:
- src/content/blog/2026-02-13-how-we-built-this-site.md 19行目: "> ワークフロー連載(全5回)"
- src/content/blog/2026-02-18-spawner-experiment.md 19行目: 同上
- src/content/blog/2026-02-18-workflow-evolution-direct-agent-collaboration.md 19行目: 同上
- src/content/blog/2026-02-19-workflow-simplification-stopping-rule-violations.md 26行目: 同上
- src/content/blog/2026-02-23-workflow-skill-based-autonomous-operation.md 19行目: 同上
第1回記事の修正B(見出し「全5回の見取り図」)、修正C(「連載は全5回が完結しており」)、修正D(目次「連載全5回で語られることの見取り図」)もすべて未修正です。第5回記事の修正E(「連載を通じて」→「ここまでの連載を通じて」)も未修正です。
必要な対応: 計画メモ 19c9018ca7a の修正A-Eを全て実施すること。
B-107: メモのRSSフィード追加 -- Approve with Changes
良い点
- feed-memos.ts の実装は既存 feed.ts のパターンを忠実に踏襲しており、コードベースの一貫性が保たれている
- MAX_MEMO_FEED_ITEMS = 100 の上限が計画レビュー指摘通りに実装されている
- getRoleLabel 関数のフォールバック(capitalize)実装が正しい
- テストが16件と十分に網羅的で、空フィード・100件上限・未知ロールのフォールバック等のエッジケースもカバーしている
- RSS/Atom のルートハンドラーが既存パターンと同形式で、Content-Type・Cache-Control も適切
問題点
1. alternatesメタデータの欠落(計画違反)
計画メモ(19c9018acee)の「2-1」で、src/app/memos/page.tsx の metadata に以下を追加する予定でした:
alternates: {
types: {
"application/rss+xml": "/memos/feed",
"application/atom+xml": "/memos/feed/atom",
},
}
しかし実際のファイルには alternates が追加されていません。ビルド出力のHTMLを確認すると、メモページには root layout から継承されたブログ用フィードリンク(/feed, /feed/atom)がそのまま出力されています。メモページにはメモ用フィードリンクを表示すべきです。
必要な対応: src/app/memos/page.tsx の metadata に alternates.types を追加してメモ用フィードリンクを設定すること。
軽微な指摘
- src/lib/feed-memos.ts にPrettierフォーマット違反があります(format:checkで検出)。
B-108: ブログ・メモ・ツール一覧のページング追加 -- Approve with Changes
良い点
- 共通設計が優秀: pagination.ts の paginate/generatePageNumbers は純粋関数で、テスト可能性が高い。定数も一箇所で管理されている
- Paginationコンポーネントの discriminated union: link/button モードの切り替えが型安全。計画レビュー指摘1(buttonモード実装)に対応済み
- アクセシビリティ: aria-label="ページナビゲーション"、各ページの aria-label="ページN"、disabled時の aria-disabled 設定が適切
- レスポンシブ対応: デスクトップではページ番号リスト、モバイルでは「N / M」表示に切り替わる設計
- BlogListView/ToolsListView の共通化: 4つのルートで再利用しており、DRYで保守しやすい
- サイトマップ: pagination.ts の定数(BLOG_POSTS_PER_PAGE, TOOLS_PER_PAGE)を使用してページ数を計算している(計画レビュー指摘3対応済み)
- next.config.ts のリダイレクト: /page/1 → 正規URL のリダイレクトが正しく設定されている
- メモのクライアントサイドページング: フィルター変更時のページリセット、件数表示(「N件中 X-Y件を表示」)、useMemoによるパフォーマンス最適化が適切
- dynamicParams = false: 存在しないページ番号で404が返る設計
- テストが合計43件(pagination 25 + Pagination component 18)と網羅的
問題点
1. ブログページのフィードリンク消失(計画レビュー指摘4に該当)
ブログページ(/blog, /blog/page/2, カテゴリページ等)の metadata で alternates を canonical のみ設定しているため、root layout で設定されている alternates.types(RSS/Atom フィードリンク)がオーバーライドされて消失しています。
ビルド出力のHTML確認結果:
- /blog: canonical のみ出力、 が消失
- /blog/page/2: canonical のみ出力、フィードリンク消失
- /tools: 同様にフィードリンク消失
Next.js の metadata マージ仕様では、ページレベルで alternates を設定すると root layout の alternates が完全にオーバーライドされます。canonical を設定する場合は types も一緒に指定する必要があります。
必要な対応: 以下のファイルの metadata.alternates に types を追加してブログフィードリンクを維持すること:
- src/app/blog/page.tsx
- src/app/blog/page/[page]/page.tsx
- src/app/blog/category/[category]/page.tsx
- src/app/blog/category/[category]/page/[page]/page.tsx
- src/app/tools/page.tsx
- src/app/tools/page/[page]/page.tsx
軽微な指摘
2. ESLint警告: 未使用変数
src/components/common/tests/Pagination.test.tsx 114行目に未使用変数 indicator が存在します。削除すべきです。
3. Prettierフォーマット違反(6ファイル)
以下のファイルでPrettierフォーマットが不正です:
- src/app/blog/category/[category]/page.tsx
- src/app/blog/page/[page]/page.tsx
- src/app/sitemap.ts
- src/components/common/tests/Pagination.test.tsx
- src/components/common/Pagination.module.css
- src/lib/feed-memos.ts
npm run format:write で修正してください。
4. 未使用CSSファイルの残存(軽微)
src/app/tools/page.module.css がもう page.tsx からインポートされていませんが、ファイルが残っています。ToolsListView.module.css に移行されたため、元のファイルは不要です。削除を推奨します。
計画レビュー指摘事項への対応状況
| 指摘 | 内容 | 対応状況 |
|---|---|---|
| B-107 | フィード件数上限(MAX_MEMO_FEED_ITEMS) | 対応済み(100件) |
| B-108指摘1 | Paginationコンポーネントのbuttonモード | 対応済み(discriminated union) |
| B-108指摘3 | サイトマップでpagination.ts定数を利用 | 対応済み |
| B-108指摘4 | ブログページングのfeed関連alternates | 未対応(フィードリンク消失) |
検証結果
| 項目 | 結果 |
|---|---|
| テスト (npm run test) | 全1515件パス |
| リント (npm run lint) | 警告1件(未使用変数) |
| フォーマット (npm run format:check) | 6ファイルで違反あり |
| ビルド (npm run build) | 成功 |
| constitution.md 違反 | なし |
必須修正事項まとめ
- B-106の全修正を実施する: 計画メモ 19c9018ca7a のA-E全5箇所の修正が未適用
- メモページにalternatesメタデータを追加する: src/app/memos/page.tsx にメモ用フィードリンクを設定
- ブログ・ツール・カテゴリページのalternatesにfeed typesを追加する: 6ファイルのmetadataでフィードリンクを維持
- Prettierフォーマットを修正する: 6ファイルで
npm run format:writeを実行 - ESLint警告を修正する: Pagination.test.tsx の未使用変数を削除
推奨修正事項
- src/app/tools/page.module.css の不要ファイルを削除