# Liam ERD コードリーディングガイドライン

## はじめに

このガイドラインは、Liam ERDプロジェクトのコードベースを効率的に理解するための手引きです。
TypeScript/React/Next.jsに精通していないエンジニアでも、段階的に学習できるよう構成されています。

**対象読者:**
- プロジェクトに新規参画するエンジニア
- 他言語からの経験者
- コードレビューを行う担当者

---

## 1. 言語基礎

> このセクションでは、TypeScriptの基本構文と概念を解説します。

### 1.1 プログラム構造

Liam ERDプロジェクトはTypeScriptで記述されています。TypeScriptはJavaScriptに静的型付けを追加した言語で、ファイル拡張子は`.ts`（純粋なTypeScript）または`.tsx`（JSXを含むTypeScript）です。

```typescript
// ファイル: frontend/apps/app/app/page.tsx:1-7
import { RootRedirectPage } from '../components/RootRedirectPage'

export const dynamic = 'force-dynamic'

export default async function Page() {
  return <RootRedirectPage />
}
```

**ポイント:**
- `import`文でモジュールをインポート
- `export`文で外部に公開
- 関数は`function`キーワードまたはアロー関数`() => {}`で定義

### 1.2 データ型と変数

TypeScriptでは変数に型を付与できます。`const`は再代入不可、`let`は再代入可能な変数宣言です。

```typescript
// ファイル: frontend/packages/ui/src/components/Button/Button.tsx:7-21
type Props = ComponentProps<'button'> & {
  variant?:
    | 'solid-primary'
    | 'solid-danger'
    | 'solid-inverse'
    | 'outline-secondary'
    | 'outline-overlay'
    | 'ghost-secondary'
  size?: 'xs' | 'sm' | 'md' | 'lg'
  leftIcon?: ReactNode
  rightIcon?: ReactNode
  isLoading?: boolean | undefined
  loadingIndicatorType?: 'leftIcon' | 'content'
  ref?: Ref<HTMLButtonElement>
}
```

**ポイント:**
- `type`キーワードで型エイリアスを定義
- `?`は省略可能なプロパティを示す
- `|`はユニオン型（複数の型のいずれか）

### 1.3 制御構造

条件分岐やループは標準的なJavaScript構文を使用します。このプロジェクトでは`ts-pattern`ライブラリによるパターンマッチングも多用されています。

```typescript
// ファイル: frontend/packages/ui/src/components/Button/Button.tsx:46-60
const variantClassName = match(variant)
  .with('solid-primary', () => styles.solidPrimary)
  .with('solid-danger', () => styles.solidDanger)
  .with('solid-inverse', () => styles.solidInverse)
  .with('outline-secondary', () => styles.outlineSecondary)
  .with('outline-overlay', () => styles.outlineOverlay)
  .with('ghost-secondary', () => styles.ghostSecondary)
  .exhaustive()

const sizeClassName = match(size)
  .with('xs', () => styles.xs)
  .with('sm', () => styles.sm)
  .with('md', () => styles.md)
  .with('lg', () => styles.lg)
  .exhaustive()
```

**ポイント:**
- `match()`と`.with()`でパターンマッチング
- `.exhaustive()`で全パターン網羅を保証

### 1.4 関数/メソッド定義

プロジェクトではアロー関数を主に使用し、`const`で関数を定義します。

```typescript
// ファイル: frontend/apps/app/hooks/usePublicShareServerAction.ts:33-64
const togglePublicShare = useCallback(async () => {
  const currentIsPublic = isPublicRef.current

  setIsLoading(true)

  const result = await fromPromise(
    currentIsPublic
      ? disablePublicShare(designSessionId)
      : enablePublicShare(designSessionId),
    (error) => ({
      success: false,
      error:
        error instanceof Error
          ? error.message
          : 'Failed to update sharing settings',
    }),
  )

  setIsLoading(false)

  return result.match(
    (data) => {
      if (data.success) {
        startTransition(() => {
          setIsPublic(data.isPublic ?? !currentIsPublic)
        })
      }
      return data
    },
    (errorData) => errorData,
  )
}, [designSessionId])
```

