# 機能設計書 55-create-payload-app

## 概要

本ドキュメントは、Payload CMSプロジェクト作成CLI（create-payload-app）の機能設計を定義する。このCLIツールは、新しいPayloadプロジェクトの作成、既存Next.jsプロジェクトへのPayload統合、テンプレートやサンプルからのプロジェクト生成を提供する。

### 本機能の処理概要

create-payload-appは、インタラクティブなCLIを通じて、開発者がPayload CMSプロジェクトを素早くセットアップできるようにするツールである。

**業務上の目的・背景**：新しいCMSプロジェクトの開始には、依存関係のインストール、設定ファイルの作成、データベース接続の設定など多くの手順が必要である。create-payload-appはこれらの手順を自動化し、開発者が数分でPayloadプロジェクトを開始できるようにする。また、既存のNext.jsプロジェクトにPayloadを追加する場合も、適切なファイル配置と設定変更を自動で行う。

**機能の利用シーン**：
- 新しいPayloadプロジェクトを開始する場合
- 既存のNext.jsプロジェクトにPayloadを統合する場合
- 公式テンプレート（blank、website、ecommerce等）からプロジェクトを作成する場合
- 公式サンプルプロジェクトを試す場合
- Payloadプラグインのスターターを作成する場合

**主要な処理内容**：
1. プロジェクト名の解析と検証
2. データベースタイプの選択（MongoDB、PostgreSQL、SQLite等）
3. テンプレート/サンプルのダウンロードと展開
4. payload.config.tsのAST変換（データベースアダプター設定等）
5. 環境ファイル（.env）の生成と設定
6. package.jsonの更新（依存関係のバージョン固定）
7. 依存関係のインストール
8. Gitリポジトリの初期化

**関連システム・外部連携**：
- npm registry: 最新バージョンの取得
- GitHub: テンプレート/サンプルのダウンロード
- パッケージマネージャー（npm、yarn、pnpm、bun）
- Next.js: 既存プロジェクト検出と統合

**権限による制御**：CLIツールのため、実行時のファイルシステム権限に依存。

## 関連画面

本機能はCLIツールであり、Payload CMSの管理画面とは直接関連しない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 管理画面との直接の関連なし |

## 機能種別

開発ツール / プロジェクト生成 / CLI

## 入力仕様

### 入力パラメータ

#### CLIオプション

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| --name, -n | string | No | プロジェクト名 | slugify処理 |
| --template, -t | string | No | 使用するテンプレート | 有効なテンプレート名 |
| --example, -e | string | No | 使用するサンプル | 有効なサンプル名 |
| --db, -d | string | No | データベースタイプ | mongodb/postgres/sqlite等 |
| --db-connection-string | string | No | データベース接続文字列 | - |
| --db-accept-recommended | boolean | No | 推奨DB設定を自動承認 | - |
| --init-next | boolean | No | 既存Next.jsへの統合 | Next.js検出 |
| --use-npm/yarn/pnpm/bun | boolean | No | パッケージマネージャー指定 | - |
| --no-deps | boolean | No | 依存関係インストールをスキップ | - |
| --no-git | boolean | No | Git初期化をスキップ | - |
| --secret | string | No | PAYLOAD_SECRET指定 | - |
| --version | string | No | Payloadバージョン指定 | npm registry存在確認 |
| --branch | string | No | テンプレート取得ブランチ | - |
| --debug | boolean | No | デバッグモード | - |
| --dry-run | boolean | No | ドライラン（実行しない） | - |
| --help, -h | boolean | No | ヘルプ表示 | - |

### 入力データソース

- コマンドライン引数
- インタラクティブプロンプト（@clack/prompts）
- ファイルシステム（Next.js検出）

## 出力仕様

### 出力データ

#### 生成ファイル/ディレクトリ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| projectDir | directory | プロジェクトディレクトリ |
| payload.config.ts | file | Payload設定ファイル |
| .env | file | 環境変数ファイル |
| package.json | file | パッケージ定義（更新済み） |
| .git | directory | Gitリポジトリ（オプション） |

### 出力先

- ファイルシステム: 指定されたプロジェクトディレクトリ
- コンソール: 進捗状況、成功/エラーメッセージ

## 処理フロー

### 処理シーケンス

```
1. CLI引数解析（arg）
   └─ オプション・フラグの取得
2. Next.js検出
   ├─ 既存Next.jsプロジェクトか判定
   └─ Payload既存インストール確認
3. プロジェクト名取得
   └─ 引数またはプロンプトで入力
4. データベースタイプ選択
   └─ プロンプトまたは引数から決定
5. テンプレート/サンプル処理
   ├─ テンプレートダウンロード
   └─ ローカルコピー（開発用）
6. 設定ファイル更新
   ├─ payload.config.ts AST変換
   └─ package.json更新
7. 環境ファイル生成
   └─ .env作成、PAYLOAD_SECRET生成
8. 依存関係インストール
   └─ パッケージマネージャーで実行
9. Git初期化
   └─ リポジトリ作成、初回コミット
```

