Skip to content

Research & Design Decisions — data-model


Purpose: data-model spec の design 書き直し(commit f106c92 以降の 3 系統データアーキテクチャへの適合)に至った調査・統合判断・トレードオフを記録する。

Summary

  • Feature: data-model
  • Discovery Scope: Extension(既存プロジェクトのデータ層を 3 系統に再構築する大規模拡張)
  • Key Findings:
    • リセットコミット 02b2612 により prisma/features/lib/prisma.ts 等が削除済み。design.md は「再構築前提」で書く必要がある。
    • 要件 (requirements.md) は CMS / Neon / Vercel ENV の 3 系統への明確な責務分離を既に規定済みで、design は「どの境界に何を置くか」を実装に翻訳するフェーズ。
    • package.json に Prisma 7.8+ / @prisma/adapter-pg / Stripe 22 / Zod 4 は揃っているが microcms-js-sdk 未導入。導入と next.config.tsimages.remotePatterns 設定が design タスクの起点になる。

Research Log

Topic 1: 現リポジトリの実体(リセット後)の確認

  • Context: design 旧版は単一 Prisma モデル前提で書かれており、現リポジトリのコード実体と整合しているかを確認する必要があった。
  • Sources Consulted:
    • ls / package.json / prisma.config.ts / docker-compose.yml / next.config.ts / lib/utils.ts
    • 直近コミット履歴(02b2612, f106c92, 9228efc
  • Findings:
    • prisma/ ディレクトリは存在しない(リセット済み)。prisma.config.tsprisma/schema.prisma を指す設定のみ残置。
    • features/app/api/lib/prisma.tslib/microcms.ts は未作成。
    • package.json: prisma ^7.8.0, @prisma/adapter-pg ^7.8.0, @prisma/client ^7.8.0, pg ^8.16.3, stripe ^22.1.0, zod ^4.3.6microcms-js-sdk は無し。
    • docker-compose.ymlpostgres:17 がローカル開発用に定義済み。
  • Implications:
    • design.md は「ゼロからの再構築」を前提に File Structure Plan を具体化する必要がある。
    • 依存追加候補は microcms-js-sdk のみ。Neon serverless adapter は不要(pg + adapter-pg で要件を満たす)。

Topic 2: 要件で求められている境界の精査

  • Context: 旧 design は「全データを Prisma に持つ」前提で、AdminUser/VoteStatus/*Snapshot 列/totalAmountJpy 等の冗長フィールドを抱えていた。新 requirements に照らして本当に必要な列を確定する必要があった。
  • Sources Consulted:
    • .kiro/specs/data-model/requirements.md(7 entity × 40+ AC)
    • .kiro/steering/product.md.kiro/steering/tech.md.kiro/steering/structure.md
  • Findings:
    • Candidate / CreditPackage は microCMS 側で完全管理(編集権限・履歴・公開状態)。アプリ DB は ID 文字列でのみ参照する。
    • 投票期間は Vercel ENV の VOTING_PERIOD_START / VOTING_PERIOD_END で表現。DB シングルトンは要件外。
    • 投票の不変性は「Vote 単独」ではなく「Purchase.status='SUCCEEDED' との JOIN」で表現する仕様(VoteStatus 列は不要)。
    • 購入額・クレジット合計はクライアントが集計可能なため total* 列は不要。価格は creditPackages 側の完全 immutable で担保(snapshot 列不要)。
    • 管理者は外部の microCMS 管理画面で完結し、AdminUser テーブル不要。
  • Implications:
    • Neon に保持するモデルは Vote / Purchase / PurchaseItem の 3 つに縮退。
    • 「決済成立 = 不変」を JOIN ベースで一貫させるため、Vote には status を一切持たせない。
    • 価格・名称等の表示要素は読み取り時に microCMS から enrichment する。

Topic 3: 横断参照(cross-boundary reference)の整合戦略

  • Context: Vote/Purchase/PurchaseItem は外部 (microCMS) の Candidate / CreditPackage を参照する必要があるが、DB 上 FK を引けないため整合性戦略を確定する必要があった。
  • Sources Consulted:
    • requirements.md 「横断参照ルール」「整合性ポリシー」
    • microCMS 公開仕様(IDは文字列/削除運用は archive 推奨)
  • Findings:
    • 「string ID で参照し、取得時に enrichment、欠落は表示側でフォールバック」というパターンが要件と一致。
    • microCMS 側の archive 運用(hard delete を業務上禁止)でデータ消失リスクを許容範囲に抑えられる。
    • 投票時の存在検証は read-time(取得後 nullable に縮退)で十分。書込時の serializable lock は過剰。
  • Implications:
    • Prisma の candidateId / creditPackageIdString @db.Text
    • サービス層(features/cms/*features/candidates/voteAggregationService)が enrichment と欠落耐性を担う。

Topic 4: キャッシュ・読取性能戦略

  • Context: Home/Ranking 表示で 候補者リスト × 得票集計 を高頻度に返す必要があり、microCMS API 制限と Neon コストの双方を最小化する必要があった。
  • Sources Consulted:
    • Next.js 15 Data Cache / unstable_cache の現行ドキュメント
    • microcms-js-sdk のクライアント設計
  • Findings:
    • microCMS 取得結果は unstable_cache で 60〜180 秒 TTL のキャッシュが妥当。タグベース revalidate を介して webhook で即時無効化が可能。
    • 得票集計は分単位で揺れるため、Neon 集計はキャッシュせず、prisma.vote.groupBy({ where: { purchase: { status: 'SUCCEEDED' } } }) で都度集計。
  • Implications:
    • lib/microcms.ts で SDK client を singleton 生成。
    • voteAggregationServiceunstable_cache を使わず、サーバ component 直叩きを許す。

Architecture Pattern Evaluation

OptionDescriptionStrengthsRisks / LimitationsNotes
単一 Prisma DB に全データを集約(旧 design)Candidate/CreditPackage/VotingPeriod も全部 PostgresFK で整合性強制可能、トランザクション一貫編集 UI を自前実装、価格の改変リスク、運用負荷高requirements の 3 系統境界に反するため不採用
3 系統分離(採用)microCMS / Neon / Vercel ENV を責務で分離編集 UI 不要、価格不変を権限で担保、ENV で即時切替横断 FK なし・enrichment コストrequirements・steering と完全一致
Neon serverless adapter@neondatabase/serverless を直接利用Edge runtime 対応プロジェクトは Node ランタイム想定、追加依存と未検証コード不採用、@prisma/adapter-pg で十分

Design Decisions

Decision: 投票不変性を Votestatus カラムではなく Purchase.status との JOIN で表現する

  • Context: requirements 4.x で「決済成立した投票のみが有効、不変」とされる。旧 design は VoteStatus enum を持っていた。
  • Alternatives Considered:
    1. Vote.statusPENDING / CONFIRMED を持つ(二重管理)。
    2. Purchase.status='SUCCEEDED' を唯一の真実とし、Vote は status を持たない。
  • Selected Approach: 2 を採用。集計クエリは where: { purchase: { status: 'SUCCEEDED' } } で常に絞り込む。
  • Rationale: 二重管理による不整合を構造的に排除でき、Purchase の状態変化と Vote の意味が一意に同期する。
  • Trade-offs: 集計時に常に JOIN が必要だが、@@index([candidateId]) + @@index([status]) で実用上問題なし。
  • Follow-up: voteAggregationService 実装時にクエリプランを EXPLAIN で確認。

Decision: CreditPackage の不変性は microCMS のロール/フィールド権限で担保する

  • Context: requirements 6.x の「単価・クレジット数は購入後に変更されてはならない」を満たす必要があった。
  • Alternatives Considered:
    1. PurchaseItem*Snapshot 列で価格を写し取る。
    2. microCMS で当該パッケージの編集権限を作成者のみに制限し、価格変更を運用ルールで禁止。
  • Selected Approach: 2 を採用。PurchaseItem には creditPackageIdquantity のみ保持。
  • Rationale: snapshot 化は冗長で、価格を変えたい場合は「新パッケージ作成 + 旧パッケージ非公開」の運用で対応すれば十分。要件のスコープ外を増やさない。
  • Trade-offs: 価格表示を過去の購入で復元するには microCMS から取り直す必要があるが、要件は「購入時の値を再現する義務」を課していないため許容。
  • Follow-up: 運用 steering(structure.md / tech.md)の「microCMS スキーマ運用ルール」を後続で整備。

Decision: 投票期間を Vercel ENV (VOTING_PERIOD_START / VOTING_PERIOD_END) で管理する

  • Context: requirements 7.x で「投票期間は管理者がコード変更なしに切り替えられる」「単一の真実」を要求。
  • Alternatives Considered:
    1. Neon に VotingPeriod シングルトンテーブルを置く(旧 design)。
    2. microCMS の単一オブジェクトコレクションで持つ。
    3. Vercel ENV で持ち、lib/voting-period.ts でパース。
  • Selected Approach: 3。InvalidVotingPeriodErrorMISSING / INVALID_FORMAT / INVERTED_RANGE の cause つきで投げる。
  • Rationale: ENV 変更で即時切替、Postgres / microCMS 両方の依存を切れる、誤更新のリスクが最小。
  • Trade-offs: 値の更新に Vercel への deploy/redeploy が必要だが、頻度が低いため許容。
  • Follow-up: home/voting spec の design で同じ util を参照することを明記。

Decision: ニックネームは正規化(NFKC + 連続空白圧縮 + 前後 trim + UTF-16 1〜32)で同一性判定する

  • Context: requirements 5.x「同一文字列のニックネームを同一支援者として集計」「本人確認は行わない」。
  • Alternatives Considered:
    1. 正規化なしで生文字列を保存。
    2. 正規化のうえ保存、表示も正規化済みを使う。
  • Selected Approach: 2。normalizeNickname()features/voting/services/nicknameService.ts に集約し、書込前に必ず通す。
  • Rationale: 全角/半角/ゼロ幅スペース等の差で支援者ランキングが分散するのを防ぐ。表示も同じ文字列で行うため UI 上のブレも消える。
  • Trade-offs: 元の入力を完全復元はできないが、要件上必要ない。
  • Follow-up: voting spec design で UI 側のバリデーション文言を整備。

Risks & Mitigations

  • microCMS スキーマドリフト: microCMS 側で必須フィールド変更が起きると enrichment が壊れる。→ Zod による boundary parse、テストでスキーマ参照を固定。
  • 横断参照の dangling: microCMS で候補者を archive ではなく削除した場合に enrichment が null になる。→ 表示側でフォールバック表示、運用 steering で hard delete 禁止を明記。
  • Vercel ENV の誤設定: VOTING_PERIOD_START >= VOTING_PERIOD_END などで起動失敗。→ getVotingPeriod() 起動時検証で fail-fast、エラーページ表示で受付停止。
  • Prisma 7 系の安定性: 7.8 は比較的新しいバージョン。→ adapter-pg 経由で動作確認、マイグレーションは feature branch で先行検証。

References

  • .kiro/specs/data-model/requirements.md — 本 design の WHAT を規定する一次ソース
  • .kiro/steering/product.md / tech.md / structure.md — 3 系統データアーキテクチャの規約
  • commit f106c92 — 3 系統分離を spec/steering に反映した変更
  • commit 02b2612 — 業務ロジック層リセット(再構築の出発点)
  • Next.js 15 Data Cache / unstable_cache — microCMS 取得のキャッシュ戦略
  • microcms-js-sdk — 採用 SDK
  • Prisma @prisma/adapter-pg — Neon Postgres 接続

Gap Analysis Re-run(2026-05-17 / tasks-generated 後の再検証)

design / tasks が approved 済みの状態で、requirements.md と現リポジトリ実体の差分を改めて分解し、実装フェーズ(/kiro-impl data-model)が安全に開始できるかを確認する。フォーマットは .claude/skills/kiro-validate-gap/rules/gap-analysis.md の Output Checklist に従う。

Discovery Scope の再判定

  • Extension: 既存 Next.js プロジェクトの空の足場(app/page.tsx は再構築中プレースホルダ、components/ui/* は shadcn の汎用部品のみ、lib/utils.tscn だけ)に対して、データ層 3 系統(microCMS / Neon / Vercel ENV)と関連サービス層をゼロから追加する作業に相当する。Greenfield ではない(依存・設定・スケルトンは存在する)が、ドメインコードはほぼ未存在のため Extension の中でも「追加比率の高い拡張」に分類される。

1. Current State Investigation

Repo 構造とドメイン関連資産(実測)

パス現状data-model spec への寄与
app/layout.tsx / page.tsx(プレースホルダ)/ providers.tsx(空ラッパー)/ globals.css のみデータ層が組み込まれていないため、本 spec が lib/* / features/* を新設しても衝突しない
components/ui/shadcn の button/card/dialog/input/label/sonner/table/textarea のみ直接編集可(spec 外)。data-model spec は触れない
components/public/未作成本 spec のスコープ外(他 spec が後で作成)
lib/utils.tscn() のみ)prisma.ts / microcms.ts / voting-period.ts を新規追加するだけで衝突なし
features/未作成spec の File Structure Plan どおりに新規作成可能
prisma/未作成prisma.config.tsprisma/schema.prisma を指す設定のみ残置)schema.prisma / migrations/ / seed.ts をゼロから生成
types/未作成本 spec は型を features/cms/types.ts に集約する方針で types/** は使わない
auth.ts / app/admin/** / app/api/auth/** / app/api/images/**存在しない(リセット済み)structure.md の「保有しない」方針と整合、再導入禁止
docker-compose.ymlpostgres:17 でローカル DB を提供Prisma 7 + adapter-pg と整合、追加変更不要
next.config.ts空の NextConfigimages.remotePatterns の追記が必要(task 1.2)
package.json@prisma/client@^7.8.0 / @prisma/adapter-pg@^7.8.0 / prisma@^7.8.0 / pg(間接) / zod@^4 / stripe@^22 / @stripe/stripe-js@^9 / tsx@^4(dev)microcms-js-sdk が未導入。task 1.1 で追加が必要
tsconfig.jsonstrict: true、エイリアス @/* / @/components/* / @/design-tokens/*@/features/* エイリアスが未定義(structure.md には記述あり)。data-model 実装で features/ ディレクトリを新設するため、import 文を @/features/... ベースで書く場合は tsconfig.jsonpaths 更新が必要。または @/features/...@/* で代替する

Conventions(structure.md と実体の擦り合わせ)

  • 3 層モデル (app/features/components/) は steering で固定。data-model spec は features/lib/ のみ作成する(components/ には触れない)。
  • import エイリアス: tsconfig.json には @/features/* が未定義。structure.md の「import エイリアス(実態)」セクションでは @/features/* を含むと記述されているが、現ファイルでは欠落。実装時に tsconfig.json 直接編集が必要("直接編集可" パスに含まれる)か、@/features/* を使わず @/* を流用するかの判断点が生じる。
  • テスト: 本リポジトリには Vitest / Playwright のセットアップが存在しない(package.json に依存なし)。design.md の Testing Strategy で想定されている Unit / Integration / E2E はインフラ未整備のため、本 spec のタスク 1〜9 の範囲では実行できない。テスト基盤導入は別 spec / steering 改訂の対象(research needed)。
  • 環境変数: .env.local / .env.example がリポジトリに存在するかは未確認だが、docker-compose.ymlDATABASE_URL を期待する形式で書かれていない(直接接続文字列をローカルで組む前提)。MICROCMS_* / VOTING_PERIOD_* も追加が必要。

統合面(External Integration Surfaces)

  • microCMS: SDK 未導入、コレクション未作成、API キー未発行。spec の task 2.1〜2.3 で運営オペレーション(コレクション・権限・キー発行)を実施する必要があり、コード作業の前段にデータ基盤の準備が必須。
  • Neon: 接続情報(DATABASE_URL)の本番値は未投入だが、ローカルは docker-compose で代替可能。Prisma 7 + adapter-pg はパッケージ揃済み。
  • Vercel ENV: VOTING_PERIOD_START / VOTING_PERIOD_END の投入は運営オペレーション。getVotingPeriod() の起動時バリデーションは fail-fast 設計のため、開発時 .env.local のテンプレートも合わせて整備する必要がある。
  • Stripe: 本 spec のスコープ外(voting spec 担当)だが、Purchase の paymentIntentId UNIQUE 制約と Webhook ハンドラのインターフェースは本 spec のスキーマで吸収済み。

2. Requirements Feasibility Analysis(Requirement-to-Asset Map)

要件必要アセット現状アセットGap タグ
Feature 1(Candidate, AC 1.1–1.7)microCMS candidates コレクション + ロール権限 + features/cms/services/candidateService.tsコレクション未作成、サービス未作成Missing(運営オペ + コード)
Feature 2(CandidateImage, AC 2.1–2.7)microCMS 画像フィールド(MIME 制限、5MB 上限)+ next.config.ts.images.remotePatterns未設定 / 未設定Missing(運営オペ + 設定)
Feature 3(CreditPackage, AC 3.1–3.7)microCMS creditPackages コレクション + フィールド権限ロック + features/cms/services/creditPackageService.ts全て未作成Missing
Feature 4(Vote, AC 4.1–4.8)Prisma Vote model + votes (candidateId) 等 index + voteAggregationService + nicknameService全て未作成Missing
Feature 5(Purchase, AC 5.1–5.6)Prisma Purchase + PaymentStatus enum + UNIQUE 制約 + Webhook ハンドラとの IFスキーマ未作成、Webhook ハンドラ未作成(voting spec 担当)Missing(本 spec ではスキーマ部分のみ)
Feature 6(PurchaseItem, AC 6.1–6.5)Prisma PurchaseItem + UNIQUE(purchaseId, creditPackageId) + CHECK (quantity ≥ 1)全て未作成Missing
Feature 7(VotingPeriod, AC 7.1–7.5)Vercel ENV キー定義 + lib/voting-period.tsgetVotingPeriod + InvalidVotingPeriodError未投入 / 未作成Missing
共通属性(id / createdAt / updatedAt)Prisma @id @default(uuid()) / @default(now()) / @updatedAt未作成Missing
越境参照規約String @db.Text カラム + 外部キー無し + 集計時 enrichment未作成Missing
ニックネーム正規化normalizeNickname(NFKC + 空白圧縮 + trim + 長さ検証)未作成Missing

Unknown / Constraint

  • Unknown 1: tsconfig.jsonpaths@/features/* を追加するかどうかは、structure.md と実ファイルで言及が食い違っている(Research Needed: 既存 lint / build を壊さず追加できるか、design 段階で確定)。
  • Unknown 2: テスト基盤(Vitest)が未導入のため、design.md / tasks.md で想定されている Unit / Integration テストは 現実装フェーズでは検証不能。完了判定を「コード書き起こし + prisma validate + ローカル DB マイグレーション適用」までに限るのか、テスト基盤導入を本 spec タスクに含めるのかは design レビュー時点で判断するべき(Research Needed)。
  • Unknown 3: microCMS の「物理削除禁止」ロール権限がプラットフォーム機能だけで完全に強制可能かは microCMS の現行プラン依存(フィールド権限プランで担保する想定)。プラン未確定なら運用ルール + 監査ログによる事後検出に切り替える必要がある(Research Needed)。
  • Constraint 1: 保護パス(prisma/** / features/** / lib/prisma.ts 等)は CLAUDE.md により直接編集禁止。/kiro-impl data-model 経由のみで作成可能。
  • Constraint 2: package.json への依存追加は spec/design に紐付くのが望ましいと CLAUDE.md にあり、microcms-js-sdk 追加は本 spec の tasks 1.1 に明示済みで整合。

Complexity Signal

  • 多くの要件は 新規ファイル追加 + 既存パターン踏襲 の単純な拡張で、ロジック面でアルゴリズム的に難しい部分はない。
  • ただし「3 系統を整合的に縫う越境参照」「Webhook トランザクション境界」「環境変数の起動時バリデーション」など、統合点が多い点が複雑さの実体。本 spec は契約定義に留まり、実際の Webhook ハンドラや PaymentIntent 作成は voting spec が担う構造で複雑度を局所化済み。

3. Implementation Approach Options

Option A — design.md / tasks.md にそのまま従う(Extend the Plan)

  • 概要: 既に approved 済みの design.md(3 系統分離、Vote/Purchase/PurchaseItem の 3 モデル、microCMS 完全イミュータブル、ENV ベース投票期間)と tasks.md(9 セクション)をそのまま /kiro-impl data-model で順番に実装する。
  • トレードオフ:
    • 良: spec / steering / 過去の研究ログ全てと完全整合。再設計コスト 0。Boundary Commitments と Out-of-Boundary が明確で、他 spec への影響範囲がコントロール済み。
    • 良: パッケージ追加が microcms-js-sdk のみで済み、依存変更が極小。
    • 悪: テスト基盤未整備のまま実装に入るため、design.md の Testing Strategy セクションは「該当ファイルを後で書く」前提となり、完了判定が緩くなる。
    • 悪: tsconfig.json@/features/* 不在が顕在化したときに、保護パスかどうか不明な微妙な編集(tsconfig.json 自体は "直接編集可")を実行する判断が必要。
  • 適合度: 高い。本 spec の Discovery Scope(Extension)と Boundary Commitments の整合性は完璧。

Option B — テスト基盤(Vitest)を本 spec に内包し、Unit / Integration を即時検証可能にする(Wider Extension)

  • 概要: Option A のタスクに加え、vitest.config.ts / vitest 依存 / tsconfig の test 設定 / prisma/seed.ts の dummy データ整備を本 spec のタスクに追加する。
  • トレードオフ:
    • 良: design.md の Testing Strategy が実行可能になり、各レイヤーの単体検証が早期に成立。normalizeNickname の境界値・getVotingPeriod のエラー分岐・voteAggregationService の JOIN フィルタが、実装中に CI で守られる。
    • 悪: tasks.md(approved 済み)を改変する必要があり、spec の再 approval が発生する。
    • 悪: Vitest セットアップは本来 steering / testing spec の担当領域で、data-model spec のスコープを越える可能性が高い。
  • 適合度: 中。テスト基盤の責務が data-model に過剰流入するため、別 spec で扱うのが筋。

Option C — ハイブリッド: design / tasks は維持しつつ、testability の最小限だけ取り込む

  • 概要: Option A をベースに、(i) Prisma の seed.ts を空ファイルで作成して将来の seed を妨げない、(ii) normalizeNickname / getVotingPeriod のような純関数は テスト基盤なしでも tsx で実行可能な smoke スクリプトscripts/ 配下)を 1 本だけ用意して Acceptance 確認に使う、という方針。Vitest は導入せず、本格テストは別 spec に切り出す。
  • トレードオフ:
    • 良: tasks.md の修正は seed.ts の追加(既に design.md にあり)と smoke script の追加だけで済み、approved 範囲を超える改変は最小。
    • 良: 純関数の挙動を /kiro-impl 中に手動確認できるため、レビューア subagent の判定材料が増える。
    • 悪: scripts/** は保護パスのため、CLAUDE.md のガードを越えるには本 spec の design に追加するか、本 spec とは別の小さな spec(テスト基盤)を立てる必要がある。
  • 適合度: 中〜高。Boundary を越えるリスクは小さいが、scripts 追加の合理化に design 改訂が必要。

4. Effort & Risk

観点判定1 行根拠
EffortM(3–7 日)新規ファイル数は中程度(lib/* 3 本 + features/* 4 本 + Prisma 一式)。難所は microCMS スキーマと Prisma マイグレーション + index 設定で、コード量より「運営オペ + 統合確認」のラウンドトリップがクリティカルパス。
RiskMediumパターンは確立済み(Prisma / microCMS いずれも標準ライブラリ)。リスクは (1) microCMS フィールド権限がプラン依存、(2) テスト未整備による品質ゲートの不在、(3) 越境参照の dangling を本番で踏むまで気付きにくい設計。アーキテクチャ的な未知数はない。

5. design phase への推奨事項(実装直前の確認事項)

design.md は approved 済みだが、/kiro-impl data-model 起動前に以下の確認を済ませるとリスクが下がる。

  1. 推奨アプローチ: Option A(design / tasks の通り実装)。Option C の smoke script は必要に応じて、本 spec を /kiro-impl した後の Follow-up(testing-foundation 等の新 spec)で対応する方が境界がきれい。
  2. Key Decisions(再確認):
    • Vote 不変性は Purchase.status='SUCCEEDED' JOIN で表現(Vote に status 列を持たせない)— 過去ログ Decision 1 と一致。
    • CreditPackage の不変性は microCMS フィールド権限 で担保(PurchaseItem に snapshot を持たない)— Decision 2 と一致。
    • VotingPeriod は Vercel ENV + 起動時 fail-fast バリデーション(DB シングルトンを使わない)— Decision 3 と一致。
    • ニックネーム正規化は NFKC + 空白圧縮 + trim + UTF-16 1〜32(Server / Client 両方から import 可能な純関数として export)— Decision 4 と一致。
  3. tsconfig.json の @/features/* パス追加: /kiro-impl の最初のタスクで、import 文の書き方を @/features/... で統一する場合は tsconfig.json への "@/features/*": ["./features/*"] 追加が必要。tsconfig.json は CLAUDE.md の "直接編集可" パスに含まれるため、本 spec の作業中に追加してよい。design.md の File Structure Plan には現状この追加が明示されていないため、design レビュー時に Modified Files へ加筆するか、/kiro-impl 内で例外的に編集する旨をレビューア subagent に申告する。
  4. 環境変数テンプレート: .env.local / .env.example の整備は design / tasks に明示が薄い。MICROCMS_SERVICE_DOMAIN / MICROCMS_API_KEY_READONLY / VOTING_PERIOD_START / VOTING_PERIOD_END / DATABASE_URL のテンプレートを .env.example に追加する手順を /kiro-impl 開始時に確認する(.env.example は spec 外パスのため直接編集可)。
  5. Research Needed(次フェーズに持ち越し):
    • R1: microCMS の現プランで「物理削除禁止」「フィールド単位の編集ロック」がロールベースで強制可能か、コンソール上で実機確認する(task 2.1 / 2.2 の事前確認)。
    • R2: テスト基盤(Vitest)導入を別 spec として立てるか、本 spec の Follow-up として /kiro-spec-init "testing-foundation" を提案する。design.md の Testing Strategy 項目を「実行は別 spec」と注記する変更も検討。
    • R3: vote.createMany の SQL サイズ上限を、合計票数の上限想定(数千〜想定最大)でローカル PG に対し先行 EXPLAIN / ベンチで確認(task 3.2 / 4 系の補強)。
    • R4: next.config.tsimages.remotePatterns に登録する microCMS の正確な配信ホスト(images.microcms-assets.io 等)を、microCMS のドキュメント現行版で確認する(task 1.2)。
  6. 想定外時の Fallback: microCMS フィールド権限プランが要件を満たさなかった場合、CreditPackage の name / credits / priceJpyPurchaseItem に snapshot として保持 する迂回路に切り替える(design.md の Decision 2 を覆す変更)。この場合は requirements.md は変えず design.md / tasks.md / Prisma スキーマだけを更新する。