**ポイント:**
- `useCallback`でメモ化された関数を作成
- `async/await`で非同期処理
- `neverthrow`ライブラリの`fromPromise`でエラーハンドリング

### 1.5 モジュール/インポート

ES Modulesを使用し、名前付きエクスポートが推奨されています。

```typescript
// ファイル: frontend/packages/erd-core/src/index.ts:1-5
export * from './features'
export * from './hooks'
export * from './providers'
export * from './schemas'
```

```typescript
// ファイル: frontend/packages/ui/src/index.ts:1-7
export * from './components'
export * from './icons'
export * from './logos'
export * from './markers'
export * from './styles'
export * from './types'
```

**ポイント:**
- `export *`で再エクスポート
- `export { name }`で名前付きエクスポート
- デフォルトエクスポート（`export default`）は使用しない方針

---

## 2. プロジェクト固有の概念

> このセクションでは、当プロジェクト特有の概念を解説します。

### 2.1 フレームワーク固有の概念

#### Next.js App Router

Next.js 15を使用し、App Routerパターンを採用しています。

```typescript
// ファイル: frontend/apps/app/app/layout.tsx:34-52
export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode
}>) {
  return (
    <html lang="en">
      <GoogleTagManager
        gtmId={GTM_ID}
        dataLayer={{ appEnv: process.env.NEXT_PUBLIC_ENV_NAME ?? '' }}
      />
      <GtagScript />
      <GTMConsent />
      <body className={clsx(inter.className, montserrat.variable)}>
        <ToastProvider>{children}</ToastProvider>
      </body>
    </html>
  )
}
```

**ポイント:**
- `app/`ディレクトリ内の`page.tsx`がルートに対応
- `layout.tsx`で共通レイアウトを定義
- Server ComponentsとClient Componentsを使い分け

#### Server Actions

データミューテーションにはServer Actionsを使用します。

```typescript
// ファイル: frontend/apps/app/features/public-share/actions.ts:1-16
'use server'

import { createClient, createPublicServerClient } from '../../libs/db/server'

export async function checkPublicShareStatus(designSessionId: string) {
  // Use public client for checking share status (no auth required)
  const supabase = await createPublicServerClient()

  const { error } = await supabase
    .from('public_share_settings')
    .select('design_session_id')
    .eq('design_session_id', designSessionId)
    .single()

  return { isPublic: !error }
}
```

**ポイント:**
- `'use server'`ディレクティブでServer Actionを宣言
- サーバーサイドで実行される関数

### 2.2 プロジェクト独自のパターン

#### LangGraph AIエージェントシステム

AI機能は`@liam-hq/agent`パッケージでLangGraphを使用して実装されています。

```typescript
// ファイル: frontend/internal-packages/agent/src/createGraph.ts:69-108
const graph = new StateGraph(workflowAnnotation)
  .addNode('validateInitialSchema', validateInitialSchemaNode)
  .addNode('leadAgent', leadAgentSubgraph)
  .addNode('pmAgent', callPmAgent, { subgraphs: [pmAgentSubgraph] })
  .addNode('dbAgent', callDbAgent, { subgraphs: [dbAgentSubgraph] })
  .addNode('qaAgent', callQaAgent, { subgraphs: [qaAgentSubgraph] })

  .addConditionalEdges(
    START,
    (state) => {
      const isFirstExecution = !state.messages.some(
        (msg) => msg instanceof AIMessage,
      )

      const shouldValidateSchema =
        isFirstExecution && !isEmptySchema(state.schemaData)
      if (shouldValidateSchema) {
        return 'validateInitialSchema'
      }

      return 'leadAgent'
    },
    {
      validateInitialSchema: 'validateInitialSchema',
      leadAgent: 'leadAgent',
    },
  )
```

**ポイント:**
- `StateGraph`でワークフローを定義
- 複数のエージェント（Lead, PM, DB, QA）が連携
- サブグラフとして各エージェントを実装

#### neverthrowによるエラーハンドリング

Result型を使用した関数型エラーハンドリングパターンを採用しています。

