ディレクトリ構成
Directory Structure

1. プロジェクト全体のディレクトリ構成
Project Directory Structure

aws_glossary/
├── prisma/Prisma スキーマ・マイグレーション
│ └── migrations/wrangler d1 migrations 用 SQL ファイル
├── scripts/seed-data.ts → seed.sql を生成するスクリプト
├── workers/画像最適化 Queues コンシューマ Worker
├── src/
│ ├── app/Next.js App Router
│ │ ├── api/
│ │ │ ├── terms/GET 一覧・POST 登録・PUT 更新・DELETE 削除・画像アップロード
│ │ │ ├── auth/POST ログイン・POST ログアウト・GET セッション確認
│ │ │ └── media/GET R2 画像プロキシ配信
│ │
│ ├── components/共通 UI のみ(features を import しない)
│ │ ├── layout/
│ │ ├── providers/
│ │ └── ui/shadcn/ui コンポーネント(自動生成)
│ │
│ ├── features/Bulletproof React に準拠したフィーチャースライス
│ │ ├── auth/管理者認証 feature
│ │ │ ├── components/
│ │ │ ├── hooks/
│ │ │ └── server/HMAC セッション管理(サーバー専用)
│ │ │
│ │ └── terms/AWS 用語 feature(メインドメイン)
│ │ ├── api/fetch 関数 + React Query hook
│ │ ├── components/
│ │ │ └── search/
│ │ ├── hooks/
│ │ ├── stores/Jotai atoms(検索・カテゴリ・ページ・表示切替・パレット)
│ │ ├── schemas/Zod スキーマ(用語・検索パラメータ)
│ │ ├── server/listTerms(API Route・統合テスト共用)
│ │ ├── types/
│ │ └── constants/
│ │
│ ├── hooks/汎用フック(useDebounce 等)
│ └── lib/インフラ・ユーティリティ(feature に依存しない)
└── tests/
├── integration/Vitest + @cloudflare/vitest-pool-workers(D1)
└── e2e/Playwright E2E テスト
└── api/
ユニットテストの配置: *.test.ts / *.test.tsx はテスト対象ファイルと同ディレクトリに配置する(コロケーション)。 例: src/features/terms/components/TermForm.test.tsxsrc/features/auth/server/adminSession.test.tstests/unit/ ディレクトリは使用しない。

2. Bulletproof React 依存ルール
Bulletproof React Dependency Rules

各レイヤーは 下位レイヤーのみ を参照できる。矢印は参照可能な方向(上位 → 下位)を示す。上位レイヤーへの逆参照は禁止。

%%{init: {'theme': 'default', 'themeVariables': {'fontSize': '14px', 'lineColor': '#9ca3af', 'edgeLabelBackground': '#fff'}}}%% flowchart TD App["app/\nPages・API Routes"] Feat["features/*\nBusiness Logic"] Comp["components/\nShared UI"] Lib["lib/\nInfrastructure"] Hooks["hooks/\nShared Hooks"] App --> Feat App --> Comp App --> Lib Feat --> Comp Feat --> Lib Feat --> Hooks Comp --> Lib Hooks --> Lib classDef appC fill:#eff6ff,stroke:#3b82f6,color:#1d4ed8,font-weight:bold classDef featC fill:#f5f3ff,stroke:#8b5cf6,color:#6d28d9,font-weight:bold classDef compC fill:#f0fdf4,stroke:#22c55e,color:#15803d,font-weight:bold classDef libC fill:#fff7ed,stroke:#f97316,color:#c2410c,font-weight:bold classDef hooksC fill:#fdf4ff,stroke:#c026d3,color:#a21caf,font-weight:bold class App appC class Feat featC class Comp compC class Lib libC class Hooks hooksC

矢印の向き = import 可能方向 / 逆方向の import は禁止

レイヤー参照できる参照禁止
app/ ✅ features/*   components/*   lib/*
features/* ✅ components/ui   lib/*   hooks/* 🚫 他の features
components/ ✅ components/ui   lib/* 🚫 features
lib/ ✅ 外部パッケージのみ 🚫 features   components
hooks/ ✅ 外部パッケージのみ 🚫 features

3. インポートエイリアス設定
Import Alias Configuration

tsconfig.json に以下のエイリアスを設定し、相対パスを簡潔にする。

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}

使用例:

エイリアス実パス
@/lib/prismasrc/lib/prisma.ts
@/features/termssrc/features/terms/index.ts
@/features/terms/stores/searchAtomssrc/features/terms/stores/searchAtoms.ts
@/features/terms/constants/categoriessrc/features/terms/constants/categories.ts
@/features/terms/types/termsrc/features/terms/types/term.ts
@/features/terms/server/termsQuerysrc/features/terms/server/termsQuery.ts
import { createPrismaClient } from "@/lib/prisma"
import { GlossaryPage, useTermList } from "@/features/terms"
import { searchQueryAtom, categoryFilterAtom } from "@/features/terms/stores/searchAtoms"
import { CATEGORIES } from "@/features/terms/constants/categories"
import type { Category } from "@/features/terms/constants/categories"
import type { Term } from "@/features/terms/types/term"
import { listTerms } from "@/features/terms/server/termsQuery"

4. .gitignore 追加対象
.gitignore Targets

# D1 ローカルエミュレーション
.wrangler/

# ローカル開発用設定(認証情報・環境変数)
.dev.vars