@einja/dev-cli 0.1.29 → 0.1.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/commands/task-loop/index.d.ts.map +1 -1
- package/dist/commands/task-loop/index.js +128 -10
- package/dist/commands/task-loop/index.js.map +1 -1
- package/dist/commands/task-loop/lib/task-state-manager.d.ts +33 -2
- package/dist/commands/task-loop/lib/task-state-manager.d.ts.map +1 -1
- package/dist/commands/task-loop/lib/task-state-manager.js +74 -3
- package/dist/commands/task-loop/lib/task-state-manager.js.map +1 -1
- package/dist/commands/task-loop/lib/task-state-manager.test.js +252 -1
- package/dist/commands/task-loop/lib/task-state-manager.test.js.map +1 -1
- package/dist/commands/task-loop/lib/types.d.ts +18 -13
- package/dist/commands/task-loop/lib/types.d.ts.map +1 -1
- package/dist/commands/task-loop/lib/vibe-kanban-client.d.ts +24 -170
- package/dist/commands/task-loop/lib/vibe-kanban-client.d.ts.map +1 -1
- package/dist/commands/task-loop/lib/vibe-kanban-client.js +65 -244
- package/dist/commands/task-loop/lib/vibe-kanban-client.js.map +1 -1
- package/dist/commands/task-loop/lib/vibe-kanban-client.test.js +185 -127
- package/dist/commands/task-loop/lib/vibe-kanban-client.test.js.map +1 -1
- package/dist/commands/task-loop/lib/vibe-kanban-rest-client.d.ts +47 -0
- package/dist/commands/task-loop/lib/vibe-kanban-rest-client.d.ts.map +1 -1
- package/dist/commands/task-loop/lib/vibe-kanban-rest-client.js +116 -0
- package/dist/commands/task-loop/lib/vibe-kanban-rest-client.js.map +1 -1
- package/dist/commands/task-loop/lib/vibe-kanban-rest-client.test.d.ts +2 -0
- package/dist/commands/task-loop/lib/vibe-kanban-rest-client.test.d.ts.map +1 -0
- package/dist/commands/task-loop/lib/vibe-kanban-rest-client.test.js +293 -0
- package/dist/commands/task-loop/lib/vibe-kanban-rest-client.test.js.map +1 -0
- package/package.json +1 -1
- package/presets/default/.claude/agents/einja/codex-agent.md +117 -0
- package/presets/default/.claude/agents/einja/specs/spec-requirements-generator.md +15 -6
- package/presets/default/.claude/hooks/einja/playwright-resize.sh +12 -2
- package/presets/default/.claude/settings.json +15 -0
- package/presets/default/.claude/skills/einja-backend-architecture/SKILL.md +4 -0
- package/presets/default/.claude/skills/einja-output-format/SKILL.md +21 -0
- package/presets/default/.claude/skills/einja-spec-context-loader/SKILL.md +1 -1
- package/scaffolds/.mcp.json +6 -9
- package/scaffolds/example/specs/issues/issue999-example-task/qa-tests/scenarios.md +4 -4
- package/scaffolds/example/specs/issues/issue999-example-task/requirements.md +131 -100
- package/scaffolds/example/specs/issues/issue999-example-task/tasks.md +4 -3
- package/scaffolds/instructions/task-vibe-kanban-loop.md +38 -17
- package/scaffolds/instructions/vercel-cli-reference.md +451 -0
- package/scaffolds/steering/README.md +1 -0
- package/scaffolds/steering/acceptance-criteria-and-qa-guide.md +13 -1
- package/scaffolds/steering/development/backend-architecture.md +2 -1
- package/scaffolds/steering/development/database-guidelines.md +239 -0
- package/scaffolds/steering/development/frontend-development.md +80 -5
- package/scaffolds/steering/development/review-guidelines.md +5 -0
- package/scaffolds/steering/development-workflow.md +15 -1
- package/scaffolds/steering/infrastructure/deployment.md +27 -21
- package/scaffolds/steering/task-management.md +21 -0
- package/scaffolds/templates/README.md +11 -7
- package/scaffolds/templates/requirements.md.template +44 -32
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
<!-- @einja:managed:start -->
|
|
2
|
+
# データベース設計ガイドライン
|
|
3
|
+
|
|
4
|
+
## 概要
|
|
5
|
+
|
|
6
|
+
このドキュメントでは、PostgreSQLを使用したデータベース設計のベストプラクティスとPrismaスキーマの実装ガイドラインを説明します。
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 目次
|
|
11
|
+
|
|
12
|
+
1. [PostgreSQL日付型の使い分け](#1-postgresql日付型の使い分け)
|
|
13
|
+
2. [PrismaのDateTimeとPostgreSQL型のマッピング](#2-prismaのdatetimeとpostgresql型のマッピング)
|
|
14
|
+
3. [推奨Prismaテンプレート](#3-推奨prismaテンプレート)
|
|
15
|
+
4. [timestamp(タイムゾーンなし)を避ける理由](#4-timestampタイムゾーンなしを避ける理由)
|
|
16
|
+
5. [既存スキーマとの整合性に関する注意](#5-既存スキーマとの整合性に関する注意)
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 1. PostgreSQL日付型の使い分け
|
|
21
|
+
|
|
22
|
+
### 用途別の型選択表
|
|
23
|
+
|
|
24
|
+
| PostgreSQL型 | 用途例 | 保存される情報 |
|
|
25
|
+
|-------------|-------|--------------|
|
|
26
|
+
| `date` | 誕生日、締日、予約日(日付のみ) | 日付のみ(例: `2025-01-15`) |
|
|
27
|
+
| `timestamptz`(**推奨**) | created_at、updated_at、ログ、イベント日時 | タイムスタンプ + タイムゾーン |
|
|
28
|
+
| `time` / `timetz` | 営業時間、定期実行時刻 | 時刻のみ |
|
|
29
|
+
| `timestamp`(**非推奨**) | 使用禁止 | タイムゾーンなしタイムスタンプ |
|
|
30
|
+
|
|
31
|
+
### 選択基準
|
|
32
|
+
|
|
33
|
+
- **日付のみが重要な場合**: `date`
|
|
34
|
+
- 例: ユーザーの誕生日、契約締日
|
|
35
|
+
- **日時が重要で、タイムゾーンを考慮する必要がある場合**: `timestamptz`(推奨)
|
|
36
|
+
- 例: ログ、イベント発生日時、created_at/updated_at
|
|
37
|
+
- **時刻のみが重要な場合**: `time` / `timetz`
|
|
38
|
+
- 例: 店舗の営業時間、定期バッチ実行時刻
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 2. PrismaのDateTimeとPostgreSQL型のマッピング
|
|
43
|
+
|
|
44
|
+
### 型マッピング表
|
|
45
|
+
|
|
46
|
+
| Prisma定義 | PostgreSQL型 | 推奨度 |
|
|
47
|
+
|-----------|-------------|-------|
|
|
48
|
+
| `DateTime`(デフォルト) | `timestamp(3)` タイムゾーンなし | ❌ 非推奨 |
|
|
49
|
+
| `DateTime @db.Timestamptz` | `timestamptz` | ✅ 推奨 |
|
|
50
|
+
| `DateTime @db.Date` | `date` | ✅ 推奨(日付のみの場合) |
|
|
51
|
+
| `DateTime @db.Time` | `time` | ✅ 推奨(時刻のみの場合) |
|
|
52
|
+
|
|
53
|
+
### 重要な注意点
|
|
54
|
+
|
|
55
|
+
- **Prismaの `DateTime` 型のデフォルトは `timestamp(3)`**(タイムゾーンなし)です
|
|
56
|
+
- **必ず `@db.Timestamptz` を明示的に指定する**ことで、タイムゾーン対応になります
|
|
57
|
+
- 既存のスキーマで `@db.Timestamptz` が省略されている場合、タイムゾーンなしで動作しています
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## 3. 推奨Prismaテンプレート
|
|
62
|
+
|
|
63
|
+
### 基本パターン
|
|
64
|
+
|
|
65
|
+
```prisma
|
|
66
|
+
model User {
|
|
67
|
+
id String @id @default(cuid())
|
|
68
|
+
email String @unique
|
|
69
|
+
name String
|
|
70
|
+
|
|
71
|
+
// 日時(タイムゾーン付き)- 推奨
|
|
72
|
+
createdAt DateTime @default(now()) @db.Timestamptz
|
|
73
|
+
updatedAt DateTime @updatedAt @db.Timestamptz
|
|
74
|
+
|
|
75
|
+
// 日付のみ
|
|
76
|
+
birthDate DateTime @db.Date
|
|
77
|
+
|
|
78
|
+
// 時刻のみ(必要に応じて)
|
|
79
|
+
preferredTime DateTime? @db.Time
|
|
80
|
+
|
|
81
|
+
@@map("users")
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### ログテーブルのパターン
|
|
86
|
+
|
|
87
|
+
```prisma
|
|
88
|
+
model ActivityLog {
|
|
89
|
+
id String @id @default(cuid())
|
|
90
|
+
userId String
|
|
91
|
+
action String
|
|
92
|
+
metadata Json?
|
|
93
|
+
|
|
94
|
+
// ログはタイムゾーン付きで記録(必須)
|
|
95
|
+
occurredAt DateTime @default(now()) @db.Timestamptz
|
|
96
|
+
|
|
97
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
98
|
+
|
|
99
|
+
@@map("activity_logs")
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### イベント管理のパターン
|
|
104
|
+
|
|
105
|
+
```prisma
|
|
106
|
+
model Event {
|
|
107
|
+
id String @id @default(cuid())
|
|
108
|
+
title String
|
|
109
|
+
description String?
|
|
110
|
+
|
|
111
|
+
// イベント開始日時(タイムゾーン付き)
|
|
112
|
+
startAt DateTime @db.Timestamptz
|
|
113
|
+
endAt DateTime @db.Timestamptz
|
|
114
|
+
|
|
115
|
+
// 登録日時
|
|
116
|
+
createdAt DateTime @default(now()) @db.Timestamptz
|
|
117
|
+
updatedAt DateTime @updatedAt @db.Timestamptz
|
|
118
|
+
|
|
119
|
+
@@map("events")
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## 4. timestamp(タイムゾーンなし)を避ける理由
|
|
126
|
+
|
|
127
|
+
### 問題1: サーバーのタイムゾーン設定に依存
|
|
128
|
+
|
|
129
|
+
```sql
|
|
130
|
+
-- タイムゾーンなし(timestamp)の場合
|
|
131
|
+
INSERT INTO users (created_at) VALUES ('2025-01-15 10:00:00');
|
|
132
|
+
-- サーバーのTZ設定が Asia/Tokyo なら JST として解釈
|
|
133
|
+
-- サーバーのTZ設定が UTC なら UTC として解釈
|
|
134
|
+
-- 同じデータが環境によって異なる意味になる
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
```sql
|
|
138
|
+
-- タイムゾーン付き(timestamptz)の場合
|
|
139
|
+
INSERT INTO users (created_at) VALUES ('2025-01-15 10:00:00+09:00');
|
|
140
|
+
-- 常に UTC に変換して保存(内部的に 2025-01-15 01:00:00 UTC)
|
|
141
|
+
-- 取得時にクライアントのTZに変換して返却
|
|
142
|
+
-- 環境に依存せず一貫した動作
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### 問題2: マルチリージョン展開で不整合が発生
|
|
146
|
+
|
|
147
|
+
- **タイムゾーンなし**: 日本リージョンとUSリージョンで同じタイムスタンプが異なる意味になる
|
|
148
|
+
- **タイムゾーン付き**: すべてUTCで保存され、表示時のみ各リージョンのTZで変換される
|
|
149
|
+
|
|
150
|
+
### 問題3: サマータイム(DST)の扱いが曖昧
|
|
151
|
+
|
|
152
|
+
- **タイムゾーンなし**: サマータイム切り替え時に同じ時刻が2回存在する可能性(曖昧性)
|
|
153
|
+
- **タイムゾーン付き**: UTCで保存されるため曖昧性がない
|
|
154
|
+
|
|
155
|
+
### 結論
|
|
156
|
+
|
|
157
|
+
- **必ず `@db.Timestamptz` を使用する**
|
|
158
|
+
- タイムゾーンなし(`timestamp`)は使用禁止
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## 5. 既存スキーマとの整合性に関する注意
|
|
163
|
+
|
|
164
|
+
### 既存カラムの変更はスコープ外
|
|
165
|
+
|
|
166
|
+
このガイドラインは**新規カラム追加時に適用**します。
|
|
167
|
+
|
|
168
|
+
- **既存の `createdAt` / `updatedAt` カラムが `@db.Timestamptz` なしで定義されている場合**:
|
|
169
|
+
- 既存カラムの変更は別タスクで実施(マイグレーションリスクあり)
|
|
170
|
+
- 新規追加カラムのみ `@db.Timestamptz` を使用する
|
|
171
|
+
|
|
172
|
+
### 移行手順(既存カラムを変更する場合)
|
|
173
|
+
|
|
174
|
+
既存の `timestamp(3)` を `timestamptz` に変更する場合の手順:
|
|
175
|
+
|
|
176
|
+
```prisma
|
|
177
|
+
// Before
|
|
178
|
+
model User {
|
|
179
|
+
createdAt DateTime @default(now())
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// After
|
|
183
|
+
model User {
|
|
184
|
+
createdAt DateTime @default(now()) @db.Timestamptz
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**マイグレーション実行**:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
pnpm prisma migrate dev --name change_timestamp_to_timestamptz
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**注意**: 既存データは自動的にタイムゾーン付きに変換されます(PostgreSQLが現在のタイムゾーン設定でUTCに変換)。
|
|
195
|
+
|
|
196
|
+
### 新規テーブル作成時
|
|
197
|
+
|
|
198
|
+
新規テーブルを作成する場合は、**必ず `@db.Timestamptz` を使用**してください。
|
|
199
|
+
|
|
200
|
+
```prisma
|
|
201
|
+
model NewFeature {
|
|
202
|
+
id String @id @default(cuid())
|
|
203
|
+
name String
|
|
204
|
+
|
|
205
|
+
// 必ず @db.Timestamptz を明示
|
|
206
|
+
createdAt DateTime @default(now()) @db.Timestamptz
|
|
207
|
+
updatedAt DateTime @updatedAt @db.Timestamptz
|
|
208
|
+
|
|
209
|
+
@@map("new_features")
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## まとめ
|
|
216
|
+
|
|
217
|
+
### チェックリスト
|
|
218
|
+
|
|
219
|
+
新規カラム追加時の確認事項:
|
|
220
|
+
|
|
221
|
+
- [ ] 日時カラムは `@db.Timestamptz` を使用しているか
|
|
222
|
+
- [ ] 日付のみのカラムは `@db.Date` を使用しているか
|
|
223
|
+
- [ ] タイムゾーンなし(`timestamp`)を使用していないか
|
|
224
|
+
- [ ] ログやイベント日時は必ず `timestamptz` を使用しているか
|
|
225
|
+
|
|
226
|
+
### 参考資料
|
|
227
|
+
|
|
228
|
+
- [PostgreSQL 公式ドキュメント - Date/Time Types](https://www.postgresql.org/docs/current/datatype-datetime.html)
|
|
229
|
+
- [Prisma 公式ドキュメント - PostgreSQL connector](https://www.prisma.io/docs/orm/reference/prisma-schema-reference#postgresql)
|
|
230
|
+
<!-- @einja:managed:end -->
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
<!-- @einja:seed:start id="database-guidelines-project" -->
|
|
235
|
+
## プロジェクト固有の設定
|
|
236
|
+
|
|
237
|
+
<!-- このセクションはプロジェクト固有の内容を追記する場所です -->
|
|
238
|
+
<!-- einja syncで上書きされません -->
|
|
239
|
+
<!-- @einja:seed:end -->
|
|
@@ -30,10 +30,11 @@ Tanstack Query、React Hook Form、Hono Clientを活用した型安全で保守
|
|
|
30
30
|
5. [Tanstack Query(サーバー状態管理)](#5-tanstack-queryサーバー状態管理)
|
|
31
31
|
6. [React Hook Form(フォーム処理)](#6-react-hook-formフォーム処理)
|
|
32
32
|
7. [コンポーネント設計](#7-コンポーネント設計)
|
|
33
|
-
8. [
|
|
34
|
-
9. [
|
|
35
|
-
10. [
|
|
36
|
-
11. [
|
|
33
|
+
8. [Layering / z-index ガイドライン](#8-layering--z-index-ガイドライン)
|
|
34
|
+
9. [App Router構成](#9-app-router構成)
|
|
35
|
+
10. [状態管理戦略](#10-状態管理戦略)
|
|
36
|
+
11. [エラーハンドリング](#11-エラーハンドリング)
|
|
37
|
+
12. [実装例](#12-実装例)
|
|
37
38
|
|
|
38
39
|
---
|
|
39
40
|
|
|
@@ -1189,7 +1190,81 @@ export function useDeletePost() {
|
|
|
1189
1190
|
|
|
1190
1191
|
---
|
|
1191
1192
|
|
|
1192
|
-
## 8.
|
|
1193
|
+
## 8. Layering / z-index ガイドライン
|
|
1194
|
+
|
|
1195
|
+
UIコンポーネントの重なり順序を一貫して管理するため、z-indexトークンを使用します。
|
|
1196
|
+
|
|
1197
|
+
### z-indexトークン管理
|
|
1198
|
+
|
|
1199
|
+
プロジェクト全体でz-indexの値をCSS変数(デザイントークン)として一元管理しています。ハードコードされたz-index値(`z-10`, `z-50`等)は使用せず、必ずトークンを使用してください。
|
|
1200
|
+
|
|
1201
|
+
#### トークン定義場所
|
|
1202
|
+
|
|
1203
|
+
- **Admin**: `packages/admin-ui/src/styles/tokens.css`
|
|
1204
|
+
- **Web**: `apps/web/src/app/globals.css`
|
|
1205
|
+
|
|
1206
|
+
#### トークン階層
|
|
1207
|
+
|
|
1208
|
+
| 値 | トークン | 用途 |
|
|
1209
|
+
|----|---------|------|
|
|
1210
|
+
| 0 | `--z-base` | ベースレイヤー |
|
|
1211
|
+
| 10 | `--z-sticky` | sticky要素(テーブルカラム、セクションヘッダー) |
|
|
1212
|
+
| 10 | `--z-sidebar` | サイドバー本体 |
|
|
1213
|
+
| 20 | `--z-sidebar-rail` | サイドバーリサイズハンドル |
|
|
1214
|
+
| 30 | `--z-mobile-panel` | モバイルスライドインパネル |
|
|
1215
|
+
| 40 | `--z-header` | 固定ヘッダー |
|
|
1216
|
+
| 50 | `--z-dropdown` | ドロップダウン / ポップオーバー(Popover, Tooltip, Select, DropdownMenu) |
|
|
1217
|
+
| 59 | `--z-drawer-overlay` | ドロワーオーバーレイ |
|
|
1218
|
+
| 60 | `--z-drawer` | ドロワー本体(Drawer/Sheet Content) |
|
|
1219
|
+
| 69 | `--z-dialog-overlay` | ダイアログオーバーレイ |
|
|
1220
|
+
| 70 | `--z-dialog` | ダイアログ本体(Dialog Content) |
|
|
1221
|
+
| 79 | `--z-alert-dialog-overlay` | アラートダイアログオーバーレイ |
|
|
1222
|
+
| 80 | `--z-alert-dialog` | アラートダイアログ本体(AlertDialog Content) |
|
|
1223
|
+
| 90 | `--z-toast` | トースト通知 |
|
|
1224
|
+
| 100 | `--z-tooltip` | ツールチップ |
|
|
1225
|
+
|
|
1226
|
+
#### 使用方法
|
|
1227
|
+
|
|
1228
|
+
Tailwind CSSの任意値記法でCSS変数を参照します:
|
|
1229
|
+
|
|
1230
|
+
```tsx
|
|
1231
|
+
// ✅ 正しい: トークンを使用
|
|
1232
|
+
<div className="z-[var(--z-header)]">ヘッダー</div>
|
|
1233
|
+
<div className="z-[var(--z-dialog)]">ダイアログ</div>
|
|
1234
|
+
|
|
1235
|
+
// ❌ 禁止: ハードコード値
|
|
1236
|
+
<div className="z-10">...</div>
|
|
1237
|
+
<div className="z-50">...</div>
|
|
1238
|
+
```
|
|
1239
|
+
|
|
1240
|
+
#### 新しいトークンの追加
|
|
1241
|
+
|
|
1242
|
+
新しいz-index値が必要な場合は、以下の手順で追加してください:
|
|
1243
|
+
|
|
1244
|
+
1. 既存の階層を確認し、適切な値を決定する
|
|
1245
|
+
2. **両方**のトークン定義ファイルに追加する(Admin用・Web用)
|
|
1246
|
+
3. このドキュメントの階層表を更新する
|
|
1247
|
+
|
|
1248
|
+
### 優先順位
|
|
1249
|
+
|
|
1250
|
+
**Tooltip > Toast > AlertDialog > Dialog > Drawer > Dropdown > Header > Mobile Panel > Sidebar Rail > Sidebar/Sticky**
|
|
1251
|
+
|
|
1252
|
+
より重要な(ユーザーの注意を引く必要がある)要素ほど高いz-index値を持ちます。
|
|
1253
|
+
|
|
1254
|
+
### 使用ルール
|
|
1255
|
+
|
|
1256
|
+
1. **数値直書き禁止**: `z-50`等の直書きは禁止。必ずトークン参照を使用
|
|
1257
|
+
|
|
1258
|
+
2. **Overlay < Content**: 同一コンポーネント内でOverlayはContentより1段下
|
|
1259
|
+
- Dialog: Overlay(69) < Content(70)
|
|
1260
|
+
- Drawer: Overlay(59) < Content(60)
|
|
1261
|
+
- AlertDialog: Overlay(79) < Content(80)
|
|
1262
|
+
|
|
1263
|
+
3. **時間依存制御禁止**: `setTimeout`等でのレイヤー制御は禁止
|
|
1264
|
+
|
|
1265
|
+
---
|
|
1266
|
+
|
|
1267
|
+
## 9. App Router構成
|
|
1193
1268
|
|
|
1194
1269
|
### ルートグループ
|
|
1195
1270
|
|
|
@@ -53,6 +53,11 @@
|
|
|
53
53
|
- [ ] **パッケージエクスポート**
|
|
54
54
|
- index.ts不使用(直接ファイルパス指定)
|
|
55
55
|
- 絶対パスインポート(`@repo/server-core/...`)
|
|
56
|
+
- [ ] **日付型の適切な使用**
|
|
57
|
+
- 新規DateTimeカラムに`@db.Timestamptz`が付与されているか
|
|
58
|
+
- 日付のみのカラムに`@db.Date`が使用されているか
|
|
59
|
+
- タイムゾーンなし`timestamp`を使用していないか
|
|
60
|
+
- 詳細: [データベースガイドライン](database-guidelines.md)
|
|
56
61
|
|
|
57
62
|
---
|
|
58
63
|
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
│ pnpm task:loop <issue-number> │
|
|
66
66
|
│ │ │
|
|
67
67
|
│ ├── 初期化: Issue取得、ブランチ作成、Vibe-Kanban接続 │
|
|
68
|
+
│ │ ├── Phase毎に親Issue作成(MCP create_issue) │
|
|
68
69
|
│ │ │
|
|
69
70
|
│ └── ループ開始 ─────────────────────────────────────────┐ │
|
|
70
71
|
│ │ │ │
|
|
@@ -75,7 +76,7 @@
|
|
|
75
76
|
│ │ │ │
|
|
76
77
|
│ ▼ │ │
|
|
77
78
|
│ ┌─────────────────────────────────────────────────────┐ │ │
|
|
78
|
-
│ │
|
|
79
|
+
│ │ サブIssue作成(親Issue配下) → start_workspace_session│ │ │
|
|
79
80
|
│ │ (Claude Codeが自動起動されて実装開始) │ │ │
|
|
80
81
|
│ └─────────────────────────────────────────────────────┘ │ │
|
|
81
82
|
│ │ │ │
|
|
@@ -111,6 +112,11 @@
|
|
|
111
112
|
│ ▼ │
|
|
112
113
|
│ task:loopがDone検知 → GitHub Issueチェックボックス更新 │
|
|
113
114
|
│ │ │
|
|
115
|
+
│ Phase全サブIssue完了? │
|
|
116
|
+
│ ├─ Yes → 親Issue Workspace作成 → PR作成・マージ │
|
|
117
|
+
│ │ → 親Issue自動Done │
|
|
118
|
+
│ └─ No → スキップ │
|
|
119
|
+
│ │ │
|
|
114
120
|
│ └──────────────────────────────────────────────────┘ │
|
|
115
121
|
│ 次のタスクグループを自動開始 │
|
|
116
122
|
│ │
|
|
@@ -187,6 +193,8 @@ pnpm task:loop 123 --branch develop # develop ブランチベースで実
|
|
|
187
193
|
|
|
188
194
|
実行後、specで作成されたタスクが着手可能なものから自動で実行開始されます。
|
|
189
195
|
|
|
196
|
+
Phase毎に親Issueが自動作成され、タスクグループはサブIssueとして管理されます。
|
|
197
|
+
|
|
190
198
|
1. **Vibe-Kanbanの画面を眺める** - タスクの進捗を確認
|
|
191
199
|
2. **In Reviewになったら自己レビュー** - 実装内容を確認
|
|
192
200
|
3. **OKなら「Create PR」ボタンをクリック** - PRが自動作成される
|
|
@@ -234,6 +242,12 @@ task-executer → task-reviewer → task-qa → In Review
|
|
|
234
242
|
│ ↓ │
|
|
235
243
|
│ GitHub Issue: チェックボックス更新(自動) │
|
|
236
244
|
│ ↓ │
|
|
245
|
+
│ Phase 全サブIssue完了? │
|
|
246
|
+
│ ├─ Yes → 親Issue Workspace作成 │
|
|
247
|
+
│ │ → Phase→Issue PR作成・マージ │
|
|
248
|
+
│ │ → 親Issue自動Done(タイムアウト2分) │
|
|
249
|
+
│ └─ No → スキップ │
|
|
250
|
+
│ ↓ │
|
|
237
251
|
│ 次のタスクが自動開始 │
|
|
238
252
|
└─────────────────────────────────────────────────────────────┘
|
|
239
253
|
```
|
|
@@ -176,9 +176,12 @@ flowchart TB
|
|
|
176
176
|
|
|
177
177
|
subgraph "ci/action.yml"
|
|
178
178
|
C1[setup action 呼び出し] --> C2[pnpm generate]
|
|
179
|
-
C2 -->
|
|
179
|
+
C2 --> C2B{database-url?}
|
|
180
|
+
C2B -->|あり| C2C[db:migrate:deploy]
|
|
181
|
+
C2B -->|なし| C3
|
|
182
|
+
C2C --> C3[pnpm typecheck]
|
|
180
183
|
C3 --> C4[pnpm lint]
|
|
181
|
-
C4 --> C5[pnpm test]
|
|
184
|
+
C4 --> C5[pnpm test<br/>DATABASE_URL]
|
|
182
185
|
end
|
|
183
186
|
|
|
184
187
|
subgraph "migrate/action.yml"
|
|
@@ -197,7 +200,7 @@ flowchart TB
|
|
|
197
200
|
| Action | ファイル | 内容 | 呼び出し元 |
|
|
198
201
|
|--------|---------|------|-----------|
|
|
199
202
|
| **Setup** | `actions/setup/action.yml` | pnpm + Node.js + install | ci action, migrate action, cleanup |
|
|
200
|
-
| **CI** | `actions/ci/action.yml` | setup → generate → typecheck → lint → test | deploy-stable-branches, deploy-pr-preview |
|
|
203
|
+
| **CI** | `actions/ci/action.yml` | setup → generate → [migrate] → typecheck → lint → test | deploy-stable-branches, deploy-pr-preview |
|
|
201
204
|
| **Migrate** | `actions/migrate/action.yml` | setup → generate → migrate → seed (optional) | deploy-stable-branches |
|
|
202
205
|
| **Neon Export Env** | `actions/neon-export-env/action.yml` | .env.previewからNeon環境変数をエクスポート | deploy-pr-preview, cleanup-pr-preview-on-close |
|
|
203
206
|
|
|
@@ -231,30 +234,31 @@ sequenceDiagram
|
|
|
231
234
|
GH->>Actions: deploy-pr-preview トリガー
|
|
232
235
|
|
|
233
236
|
rect rgb(240, 248, 255)
|
|
234
|
-
Note over Actions,CI: CI Checks
|
|
235
|
-
Actions->>CI: ci action 呼び出し
|
|
237
|
+
Note over Actions,CI: CI Checks(PostgreSQLサービスコンテナ付き)
|
|
238
|
+
Actions->>CI: ci action 呼び出し (database-url付き)
|
|
236
239
|
CI->>CI: setup (pnpm + Node.js)
|
|
237
240
|
CI->>CI: pnpm generate
|
|
241
|
+
CI->>CI: db:migrate:deploy (テスト用DB)
|
|
238
242
|
CI->>CI: pnpm typecheck
|
|
239
243
|
CI->>CI: pnpm lint
|
|
240
|
-
CI->>CI: pnpm test
|
|
244
|
+
CI->>CI: pnpm test (DATABASE_URL付き)
|
|
241
245
|
CI-->>Actions: CI完了
|
|
242
246
|
end
|
|
243
247
|
|
|
244
248
|
rect rgb(255, 248, 240)
|
|
245
|
-
Note over Actions,Neon: Neon Branch
|
|
249
|
+
Note over Actions,Neon: Neon Branch 作成(connection_uri API方式)
|
|
246
250
|
Actions->>Actions: dotenvx で NEON_API_KEY 取得
|
|
247
251
|
Actions->>Actions: pnpm generate (Prisma Client生成)
|
|
248
252
|
Actions->>Neon: preview/pr-{番号} ブランチ作成
|
|
249
|
-
Neon-->>Actions: DB URL (
|
|
250
|
-
Actions->>Neon: pnpm db:push (スキーマ同期)
|
|
253
|
+
Neon-->>Actions: DB URL (connection_uri APIから取得)
|
|
254
|
+
Actions->>Neon: pnpm db:push --accept-data-loss (スキーマ同期)
|
|
251
255
|
Actions->>Neon: pnpm db:seed (データ投入)
|
|
252
256
|
end
|
|
253
257
|
|
|
254
258
|
rect rgb(240, 255, 240)
|
|
255
259
|
Note over Actions,Vercel: Vercel デプロイ
|
|
256
260
|
Actions->>Vercel: vercel pull
|
|
257
|
-
Actions->>Vercel: 環境変数同期 (
|
|
261
|
+
Actions->>Vercel: 環境変数同期 (encrypted-only)
|
|
258
262
|
Actions->>Vercel: vercel build (DATABASE_URL=pooled)
|
|
259
263
|
Actions->>Vercel: vercel deploy --prebuilt
|
|
260
264
|
Vercel-->>Actions: Preview URL
|
|
@@ -279,20 +283,21 @@ sequenceDiagram
|
|
|
279
283
|
GH->>Actions: deploy-stable-branches トリガー
|
|
280
284
|
|
|
281
285
|
rect rgb(240, 248, 255)
|
|
282
|
-
Note over Actions,CI: CI Checks
|
|
283
|
-
Actions->>CI: ci action 呼び出し
|
|
286
|
+
Note over Actions,CI: CI Checks(PostgreSQLサービスコンテナ付き)
|
|
287
|
+
Actions->>CI: ci action 呼び出し (database-url付き)
|
|
284
288
|
CI->>CI: setup (pnpm + Node.js)
|
|
285
289
|
CI->>CI: pnpm generate
|
|
290
|
+
CI->>CI: db:migrate:deploy (テスト用DB)
|
|
286
291
|
CI->>CI: pnpm typecheck
|
|
287
292
|
CI->>CI: pnpm lint
|
|
288
|
-
CI->>CI: pnpm test
|
|
293
|
+
CI->>CI: pnpm test (DATABASE_URL付き)
|
|
289
294
|
CI-->>Actions: CI完了
|
|
290
295
|
end
|
|
291
296
|
|
|
292
297
|
Actions->>Actions: ブランチ判定 (環境変数セット)
|
|
293
298
|
|
|
294
299
|
rect rgb(255, 248, 240)
|
|
295
|
-
Note over Actions,Neon: DB マイグレーション (main/staging
|
|
300
|
+
Note over Actions,Neon: DB マイグレーション (main/stagingのみ・if分岐方式)
|
|
296
301
|
Actions->>Neon: pnpm db:migrate:deploy
|
|
297
302
|
end
|
|
298
303
|
|
|
@@ -303,7 +308,7 @@ sequenceDiagram
|
|
|
303
308
|
rect rgb(240, 255, 240)
|
|
304
309
|
Note over Actions,Vercel: Vercel デプロイ
|
|
305
310
|
Actions->>Vercel: vercel pull
|
|
306
|
-
Actions->>Vercel: 環境変数同期 (
|
|
311
|
+
Actions->>Vercel: 環境変数同期 (encrypted-only)
|
|
307
312
|
Actions->>Vercel: vercel pull (Re-pull: 同期後の最新化)
|
|
308
313
|
Actions->>Vercel: vercel build [--prod]
|
|
309
314
|
Actions->>Vercel: vercel deploy --prebuilt [--prod]
|
|
@@ -521,14 +526,14 @@ flowchart TD
|
|
|
521
526
|
|
|
522
527
|
### Vercel環境変数の自動同期
|
|
523
528
|
|
|
524
|
-
ワークフローは
|
|
529
|
+
ワークフローは **encrypted-only方式** で同期対象を制御:
|
|
525
530
|
|
|
526
|
-
| ワークフロー |
|
|
527
|
-
|
|
528
|
-
| PR Preview |
|
|
529
|
-
| Stable Branches |
|
|
531
|
+
| ワークフロー | 同期対象 | 除外 | 説明 |
|
|
532
|
+
|------------|---------|------|------|
|
|
533
|
+
| PR Preview | `.env.preview` 内の `encrypted:` キー | `NEON_*`, `DATABASE_*` | dotenvxで管理しているもの = Vercelに同期すべきもの |
|
|
534
|
+
| Stable Branches | `.env.{env}` 内の `encrypted:` キー | なし | dotenvxで管理している全キーを同期 |
|
|
530
535
|
|
|
531
|
-
**設計意図**:
|
|
536
|
+
**設計意図**: dotenvxの暗号化ファイル内の `encrypted:` を含む行のキー名のみを対象とし、「dotenvxで管理 = Vercelに同期」の意図を明確にする。ブラックリスト方式(全env走査)ではシステム変数混入や新変数追加時の漏れリスクがあるため廃止。
|
|
532
537
|
|
|
533
538
|
---
|
|
534
539
|
|
|
@@ -574,6 +579,7 @@ flowchart TD
|
|
|
574
579
|
| タスク | キャッシュ | 理由 |
|
|
575
580
|
|--------|----------|------|
|
|
576
581
|
| build | ✅ | ビルド成果物を再利用 |
|
|
582
|
+
| generate | ✅ | `src/__generated__/**` をキャッシュ(outputs定義) |
|
|
577
583
|
| lint | ✅ | ソースコード未変更時はスキップ |
|
|
578
584
|
| typecheck | ✅ | 型定義未変更時はスキップ |
|
|
579
585
|
| test | ✅ | テストコード・対象未変更時はスキップ |
|
|
@@ -455,6 +455,26 @@ server-coreパッケージが動作し、DBに接続できること(AC1.1を
|
|
|
455
455
|
design.md「Server Core構築」セクション
|
|
456
456
|
```
|
|
457
457
|
|
|
458
|
+
### 親Issue/サブIssue階層(task:loop使用時)
|
|
459
|
+
|
|
460
|
+
`pnpm task:loop` 使用時は、Vibe-Kanban上でPhase→親Issue、タスクグループ→サブIssueの階層構造で管理されます。
|
|
461
|
+
|
|
462
|
+
**親Issueタイトル形式**:
|
|
463
|
+
```
|
|
464
|
+
[Issue{N} Phase{M}] {Phase名}
|
|
465
|
+
```
|
|
466
|
+
例: `[Issue17 Phase1] 基盤構築`
|
|
467
|
+
|
|
468
|
+
**サブIssueタイトル形式**:
|
|
469
|
+
```
|
|
470
|
+
[Issue{N} {X.Y}] {タスクグループ名}
|
|
471
|
+
```
|
|
472
|
+
例: `[Issue17 1.1] Server Core構築とDB設定`
|
|
473
|
+
|
|
474
|
+
**親子関係の設定**: サブIssue作成後、REST API(PATCH `/api/remote/issues/{id}`)で `parent_issue_id` を設定します。
|
|
475
|
+
|
|
476
|
+
**注意**: `/einja:task-exec` による単発実行時はこの階層構造は使用されません。`pnpm task:loop` 使用時のみ適用されます。
|
|
477
|
+
|
|
458
478
|
## コマンドリファレンス
|
|
459
479
|
|
|
460
480
|
### タスク管理関連コマンド
|
|
@@ -483,6 +503,7 @@ pnpm task:loop <issue番号> --branch <ブランチ> # ベースブランチ指
|
|
|
483
503
|
```
|
|
484
504
|
- 着手可能なタスクグループを並列でVibe-Kanbanに登録
|
|
485
505
|
- Done状態を監視して次のタスクを自動開始
|
|
506
|
+
- Phase毎に親Issueを作成し、タスクグループをサブIssueとして管理(詳細は「親Issue/サブIssue階層」を参照)
|
|
486
507
|
- **前提**: `npx @einja/cli init` 実行済み、Claude Code インストール済み
|
|
487
508
|
|
|
488
509
|
**仕様書からドキュメント更新**:
|
|
@@ -31,16 +31,20 @@
|
|
|
31
31
|
受け入れ基準は以下の形式で記載してください:
|
|
32
32
|
|
|
33
33
|
```markdown
|
|
34
|
-
- [ ]
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
- [ ] **AC1.1**: [振る舞いの1文要約]
|
|
35
|
+
- Given: [前提条件]
|
|
36
|
+
- When: [実行する操作]
|
|
37
|
+
- Then: [期待される結果]
|
|
38
|
+
- 検証レベル: [Unit / Integration / E2E / Browser]
|
|
37
39
|
```
|
|
38
40
|
|
|
39
41
|
**良い例**:
|
|
40
42
|
```markdown
|
|
41
|
-
- [ ]
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
- [ ] **AC1.1**: 有効なメールアドレスで送信すると、成功メッセージが表示されメールが送信される
|
|
44
|
+
- Given: ログインページにアクセスした
|
|
45
|
+
- When: 有効なメールアドレスを入力して送信
|
|
46
|
+
- Then: 成功メッセージが表示され、メールが送信される
|
|
47
|
+
- 検証レベル: Integration
|
|
44
48
|
```
|
|
45
49
|
|
|
46
50
|
**悪い例**:
|
|
@@ -76,7 +80,7 @@
|
|
|
76
80
|
**重要なセクション**:
|
|
77
81
|
- **受け入れ基準(Acceptance Criteria)**: QAエージェント(task-qa)がこのセクションを参照してテストシナリオを作成します
|
|
78
82
|
- **AC番号体系**: AC1.1, AC1.2 のように、ストーリー番号.連番 で一意に識別
|
|
79
|
-
- **検証レベル**: Unit/Integration/E2E を必ず指定
|
|
83
|
+
- **検証レベル**: Unit/Integration/E2E/Browser を必ず指定
|
|
80
84
|
- **検証者**: task-executer または task-qa を明記
|
|
81
85
|
|
|
82
86
|
**使い方**:
|