```typescript
// ファイル: frontend/apps/app/components/SessionDetailPage/SessionDetailPage.tsx:30-92
async function loadSessionData(designSessionId: string): Promise<
  Result<
    {
      messages: StoredMessage[]
      buildingSchema: NonNullable<Awaited<ReturnType<typeof getBuildingSchema>>>
      initialSchema: Schema
      baselineSchema: Schema
      initialAnalyzedRequirements: AnalyzedRequirements | null
      workflowError: string | null
    },
    Error
  >
> {
  const buildingSchema = await getBuildingSchema(designSessionId)
  if (!buildingSchema) {
    return err(new Error('Building schema not found for design session'))
  }
  // ...
  return ok({
    messages,
    buildingSchema,
    initialSchema,
    baselineSchema,
    initialAnalyzedRequirements,
    workflowError,
  })
}
```

**ポイント:**
- `Result<T, E>`で成功/失敗を型安全に表現
- `ok()`で成功、`err()`で失敗を返す
- 例外を投げる代わりにResult型を返す

---

## 3. 命名規則

> このセクションでは、プロジェクト全体で使用される命名規則を解説します。

### 3.1 ファイル・ディレクトリ命名

| パターン | 意味 | 例 |
|---------|------|-----|
| PascalCase | Reactコンポーネント | `Button.tsx`, `SessionDetailPage.tsx` |
| camelCase | ユーティリティ、フック | `useStream.ts`, `parseSse.ts` |
| kebab-case | パッケージ名、ディレクトリ | `erd-core`, `internal-packages` |
| *.module.css | CSS Modules | `Button.module.css` |
| *.stories.tsx | Storybookストーリー | `Button.stories.tsx` |
| *.test.ts | テストファイル | `parseSse.test.ts` |

### 3.2 クラス・関数・変数命名

| プレフィックス/サフィックス | 意味 | 例 |
|---------------------------|------|-----|
| use* | Reactカスタムフック | `useStream`, `usePublicShareServerAction` |
| handle* | イベントハンドラ | `handleClick`, `handleSubmit` |
| is*, has*, can* | 真偽値 | `isLoading`, `hasError`, `canEdit` |
| *Provider | Reactコンテキストプロバイダ | `ToastProvider`, `ViewModeProvider` |
| *Context | Reactコンテキスト | `ViewModeContext` |
| *Schema | Valibotスキーマ | `schemaSchema`, `testCaseSchema` |
| *Annotation | LangGraph状態定義 | `workflowAnnotation` |

### 3.3 プログラム分類一覧

| 種類 | 場所 | 説明 |
|-----|------|-----|
| Page Component | `app/**/page.tsx` | ルーティングに対応するページ |
| Layout | `app/**/layout.tsx` | 共通レイアウト |
| Feature Component | `components/**`, `features/**` | 機能別UIコンポーネント |
| UI Component | `packages/ui/src/components/**` | 汎用UIコンポーネント |
| Hook | `hooks/**`, `**/hooks/**` | カスタムフック |
| Server Action | `**/actions.ts` | サーバーサイド処理 |
| Service | `**/services/**` | ビジネスロジック |
| Schema | `**/schemas/**` | データスキーマ定義 |

---

## 4. ディレクトリ構造

> このセクションでは、プロジェクトのディレクトリ構造を解説します。

```
liam-main/
├── frontend/
│   ├── apps/
│   │   ├── app/          # メインWebアプリケーション (@liam-hq/app)
│   │   ├── docs/         # ドキュメントサイト (@liam-hq/docs)
│   │   ├── assets/       # 静的アセット
│   │   └── erd-sample/   # ERDサンプル
│   │
│   ├── packages/         # 公開パッケージ
│   │   ├── cli/          # CLIツール (@liam-hq/cli)
│   │   ├── erd-core/     # ERD可視化コア (@liam-hq/erd-core)
│   │   ├── schema/       # スキーマパーサー (@liam-hq/schema)
│   │   └── ui/           # UIコンポーネント (@liam-hq/ui)
│   │
│   └── internal-packages/ # 内部パッケージ
│       ├── agent/        # AIエージェント (@liam-hq/agent)
│       ├── db/           # データベース (@liam-hq/db)
│       ├── github/       # GitHub連携
│       ├── mcp-server/   # MCPサーバー
│       └── ...
│
├── docs/                 # プロジェクトドキュメント
├── scripts/              # ビルド・セットアップスクリプト
└── config/               # 設定ファイル
```

