ディレクトリ構成
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.tsx、src/features/auth/server/adminSession.test.ts。tests/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/prisma | src/lib/prisma.ts |
@/features/terms | src/features/terms/index.ts |
@/features/terms/stores/searchAtoms | src/features/terms/stores/searchAtoms.ts |
@/features/terms/constants/categories | src/features/terms/constants/categories.ts |
@/features/terms/types/term | src/features/terms/types/term.ts |
@/features/terms/server/termsQuery | src/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