@k2works/claude-code-booster 0.1.3 → 0.2.0
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 +14 -0
- package/bin/claude-code-booster +24 -4
- package/lib/assets/.claude/README.md +44 -40
- package/lib/assets/.claude/commands/analysis.md +230 -0
- package/lib/assets/.claude/commands/kill.md +109 -0
- package/lib/assets/.claude/commands/next.md +136 -0
- package/lib/assets/.claude/commands/plan.md +141 -91
- package/lib/assets/.claude/commands/progress.md +172 -0
- package/lib/assets/docs/reference/UI/350/250/255/350/250/210/343/202/254/343/202/244/343/203/211.md +446 -0
- package/lib/assets/docs/reference//343/202/242/343/203/274/343/202/255/343/203/206/343/202/257/343/203/201/343/203/243/350/250/255/350/250/210/343/202/254/343/202/244/343/203/211.md +1428 -0
- package/lib/assets/docs/reference//343/202/244/343/203/263/343/203/225/343/203/251/350/250/255/350/250/210/343/202/254/343/202/244/343/203/211.md +1879 -0
- package/lib/assets/docs/reference//343/203/206/343/202/271/343/203/210/346/210/246/347/225/245/343/202/254/343/202/244/343/203/211.md +1310 -0
- package/lib/assets/docs/reference//343/203/207/343/203/274/343/202/277/343/203/242/343/203/207/343/203/253/350/250/255/350/250/210/343/202/254/343/202/244/343/203/211.md +312 -0
- package/lib/assets/docs/reference//343/203/211/343/203/241/343/202/244/343/203/263/343/203/242/343/203/207/343/203/253/350/250/255/350/250/210/343/202/254/343/202/244/343/203/211.md +600 -0
- package/lib/assets/docs/reference//343/203/246/343/203/274/343/202/271/343/202/261/343/203/274/343/202/271/344/275/234/346/210/220/343/202/254/343/202/244/343/203/211.md +672 -0
- package/lib/assets/docs/reference//343/203/252/343/203/252/343/203/274/343/202/271/343/203/273/343/202/244/343/203/206/343/203/254/343/203/274/343/202/267/343/203/247/343/203/263/350/250/210/347/224/273/343/202/254/343/202/244/343/203/211.md +524 -0
- package/lib/assets/docs/reference//351/201/213/347/224/250/350/246/201/344/273/266/345/256/232/347/276/251/343/202/254/343/202/244/343/203/211.md +393 -0
- package/lib/assets/docs/reference//351/226/213/347/231/272/343/202/254/343/202/244/343/203/211.md +18 -173
- package/lib/assets/docs/reference//351/235/236/346/251/237/350/203/275/350/246/201/344/273/266/345/256/232/347/276/251/343/202/254/343/202/244/343/203/211.md +1231 -0
- package/lib/assets/docs/template//345/256/214/345/205/250/345/275/242/345/274/217/343/201/256/343/203/246/343/203/274/343/202/271/343/202/261/343/203/274/343/202/271.md +64 -0
- package/lib/assets/docs/template//350/246/201/344/273/266/345/256/232/347/276/251.md +467 -443
- package/package.json +1 -1
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
# データモデル設計ガイド
|
|
2
|
+
|
|
3
|
+
## はじめに
|
|
4
|
+
|
|
5
|
+
データベース設計は、アプリケーションの基盤となる重要な活動です。このガイドでは、テスト駆動開発(TDD)の原則をデータベース設計に応用し、要求の変化に柔軟に対応できる堅牢なデータモデルを段階的に構築する方法論を説明します。
|
|
6
|
+
|
|
7
|
+
従来の「最初に完璧なER図を描く」アプローチではなく、小さな要求から始めて徐々にデータモデルを育てていく実践的なアプローチを推奨します。
|
|
8
|
+
|
|
9
|
+
## TDDデータベース設計の基本原則
|
|
10
|
+
|
|
11
|
+
### なぜTDDでデータベース設計?
|
|
12
|
+
|
|
13
|
+
1. **要求が明確になる**: テストという形で、その時点で必要なデータ要求を具体的に定義します
|
|
14
|
+
2. **設計がシンプルに保たれる**: 今必要なことだけを実装するため、過剰な設計を防ぎます
|
|
15
|
+
3. **変更に強くなる**: テストが既存の要求を守るため、安心してリファクタリング(設計改善)を行えます
|
|
16
|
+
|
|
17
|
+
### TDDサイクル
|
|
18
|
+
|
|
19
|
+
```plantuml
|
|
20
|
+
@startuml
|
|
21
|
+
start
|
|
22
|
+
:要求の定義;
|
|
23
|
+
:レッド (Red)\n失敗するテストを書く;
|
|
24
|
+
:グリーン (Green)\n最小限のスキーマで\nテストを通す;
|
|
25
|
+
:リファクタリング (Refactor)\nER図で設計を可視化・改善;
|
|
26
|
+
if (新しい要求?) then (yes)
|
|
27
|
+
else (no)
|
|
28
|
+
:完了;
|
|
29
|
+
stop
|
|
30
|
+
endif
|
|
31
|
+
@enduml
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## 設計プロセス
|
|
35
|
+
|
|
36
|
+
### 1. レッド(Red):要求をテストコードで表現
|
|
37
|
+
|
|
38
|
+
まず、「どのようなデータを、どのように扱いたいか」を具体的なテストコードで示します。
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
describe("部門マスタ", () => {
|
|
42
|
+
test("部門を登録できる", async () => {
|
|
43
|
+
// 1. テストデータを作成
|
|
44
|
+
await prisma.department.create({ data: departments[0] });
|
|
45
|
+
// 2. 取得したデータが期待通りか検証
|
|
46
|
+
const result = await prisma.department.findMany();
|
|
47
|
+
expect(result).toEqual(departments);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test("部門を更新できる", async () => {
|
|
51
|
+
const expected = { ...departments[0], name: "更新部署" };
|
|
52
|
+
await prisma.department.update({
|
|
53
|
+
where: { deptCode_startDate: {
|
|
54
|
+
deptCode: departments[0].deptCode,
|
|
55
|
+
startDate: departments[0].startDate
|
|
56
|
+
}},
|
|
57
|
+
data: { name: "更新部署" },
|
|
58
|
+
});
|
|
59
|
+
const result = await prisma.department.findUnique({
|
|
60
|
+
where: { deptCode_startDate: {
|
|
61
|
+
deptCode: departments[0].deptCode,
|
|
62
|
+
startDate: departments[0].startDate
|
|
63
|
+
}}
|
|
64
|
+
});
|
|
65
|
+
expect(result).toEqual(expected);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 2. グリーン(Green):最小限のスキーマ定義
|
|
71
|
+
|
|
72
|
+
テストをパスさせるための最小限のスキーマを定義します。
|
|
73
|
+
|
|
74
|
+
```prisma
|
|
75
|
+
model Department {
|
|
76
|
+
deptCode String @map("部門コード") @db.VarChar(6)
|
|
77
|
+
startDate DateTime @default(dbgenerated("CURRENT_DATE")) @map("開始日") @db.Timestamp(6)
|
|
78
|
+
endDate DateTime? @default(dbgenerated("'2100-12-31 00:00:00'::timestamp without time zone")) @map("終了日") @db.Timestamp(6)
|
|
79
|
+
name String? @map("部門名") @db.VarChar(40)
|
|
80
|
+
layer Int @default(0) @map("組織階層")
|
|
81
|
+
psth String @map("部門パス") @db.VarChar(100)
|
|
82
|
+
lowestType Int @default(0) @map("最下層区分")
|
|
83
|
+
slitYn Int @default(1) @map("伝票入力可否")
|
|
84
|
+
createDate DateTime @default(dbgenerated("CURRENT_DATE")) @map("作成日時") @db.Timestamp(6)
|
|
85
|
+
creator String? @map("作成者名") @db.VarChar(12)
|
|
86
|
+
updateDate DateTime @default(dbgenerated("CURRENT_DATE")) @map("更新日時") @db.Timestamp(6)
|
|
87
|
+
updater String? @map("更新者名") @db.VarChar(12)
|
|
88
|
+
|
|
89
|
+
// 履歴管理のため、部門コードと適用開始日で複合主キー
|
|
90
|
+
@@id([deptCode, startDate], map: "pk_department")
|
|
91
|
+
@@map("部門マスタ")
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### 3. リファクタリング(Refactor):ER図で設計を可視化・改善
|
|
96
|
+
|
|
97
|
+
テストがパスした状態で、設計をER図で可視化し、必要に応じて改善します。
|
|
98
|
+
|
|
99
|
+
```plantuml
|
|
100
|
+
@startuml
|
|
101
|
+
entity "部門マスタ (Department)" as Department {
|
|
102
|
+
* **deptCode**: VARCHAR(6) <<PK>>
|
|
103
|
+
* **startDate**: TIMESTAMP <<PK>>
|
|
104
|
+
--
|
|
105
|
+
name: VARCHAR(40)
|
|
106
|
+
layer: INTEGER
|
|
107
|
+
psth: VARCHAR(100)
|
|
108
|
+
lowestType: INTEGER
|
|
109
|
+
...
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
entity "社員マスタ (Employee)" as Employee {
|
|
113
|
+
* **empCode**: VARCHAR(10) <<PK>>
|
|
114
|
+
--
|
|
115
|
+
name: VARCHAR(20)
|
|
116
|
+
deptCode: VARCHAR(6) <<FK>>
|
|
117
|
+
startDate: TIMESTAMP
|
|
118
|
+
...
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
Department "1" -- "0..*" Employee : 所属する
|
|
122
|
+
@enduml
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## 設計パターンとベストプラクティス
|
|
126
|
+
|
|
127
|
+
### 1. マスタデータの設計
|
|
128
|
+
|
|
129
|
+
#### 履歴管理
|
|
130
|
+
- 組織変更などで同じコードでも期間が異なるデータを管理する場合は複合主キーを使用
|
|
131
|
+
- `{コード, 開始日}`の組み合わせを主キーとする
|
|
132
|
+
|
|
133
|
+
#### 命名規則
|
|
134
|
+
- テーブル名:業務上の意味を表す日本語名
|
|
135
|
+
- カラム名:英語名(データベースレベル)と日本語名(アプリケーションレベル)の対応
|
|
136
|
+
|
|
137
|
+
### 2. トランザクションデータの設計
|
|
138
|
+
|
|
139
|
+
#### ヘッダ・明細パターン
|
|
140
|
+
一回の取引に複数の項目が含まれる場合、ヘッダテーブルと明細テーブルに分離します。
|
|
141
|
+
|
|
142
|
+
```prisma
|
|
143
|
+
model Order {
|
|
144
|
+
orderNo String @id @map("受注番号") @db.VarChar(10)
|
|
145
|
+
orderDate DateTime @default(dbgenerated("CURRENT_DATE")) @map("受注日")
|
|
146
|
+
custCode String @map("顧客コード") @db.VarChar(8)
|
|
147
|
+
orderDetails OrderDetail[]
|
|
148
|
+
@@map("受注データ")
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
model OrderDetail {
|
|
152
|
+
orderNo String @map("受注番号") @db.VarChar(10)
|
|
153
|
+
soRowNo Int @map("受注行番号")
|
|
154
|
+
prodCode String @map("商品コード") @db.VarChar(16)
|
|
155
|
+
quantity Int @default(1) @map("受注数量")
|
|
156
|
+
order Order @relation(fields: [orderNo], references: [orderNo])
|
|
157
|
+
|
|
158
|
+
@@id([orderNo, soRowNo])
|
|
159
|
+
@@map("受注データ明細")
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### 3. リレーションシップの設計
|
|
164
|
+
|
|
165
|
+
#### パーティモデル
|
|
166
|
+
取引先のように複数の役割を持つエンティティは、共通部分(Party)と役割特化部分(Role)に分離します。
|
|
167
|
+
|
|
168
|
+
```prisma
|
|
169
|
+
// 共通情報
|
|
170
|
+
model Company {
|
|
171
|
+
compCode String @id @map("取引先コード") @db.VarChar(8)
|
|
172
|
+
name String @map("取引先名") @db.VarChar(40)
|
|
173
|
+
customers Customer[]
|
|
174
|
+
suppliers Supplier[]
|
|
175
|
+
@@map("取引先マスタ")
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// 顧客としての役割情報
|
|
179
|
+
model Customer {
|
|
180
|
+
custCode String @map("顧客コード") @db.VarChar(8)
|
|
181
|
+
custSubNo Int @map("顧客枝番")
|
|
182
|
+
arCode String @map("請求先コード") @db.VarChar(8)
|
|
183
|
+
company Company @relation(fields: [custCode], references: [compCode])
|
|
184
|
+
@@id([custCode, custSubNo])
|
|
185
|
+
@@map("顧客マスタ")
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// 仕入先としての役割情報
|
|
189
|
+
model Supplier {
|
|
190
|
+
supCode String @map("仕入先コード") @db.VarChar(8)
|
|
191
|
+
supSubNo Int @map("仕入先枝番")
|
|
192
|
+
company Company @relation(fields: [supCode], references: [compCode])
|
|
193
|
+
@@id([supCode, supSubNo])
|
|
194
|
+
@@map("仕入先マスタ")
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## テスト戦略
|
|
199
|
+
|
|
200
|
+
### 1. マスタデータのテスト
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
describe("マスタデータ", () => {
|
|
204
|
+
beforeAll(async () => {
|
|
205
|
+
// テスト前にデータをクリア
|
|
206
|
+
await prisma.department.deleteMany();
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
test("CRUD操作が正常に動作する", async () => {
|
|
210
|
+
// Create
|
|
211
|
+
await prisma.department.create({ data: testData });
|
|
212
|
+
|
|
213
|
+
// Read
|
|
214
|
+
const result = await prisma.department.findMany();
|
|
215
|
+
expect(result).toEqual([testData]);
|
|
216
|
+
|
|
217
|
+
// Update
|
|
218
|
+
await prisma.department.update({
|
|
219
|
+
where: { id: testData.id },
|
|
220
|
+
data: { name: "更新後の名前" }
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// Delete
|
|
224
|
+
await prisma.department.delete({ where: { id: testData.id } });
|
|
225
|
+
const empty = await prisma.department.findMany();
|
|
226
|
+
expect(empty).toEqual([]);
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### 2. 関連データのテスト
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
describe("関連データ", () => {
|
|
235
|
+
test("関連するデータを一括で取得できる", async () => {
|
|
236
|
+
// 関連するマスタを先に登録
|
|
237
|
+
await prisma.$transaction(async (prisma) => {
|
|
238
|
+
await prisma.department.createMany({ data: departments });
|
|
239
|
+
await prisma.employee.createMany({ data: employees });
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
// 関連データを含めて取得
|
|
243
|
+
const result = await prisma.department.findMany({
|
|
244
|
+
include: { employees: true }
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
expect(result[0].employees).toHaveLength(expectedEmployeeCount);
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## 段階的な発展プロセス
|
|
253
|
+
|
|
254
|
+
### フェーズ1:基本マスタ
|
|
255
|
+
1. 部門・社員
|
|
256
|
+
2. 商品・商品分類
|
|
257
|
+
3. 取引先(Company, Customer, Supplier)
|
|
258
|
+
|
|
259
|
+
### フェーズ2:基本トランザクション
|
|
260
|
+
1. 受注・受注明細
|
|
261
|
+
2. 売上・売上明細
|
|
262
|
+
|
|
263
|
+
### フェーズ3:調達プロセス
|
|
264
|
+
1. 発注・発注明細
|
|
265
|
+
2. 仕入・仕入明細
|
|
266
|
+
3. 在庫管理
|
|
267
|
+
|
|
268
|
+
### フェーズ4:財務プロセス
|
|
269
|
+
1. 請求・請求明細
|
|
270
|
+
2. 入金管理
|
|
271
|
+
3. 支払管理
|
|
272
|
+
|
|
273
|
+
### フェーズ5:補助機能
|
|
274
|
+
1. 与信管理
|
|
275
|
+
2. 自動採番
|
|
276
|
+
3. その他運用支援機能
|
|
277
|
+
|
|
278
|
+
## 共通設計原則
|
|
279
|
+
|
|
280
|
+
### 1. 監査証跡の設計
|
|
281
|
+
|
|
282
|
+
すべてのテーブルに以下のカラムを含めます:
|
|
283
|
+
|
|
284
|
+
```prisma
|
|
285
|
+
createDate DateTime @default(dbgenerated("CURRENT_DATE")) @map("作成日時") @db.Timestamp(6)
|
|
286
|
+
creator String? @map("作成者名") @db.VarChar(12)
|
|
287
|
+
updateDate DateTime @default(dbgenerated("CURRENT_DATE")) @map("更新日時") @db.Timestamp(6)
|
|
288
|
+
updater String? @map("更新者名") @db.VarChar(12)
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### 2. 論理削除vs物理削除
|
|
292
|
+
|
|
293
|
+
- マスタデータ:論理削除(削除フラグ)
|
|
294
|
+
- トランザクションデータ:物理削除または履歴保持
|
|
295
|
+
|
|
296
|
+
### 3. パフォーマンス考慮
|
|
297
|
+
|
|
298
|
+
- 検索頻度の高いカラムにはインデックスを設定
|
|
299
|
+
- 大量データが予想されるテーブルは分割を検討
|
|
300
|
+
- 集計用のサマリテーブルを必要に応じて作成
|
|
301
|
+
|
|
302
|
+
## まとめ
|
|
303
|
+
|
|
304
|
+
TDDアプローチによるデータベース設計では:
|
|
305
|
+
|
|
306
|
+
1. **小さく始める**: 完璧な初期設計を目指さず、最小限の要求から開始
|
|
307
|
+
2. **テストファースト**: 要求をテストコードで明確に定義
|
|
308
|
+
3. **段階的改善**: テストに守られながら継続的にスキーマを改善
|
|
309
|
+
4. **可視化**: ER図で設計の全体像を把握
|
|
310
|
+
5. **一貫性**: 命名規則や設計パターンを統一
|
|
311
|
+
|
|
312
|
+
このアプローチにより、変化する要求に柔軟に対応しながら、保守性の高いデータベース設計を実現できます。
|