### 各ディレクトリの役割

| ディレクトリ | 役割 | 主要ファイル |
|-------------|------|-------------|
| `frontend/apps/app` | メインWebアプリ | `app/`, `components/`, `features/` |
| `frontend/packages/ui` | 共有UIライブラリ | `src/components/`, `src/styles/` |
| `frontend/packages/erd-core` | ERD可視化ロジック | `src/features/erd/` |
| `frontend/packages/schema` | DBスキーマパース | `src/parser/`, `src/schema/` |
| `frontend/internal-packages/agent` | LangGraphエージェント | `src/createGraph.ts`, `src/db-agent/` |
| `frontend/internal-packages/db` | Supabase連携 | `supabase/`, `src/` |

---

## 5. アーキテクチャ

> このセクションでは、プロジェクトのアーキテクチャパターンを解説します。

### 5.1 全体アーキテクチャ

Turborepoによるモノレポ構成を採用し、pnpm workspacesでパッケージ管理を行っています。

```
┌─────────────────────────────────────────────────────────────┐
│                      Applications                            │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐          │
│  │  @liam-hq  │  │  @liam-hq  │  │  @liam-hq  │          │
│  │    /app    │  │   /docs    │  │   /cli     │          │
│  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘          │
│         │                │                │                  │
└─────────┼────────────────┼────────────────┼──────────────────┘
          │                │                │
┌─────────┼────────────────┼────────────────┼──────────────────┐
│         ▼                ▼                ▼                  │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐          │
│  │  @liam-hq  │  │  @liam-hq  │  │  @liam-hq  │          │
│  │ /erd-core  │  │   /schema  │  │    /ui     │          │
│  └─────────────┘  └─────────────┘  └─────────────┘          │
│                    Public Packages                           │
└──────────────────────────────────────────────────────────────┘
          │
┌─────────┼────────────────────────────────────────────────────┐
│         ▼                                                    │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐          │
│  │  @liam-hq  │  │  @liam-hq  │  │  @liam-hq  │          │
│  │   /agent   │  │    /db     │  │  /github   │          │
│  └─────────────┘  └─────────────┘  └─────────────┘          │
│                   Internal Packages                          │
└──────────────────────────────────────────────────────────────┘
```

### 5.2 レイヤー構成

| レイヤー | 責務 | 代表的なファイル |
|---------|------|-----------------|
| Presentation | UIレンダリング | `app/**/page.tsx`, `components/**/*.tsx` |
| Application | ユースケース実行 | `features/**`, `**/actions.ts` |
| Domain | ビジネスロジック | `**/services/**`, `packages/schema/` |
| Infrastructure | 外部サービス連携 | `libs/db/`, `internal-packages/db/` |

### 5.3 データフロー

```
ユーザー入力
    │
    ▼
┌─────────────┐     ┌─────────────┐
│   Client    │────▶│   Server    │
│  Component  │     │  Component  │
└─────────────┘     └──────┬──────┘
                           │
                           ▼
                   ┌─────────────┐
                   │   Server    │
                   │   Action    │
                   └──────┬──────┘
                           │
                           ▼
                   ┌─────────────┐
                   │  Supabase   │
                   │   Client    │
                   └──────┬──────┘
                           │
                           ▼
                   ┌─────────────┐
                   │  Database   │
                   │ (Supabase)  │
                   └─────────────┘
```

---

## 6. 主要コンポーネント

> このセクションでは、主要なコンポーネントとその連携を解説します。

### 6.1 エントリーポイント

Next.js App Routerの`app/page.tsx`がメインエントリーポイントです。

```typescript
// ファイル: frontend/apps/app/app/page.tsx:1-7
import { RootRedirectPage } from '../components/RootRedirectPage'

export const dynamic = 'force-dynamic'

export default async function Page() {
  return <RootRedirectPage />
}
```

### 6.2 ビジネスロジック

AIエージェントの中核ロジックは`@liam-hq/agent`パッケージにあります。