### フローチャート

```mermaid
flowchart TD
    A[CLI実行] --> B{--helpフラグ}
    B -->|Yes| C[ヘルプ表示]
    B -->|No| D[Next.js検出]
    D --> E{Next.jsプロジェクト内}
    E -->|Yes| F{Payload既存インストール}
    F -->|Yes| G[アップグレード確認]
    F -->|No| H[--init-nextフロー]
    E -->|No| I[プロジェクト名取得]
    I --> J{--template or --example}
    J -->|template| K[テンプレートフロー]
    J -->|example| L[サンプルフロー]
    K --> M[DB選択]
    M --> N[テンプレートダウンロード]
    N --> O[設定ファイル更新]
    O --> P[.env生成]
    P --> Q{--no-deps}
    Q -->|No| R[依存関係インストール]
    Q -->|Yes| S[スキップ]
    R --> T{--no-git}
    S --> T
    T -->|No| U[Git初期化]
    T -->|Yes| V[完了]
    U --> V
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-55-01 | Next.js検出 | カレントディレクトリでnext.config.tsを検索 | 起動時 |
| BR-55-02 | バージョン固定 | workspace:*をPayload最新バージョンに置換 | package.json更新時 |
| BR-55-03 | シークレット生成 | PAYLOAD_SECRETを自動生成 | .env作成時 |
| BR-55-04 | スラッグ化 | プロジェクト名をスラッグ形式に変換 | プロジェクトディレクトリ作成時 |
| BR-55-05 | Next.js 15以上必須 | Next.js 15未満の場合は警告表示 | Next.js検出時 |
| BR-55-06 | top-level layout検出 | app/layout.tsxが存在する場合は警告 | --init-next時 |

### 計算ロジック

**バージョン更新ロジック**:
```typescript
// workspace:*またはPayloadパッケージをlatestVersionに更新
if (value.startsWith('workspace:')) {
  acc[key] = latestVersion
} else if (key === 'payload' || key.startsWith('@payloadcms')) {
  acc[key] = latestVersion
}
```

**シークレット生成ロジック**:
```typescript
// ランダムな文字列でPAYLOAD_SECRETを生成
const secret = generateSecret() // crypto.randomBytes等を使用
```

## データベース操作仕様

create-payload-appはデータベースを直接操作しない。データベース設定は生成されるpayload.config.tsに記述される。

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | テンプレート無効 | 無効なテンプレート名指定 | ヘルプ表示、終了 |
| - | Next.js非対応バージョン | Next.js 15未満 | 警告表示、終了 |
| - | 依存関係インストール失敗 | パッケージマネージャーエラー | エラーメッセージ表示 |
| - | バージョン不存在 | 指定バージョンがnpmに存在しない | エラーで終了 |

### リトライ仕様

依存関係インストールの失敗時にリトライは行わない。ユーザーが手動で再実行可能。

## トランザクション仕様

トランザクション管理は不要。ファイル操作は逐次実行。

## パフォーマンス要件

- テンプレートダウンロードはtar形式で効率化
- npm registryへのリクエストは最小限に

## セキュリティ考慮事項

- PAYLOAD_SECRETは暗号学的に安全なランダム文字列で生成
- .envファイルは.gitignoreで除外される
- 外部URLからのダウンロードはPayload公式GitHubリポジトリに限定

## 備考

- ts-morphを使用したAST変換でpayload.config.tsを安全に更新
- @clack/promptsでモダンなインタラクティブUIを提供
- Node.js 18.20.2以上または20.9.0以上が必要

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、CLI引数とプロジェクト関連の型定義を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.ts | `packages/create-payload-app/src/types.ts` | CliArgs、ProjectTemplate、DbType等の型定義 |

**読解のコツ**:
- **5-35行目**: Args interface でCLI引数の定義
- **39-62行目**: ProjectTemplate、GitTemplate、PluginTemplateの型
- **71-78行目**: PackageManager、DbType、DbDetailsの定義
- **82-95行目**: NextAppDetails型でNext.js検出結果を表現

#### Step 2: エントリーポイントを理解する

CLIのメイン処理フローを把握。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | main.ts | `packages/create-payload-app/src/main.ts` | Mainクラス、init()メソッド |

**主要処理フロー**:
1. **32-78行目**: コンストラクタでarg()によるCLI引数解析
2. **80-97行目**: ヘルプ表示、デバッグモード設定
3. **104-142行目**: Next.js検出、Payload既存インストール確認
4. **144-210行目**: --init-nextフロー（既存Next.jsへの統合）
5. **212-282行目**: テンプレート/サンプルフロー

#### Step 3: プロジェクト作成処理を理解する

テンプレートダウンロードから設定完了までの処理を把握。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | create-project.ts | `packages/create-payload-app/src/lib/create-project.ts` | createProject関数 |

**主要処理フロー**:
- **73-189行目**: createProject関数メイン処理
- **89-127行目**: テンプレート/サンプルのダウンロードまたはローカルコピー
- **129-147行目**: Payload最新バージョン取得、package.json更新
- **151-162行目**: payload.config.ts設定
- **164-171行目**: .env生成
- **173-184行目**: 依存関係インストール
- **186-188行目**: Git初期化

#### Step 4: AST変換処理を理解する

payload.config.tsの変換処理を把握。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | configure-payload-config.ts | `packages/create-payload-app/src/lib/configure-payload-config.ts` | configurePayloadConfig関数 |

**主要処理フロー**:
- ts-morphを使用したAST解析と変換
- データベースアダプターのインポート追加
- buildConfig()内のdb設定更新

#### Step 5: Next.js統合処理を理解する

既存Next.jsプロジェクトへのPayload追加処理を把握。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | init-next.ts | `packages/create-payload-app/src/lib/init-next.ts` | initNext、getNextAppDetails関数 |

**主要処理フロー**:
- Next.jsプロジェクト検出
- Payloadパッケージのインストール
- 必要なファイルのコピー

### プログラム呼び出し階層図

```
Main (main.ts)
    │
    ├─ parseProjectName (parse-project-name.ts)
    │
    ├─ getNextAppDetails (init-next.ts)
    │      └─ Next.js検出、バージョン確認
    │
    ├─ initNext (init-next.ts)
    │      ├─ パッケージインストール
    │      └─ ファイルコピー
    │
    ├─ selectDb (select-db.ts)
    │      └─ データベースタイプ選択
    │
    ├─ createProject (create-project.ts)
    │      ├─ downloadTemplate (download-template.ts)
    │      ├─ downloadExample (download-example.ts)
    │      ├─ updatePackageJSON
    │      ├─ configurePayloadConfig (configure-payload-config.ts)
    │      │      └─ AST変換 (lib/ast/*)
    │      ├─ manageEnvFiles (manage-env-files.ts)
    │      ├─ installDeps
    │      └─ tryInitRepoAndCommit (utils/git.ts)
    │
    └─ parseTemplate (parse-template.ts)
           └─ テンプレート選択
```

### データフロー図

```
[入力]                    [処理]                         [出力]

CLI引数 ────────────┐
                     │
インタラクティブ入力 ─┼──▶ Main.init() ──▶ プロジェクトディレクトリ
                     │        │
ファイルシステム ────┘        │
(Next.js検出)                 ▼
                     テンプレートダウンロード
                              │
                              ▼
                     AST変換（payload.config.ts）
                              │
                              ▼
                     package.json更新
                              │
                              ▼
                     .env生成
                              │
                              ▼
                     依存関係インストール
                              │
                              ▼
                     Git初期化
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| main.ts | `packages/create-payload-app/src/main.ts` | エントリー | CLIメイン処理 |
| types.ts | `packages/create-payload-app/src/types.ts` | 型定義 | 共通型定義 |
| index.ts | `packages/create-payload-app/src/index.ts` | エクスポート | パッケージエントリー |
| create-project.ts | `packages/create-payload-app/src/lib/create-project.ts` | ソース | プロジェクト作成処理 |
| init-next.ts | `packages/create-payload-app/src/lib/init-next.ts` | ソース | Next.js統合処理 |
| configure-payload-config.ts | `packages/create-payload-app/src/lib/configure-payload-config.ts` | ソース | payload.config.ts設定 |
| select-db.ts | `packages/create-payload-app/src/lib/select-db.ts` | ソース | DB選択処理 |
| manage-env-files.ts | `packages/create-payload-app/src/lib/manage-env-files.ts` | ソース | 環境ファイル管理 |
| download-template.ts | `packages/create-payload-app/src/lib/download-template.ts` | ソース | テンプレートダウンロード |
| download-example.ts | `packages/create-payload-app/src/lib/download-example.ts` | ソース | サンプルダウンロード |
| templates.ts | `packages/create-payload-app/src/lib/templates.ts` | ソース | テンプレート定義 |
| generate-secret.ts | `packages/create-payload-app/src/lib/generate-secret.ts` | ソース | シークレット生成 |
| package.json | `packages/create-payload-app/package.json` | 設定 | パッケージ定義 |