```typescript
// ファイル: frontend/internal-packages/agent/src/index.ts:1-19
export { createGraph } from './createGraph'
export { createDbAgentGraph } from './db-agent/createDbAgentGraph'
export { deepModeling } from './deepModeling'
export { deepModelingReplayStream } from './deepModelingReplayStream'
export { deepModelingStream } from './deepModelingStream'
export { getAnalyzedRequirements } from './getAnalyzedRequirements'
export { getCheckpointErrors } from './getCheckpointErrors'
export { getMessages } from './getMessages'
export { createSupabaseRepositories, InMemoryRepository } from './repositories'
```

### 6.3 データアクセス

Supabaseを使用したデータアクセスは`@liam-hq/db`パッケージで管理されています。

```typescript
// Server Actionでのデータアクセス例
// ファイル: frontend/apps/app/features/public-share/actions.ts:18-47
export async function enablePublicShare(designSessionId: string) {
  const supabase = await createClient()

  // Get current user
  const { data: userData, error: authError } = await supabase.auth.getUser()
  if (authError || !userData?.user) {
    return { success: false, error: 'Authentication required' }
  }

  // First check if the user has access to this design session
  const { data: session } = await supabase
    .from('design_sessions')
    .select('id')
    .eq('id', designSessionId)
    .single()

  if (!session) {
    return { success: false, error: 'Session not found' }
  }

  const { error } = await supabase
    .from('public_share_settings')
    .insert({ design_session_id: designSessionId })

  if (error) {
    return { success: false, error: error.message }
  }

  return { success: true, isPublic: true }
}
```

### 6.4 ユーティリティ/共通機能

UIコンポーネントは`@liam-hq/ui`パッケージから提供されます。

```typescript
// ファイル: frontend/packages/ui/src/components/Button/Button.tsx:23-82
export const Button = ({
  className,
  variant = 'solid-primary',
  size = 'sm',
  isLoading = false,
  loadingIndicatorType = 'leftIcon',
  leftIcon: propsLeftIcon,
  rightIcon,
  disabled: propsDisabled,
  children,
  ref,
  ...props
}: Props) => {
  const disabled = propsDisabled || isLoading
  // ...
  return (
    <button
      ref={ref}
      type="button"
      className={clsx(
        styles.wrapper,
        sizeClassName,
        className,
        variantClassName,
      )}
      disabled={disabled}
      {...props}
    >
      {leftIcon && <div className={styles.icon}>{leftIcon}</div>}
      {displayedChildren}
      {rightIcon && <div className={styles.icon}>{rightIcon}</div>}
    </button>
  )
}
```

---

## 7. よく使われるパターン

> このセクションでは、コード内で頻出するパターンを解説します。

### パターン一覧

| パターン | 説明 | 出現頻度 | 代表的なファイル |
|---------|------|---------|-----------------|
| Server Components | サーバーサイドデータフェッチ | 高 | `app/**/page.tsx` |
| Server Actions | サーバーサイドミューテーション | 高 | `**/actions.ts` |
| CSS Modules | スコープ付きスタイリング | 高 | `*.module.css` |
| Result型 | 関数型エラーハンドリング | 高 | `neverthrow`使用箇所 |
| Custom Hooks | ロジックの再利用 | 高 | `hooks/**`, `**/hooks/**` |
| Pattern Matching | 条件分岐の簡略化 | 中 | `ts-pattern`使用箇所 |
| LangGraph Workflow | AIエージェント実装 | 中 | `agent/src/**` |

### 各パターンの詳細

#### パターン1: Server Components

**目的:** サーバーサイドでデータをフェッチし、クライアントに送信するHTMLを最小化

**実装例:**
```typescript
// ファイル: frontend/apps/app/components/SessionDetailPage/SessionDetailPage.tsx:98-137
const SessionDetailPageInner: FC<InnerProps> = async ({
  designSessionId,
  panelSizes,
}) => {
  const result = await loadSessionData(designSessionId)

  if (result.isErr()) {
    throw result.error
  }

  const {
    messages,
    buildingSchema,
    initialSchema,
    baselineSchema,
    workflowError,
    initialAnalyzedRequirements,
  } = result.value

  const versions = await getVersions(buildingSchema.id)

  return (
    <SessionDetailPageClient
      buildingSchemaId={buildingSchema.id}
      designSessionId={designSessionId}
      initialMessages={messages}
      initialAnalyzedRequirements={initialAnalyzedRequirements}
      initialDisplayedSchema={initialSchema}
      baselineSchema={baselineSchema}
      initialVersions={versions}
      initialIsPublic={initialIsPublic}
      initialWorkflowError={workflowError}
      panelSizes={panelSizes}
    />
  )
}
```

**解説:** `async`関数としてコンポーネントを定義し、直接`await`でデータをフェッチ。エラーは`Result`型でハンドリングし、データはClient Componentにpropsとして渡します。

#### パターン2: Custom Hooks

**目的:** ステートフルなロジックを再利用可能な形で抽出

**実装例:**
```typescript
// ファイル: frontend/apps/app/hooks/usePublicShareServerAction.ts:13-70
export const usePublicShareServerAction = ({
  designSessionId,
  initialIsPublic = false,
}: UsePublicShareServerActionProps) => {
  const [isPublic, setIsPublic] = useState(initialIsPublic)
  const [isPending, startTransition] = useTransition()
  const [isLoading, setIsLoading] = useState(false)
  const isPublicRef = useRef(initialIsPublic)

  useEffect(() => {
    setIsPublic(initialIsPublic)
    isPublicRef.current = initialIsPublic
  }, [initialIsPublic])

  const togglePublicShare = useCallback(async () => {
    // ...処理
  }, [designSessionId])

  return {
    isPublic,
    loading: isLoading || isPending,
    togglePublicShare,
  }
}
```

**解説:** `use`プレフィックスで命名し、状態管理とロジックをカプセル化。戻り値として状態と操作関数を提供します。

---

## 8. 業務フロー追跡の実践例

> このセクションでは、実際の業務フローをコードで追跡する方法を解説します。

### 8.1 フロー追跡の基本手順

1. エントリーポイントを特定
2. 処理の流れを追跡（呼び出し関係を追う）
3. データの変換を確認
4. 最終的な出力を確認

### 8.2 フロー追跡の実例

#### 例1: デザインセッション詳細ページの表示

**概要:** ユーザーがセッション詳細ページにアクセスした際のデータフェッチフロー

**処理フロー:**
```
page.tsx → SessionDetailPage → loadSessionData → Supabase → 描画
```

**詳細な追跡:**

1. **ルーティング** (`frontend/apps/app/app/design_sessions/[id]/page.tsx`)
   - URLパラメータから`designSessionId`を取得
   - `SessionDetailPage`コンポーネントを呼び出し

2. **Server Component** (`frontend/apps/app/components/SessionDetailPage/SessionDetailPage.tsx:143-165`)
   ```typescript
   export const SessionDetailPage: FC<Props> = async ({ designSessionId }) => {
     const cookieStore = await cookies()
     const layoutCookie = cookieStore.get(PANEL_LAYOUT_COOKIE_NAME)
     const panelSizes = (() => {
       if (!layoutCookie) return DEFAULT_PANEL_SIZES
       try {
         const sizes = JSON.parse(layoutCookie.value)
         if (Array.isArray(sizes) && sizes.length >= 2) return sizes
       } catch {}
       return DEFAULT_PANEL_SIZES
     })()

     return (
       <Suspense fallback={<Fallback panelSizes={panelSizes} />}>
         <ViewModeProvider mode="private">
           <SessionDetailPageInner
             designSessionId={designSessionId}
             panelSizes={panelSizes}
           />
         </ViewModeProvider>
       </Suspense>
     )
   }
   ```

3. **データフェッチ** (`loadSessionData`関数)
   - Supabase経由でスキーマデータを取得
   - LangGraphからメッセージ履歴を取得
   - Result型でエラーハンドリング

4. **Client Componentへの引き渡し**
   - `SessionDetailPageClient`にpropsとしてデータを渡す
   - クライアントサイドでインタラクティブな機能を提供

### 8.3 フロー追跡チェックリスト

- [ ] エントリーポイントを特定したか
- [ ] 呼び出し関係を把握したか
- [ ] データの変換ポイントを確認したか
- [ ] エラーハンドリングを確認したか
- [ ] 最終的な出力を確認したか

---

## 9. 設計書の参照順序

> このセクションでは、プロジェクト理解のための設計書参照順序を案内します。

### 9.1 目的別ロードマップ

#### 全体像を把握したい場合
1. `README.md` - プロジェクト概要
2. `CLAUDE.md` - 開発ガイドライン
3. `CONTRIBUTING.md` - コントリビューションガイド
4. このコードリーディングガイドライン

#### 特定機能を理解したい場合
1. 対象パッケージの`package.json` - 依存関係確認
2. `src/index.ts` - エクスポート一覧
3. 関連するソースコード

#### 改修作業を行う場合
1. 対象機能のServer Component/Client Component
2. 関連するServer Actions
3. テストファイル（`*.test.ts`）

### 9.2 ドキュメント一覧

| ドキュメント | 概要 | 参照タイミング |
|-------------|------|---------------|
| `README.md` | プロジェクト概要 | 初回参画時 |
| `CLAUDE.md` | 開発ガイドライン | 開発時常時 |
| `CONTRIBUTING.md` | コントリビューションガイド | PR作成時 |
| `docs/langgraph/` | LangGraph実装ガイド | AI機能開発時 |
| `docs/migrationOpsContext.md` | DBマイグレーションガイド | DB変更時 |
| `docs/test-principles.md` | テスト方針 | テスト作成時 |

---

## 10. トラブルシューティング

> このセクションでは、コードリーディング時によくある問題と解決法を解説します。

### よくある疑問と回答

#### Q: `workspace:*`という依存関係は何ですか？
A: pnpm workspaceでのモノレポ内パッケージ参照です。同一リポジトリ内の他パッケージを参照しています。

#### Q: `'use server'`と`'use client'`の違いは？
A: `'use server'`はServer Actionsを宣言し、`'use client'`はClient Componentを宣言します。何も指定しない場合はServer Componentです。

#### Q: CSS Modulesの型定義はどこ？
A: `*.module.css.d.ts`ファイルが自動生成されます。`pnpm gen:css`で生成できます。

#### Q: Result型のエラーハンドリングはどう読む？
A: `result.isOk()`で成功判定、`result.isErr()`で失敗判定。`result.value`で成功値、`result.error`でエラーを取得します。

### デバッグのヒント

1. **Server Componentのデバッグ**: `console.log`はサーバーターミナルに出力されます
2. **Client Componentのデバッグ**: ブラウザのDevToolsを使用
3. **Server Actionsのデバッグ**: サーバーターミナルで確認
4. **型エラーの確認**: `pnpm lint:tsc`で型チェック

---

## 付録

### A. 用語集

| 用語 | 説明 |
|-----|------|
| ERD | Entity-Relationship Diagram（実体関連図） |
| Server Component | サーバーサイドでレンダリングされるReactコンポーネント |
| Client Component | クライアントサイドでインタラクティブに動作するコンポーネント |
| Server Action | サーバーサイドで実行されるミューテーション関数 |
| LangGraph | LangChainによるAIワークフローフレームワーク |
| Supabase | オープンソースのBaaS（Backend as a Service） |
| Valibot | 軽量なスキーマバリデーションライブラリ |
| neverthrow | Result型によるエラーハンドリングライブラリ |
| ts-pattern | TypeScript向けパターンマッチングライブラリ |

### B. ファイル一覧

| ファイル/ディレクトリ | 説明 | 主な内容 |
|---------------------|------|---------|
| `turbo.json` | Turborepo設定 | ビルドタスク定義 |
| `biome.jsonc` | Biome設定 | リンター/フォーマッター |
| `pnpm-workspace.yaml` | pnpm workspace設定 | パッケージ構成 |
| `tsconfig.json` | TypeScript設定 | コンパイラオプション |
| `.env.template` | 環境変数テンプレート | 必要な環境変数一覧 |

### C. 参考資料

- [Next.js 15 Documentation](https://nextjs.org/docs)
- [React 19 Documentation](https://react.dev/)
- [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/)
- [Supabase Documentation](https://supabase.com/docs)
- [LangGraph.js Documentation](https://langchain-ai.github.io/langgraphjs/)
- [Valibot Documentation](https://valibot.dev/)
- [neverthrow Documentation](https://github.com/supermacro/neverthrow)
