【第4回】ChatGPTで大規模システムは作れるか？（設計工程の振り返り）

# 経緯
この記事は以下の記事の続き。第4回です。
[第1回 全体計画～要件定義編](https://qiita.com/Programmer-cbl/items/480767f026ae8316b72d)
[第2回 アーキテクチャ設計～データベース設計編](https://qiita.com/Programmer-cbl/items/0fcf5d4b20408de6ef80)
[第3回 API設計～インフラ設計編](https://qiita.com/Programmer-cbl/items/0c5de54a93f8c5e07ba3)

こんなに長くなるつもりはなかったんですが一応続けます。
前回までで設計工程が終わった、ということになってはいるものの、成果物の整合性が合っていなかったり、詳細化が不十分と思われるものがあったりで、いきなり実装工程に入のではなく一旦ここまでの成果物を振り返って次の方針を考えていきます。

# 成果物まとめ

<details><summary>要件定義書</summary><div>

# 要件定義書

1. 概要
本システムは、個人または家族単位での家計管理を行うためのWebアプリケーションである。収入と支出を管理し、予算の設定や銀行口座との連携、グラフ表示など、家計管理に必要な機能を提供する。

2. 対象ユーザー
本システムは、個人または家族単位での家計管理を行いたい人を対象とする。

3. 機能要件
以下の機能が必要とされる。
  - 収支の管理機能（収入と支出）
  - カテゴリ別の支出管理機能
  - 家族全員が使用できる共有機能
  - 通知機能やリマインダー機能
  - 予算管理機能
  - 銀行連携機能
  - 簡単なグラフ表示機能

4. その他要件
以下の要件が必要とされる。

- ユーザー登録機能
- ログイン・ログアウト機能
- パスワードリセット機能
- セキュリティ対策（パスワードのハッシュ化、SSL通信）
- バックアップ機能
- スマートフォンからのアクセスに対応

5. 開発環境
以下の開発環境を利用する。

- フロントエンド：JavaScript、React
- バックエンド：Python、Flask
- データベース：PostgreSQL

6. 画面構成
以下の画面が必要とされる。

- ログイン画面
- ホーム画面（収支一覧、グラフ表示）
- 収支入力画面
- カテゴリ管理画面
- 予算設定画面
- 銀行口座連携画面
- アカウント設定画面

7. 開発スケジュール
以下のスケジュールで開発を進める。

- 要件定義：2023年3月-4月
- 詳細設計：2023年4月-5月
- 実装：2023年5月-7月
- テスト：2023年7月-8月
- リリース：2023年8月

</div></details>


<details><summary>データベース設計書</summary><div>

## データベース設計書

### データベース名

household_account_book

### テーブル一覧

- users
- incomes
- expenses
- categories
- budgets

以下にデータベース設計書を記載します。

### usersテーブル

|項目名|データ型|主キー|NOT NULL|備考|
|-|-|-|-|-|
|id|SERIAL|○|○|ユーザーID|
|email|VARCHAR(255)||○|ユーザーメールアドレス|
|password|VARCHAR(255)||○|ユーザーパスワード|



### incomesテーブル

|項目名|データ型|主キー|NOT NULL|備考|
|-|-|-|-|-|
|id|SERIAL|○|○|収入ID|
|user_id|INT||○|ユーザーID|
|date|DATE||○|収入日|
|amount|INT||○|収入金額|
|memo|VARCHAR(255)|||収入メモ|



### expensesテーブル

|項目名|データ型|主キー|NOT NULL|備考|
|-|-|-|-|-|
|id|SERIAL|○|○|支出ID|
|user_id|INT||○|ユーザーID|
|date|DATE||○|支出日|
|amount|INT||○|支出金額|
|memo|VARCHAR(255)|||支出メモ|
|category_id|INT||○|カテゴリID|



### categoriesテーブル

|項目名|データ型|主キー|NOT NULL|備考|
|-|-|-|-|-|
|id|SERIAL|○|○|カテゴリID|
|user_id|INT||○|ユーザーID|
|name|VARCHAR(255)||○|カテゴリ名|



### budgetsテーブル

|項目名|データ型|主キー|NOT NULL|備考|
|-|-|-|-|-|
|id|SERIAL|○|○|予算ID|
|user_id|INT||○|ユーザーID|
|category_id|INT||○|カテゴリID|
|year|INT||○|年|
|month|INT||○|月|
|amount|INT||○|予算金額|

### accountsテーブル

|項目名|データ型|主キー|NOT NULL|備考|
|-|-|-|-|-|
|id|SERIAL|○|○|口座ID|
|user_id|INT||○|ユーザーID|
|name|VARCHAR(255)||○|口座名|
|bank|VARCHAR(255)||○|口座を開設した金融機関名|
|branch|VARCHAR(255)||○|口座を開設した支店名|
|account_number|VARCHAR(255)||○|口座番号|
|account_type|VARCHAR(255)||○|口座種別|

</div></details>

<details><summary>画面一覧</summary><div>

## 画面一覧

|画面名|画面ID|機能概要|
|-|-|-|
|ログイン画面|LG_001|ユーザーのログインを行う|
|ホーム画面|HM_001|収支一覧やグラフ表示などの機能へのリンクを提供する|
|収支入力画面|IM_001|収支の入力を行う|
|カテゴリ管理画面|CT_001|カテゴリの登録・編集・削除を行う|
|予算設定画面|BG_001|予算の設定・編集を行う|
|銀行口座連携画面|BN_001|銀行口座との連携を行う|
|アカウント設定画面|AC_001|アカウント情報の設定・編集を行う|
|収支一覧画面|BL_001|登録された収支一覧を表示する|
|カテゴリ一覧画面|CT_002|登録されたカテゴリ一覧を表示する|
|グラフ表示画面|GP_001|登録された収支データをグラフ表示する|
|レポート表示画面|RP_001|収支データからレポートを生成し、表示する|
|通知設定画面|NT_001|通知の設定を行う|
|パスワード再設定画面|PS_001|パスワードの再設定を行う|

</div></details>

<details><summary>API一覧</summary><div>

## API一覧

|API名|エンドポイント|API-ID|利用するテーブル|
|-|-|-|-|
|ユーザー登録|POST /api/users|USR_001|users|
|ログイン|POST /api/login|USR_002|users|
|ログアウト|POST /api/logout|USR_003|-|
|パスワードリセット|POST /api/password-reset|USR_004|users|
|アカウント情報取得|GET /api/account|USR_005|users|
|アカウント情報更新|PUT /api/account|USR_006|users|
|収入一覧取得|GET /api/incomes|INC_001|incomes|
|収入登録|POST /api/incomes|INC_002|incomes|
|収入情報更新|PUT /api/incomes/:id|INC_003|incomes|
|収入情報削除|DELETE /api/incomes/:id|INC_004|incomes|
|支出一覧取得|GET /api/expenses|EXP_001|expenses|
|支出登録|POST /api/expenses|EXP_002|expenses|
|支出情報更新|PUT /api/expenses/:id|EXP_003|expenses|
|支出情報削除|DELETE /api/expenses/:id|EXP_004|expenses|
|カテゴリ一覧取得|GET /api/categories|CAT_001|categories|
|カテゴリ登録|POST /api/categories|CAT_002|categories|
|カテゴリ情報更新|PUT /api/categories/:id|CAT_003|categories|
|カテゴリ情報削除|DELETE /api/categories/:id|CAT_004|categories|
|予算一覧取得|GET /api/budgets|BUD_001|budgets|
|予算登録|POST /api/budgets|BUD_002|budgets|
|予算情報更新|PUT /api/budgets/:id|BUD_003|budgets|
|予算情報削除|DELETE /api/budgets/:id|BUD_004|budgets|
|通知設定取得|GET /api/notification-settings|NTF_001|notification_settings|
|通知設定更新|PUT /api/notification-settings|NTF_002|notification_settings|
|銀行口座情報取得|GET /api/bank-accounts|BKA_001|bank_accounts|
|銀行口座登録|POST /api/bank-accounts|BKA_002|bank_accounts|
|銀行口座情報更新|PUT /api/bank-accounts/:id|BKA_003|bank_accounts|
|銀行口座情報削除|DELETE /api/bank-accounts/:id|BKA_004|bank_accounts|

</div></details>

# 整合性チェック

ここまでの情報を再度読み込ませて、内容に不具合がないかをチェックしてもらいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301527/3c813f58-39b8-4993-de9e-71518fbb0420.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301527/68745bbe-f347-f573-b3c8-486ff56fafe5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301527/b23f63da-9921-797a-c107-5867955addfc.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301527/6e4d3ed6-6e47-1215-7711-94d822e2828c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301527/a9febe55-2bca-feb7-1fb0-033bee56b6d2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301527/5dc259c1-11ac-2e8b-d573-5c2c0b5cccb0.png)

一応矛盾なく作れている、という理解のようですが、本当かなぁ。。
次の章で人によるレビューを再現してみます。

## 人力レビュー
内容をよく見ると、要件定義書の「画面構成」というところに画面一覧的なものが載っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301527/bf9e32ab-f056-711f-806f-f18e6f905531.png)

これに対し、画面一覧では収支一覧～パスワード再設定画面までが増幅されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301527/343e0f64-36b1-5a11-4eab-77be539f61c8.png)

これに対して突っ込みを入れてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301527/3cc9f425-c0df-96d1-91e0-89295ffaa429.png)
めっちゃまともなこと言ってますね。。
現場でも確かにこういう分割はしますね。ダッシュボード的なところの重めのコンポーネントは別ページとしてカウントする的な話だと思います。
ここで試しに「グラフ表示画面」を削除して、概要設計書との整合性を再度聞いてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301527/226a744f-071b-2c04-0f2f-96a011298864.png)
↑これはこれでまともなんですが、、、ああ言えばこう言う感はありますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301527/227b1fb9-9d3d-c8df-26c9-304372506923.png)
↑どうやらChat-GPT自体は画面分けるべきという認識のようです。
というわけで、先ほどと同じように、再度「グラフ表示画面」を外した状態でチェックさせました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301527/c8372d16-d811-dd15-df0d-6c4243f88b6c.png)
↑一度あっさりとチェック通過してしまうのがとても怪しいですが、指摘には反応します。
指摘を理解できたようなので同件チェックをさせます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301527/604c06f8-85d5-0e6d-7cf8-d9f5d22f9d3d.png)
なんとなく理解してそうな雰囲気は出てますのでこの辺で終わりにします。

# まとめ

今回は Chat-GPT で設計工程の成果物レビューをしました。
モジュール分割の考え方などは一般的なことを語ることはできるようですが、「じゃぁその通りやって」と言ってもなかなかその通りにしてくれません。
わかってる風な受け答えはするものの最終成果物が変というのは、この辺はオフショア開発経験がある方は既視感あるやり取りなのではないでしょうか？
次回はようやく実装工程に入っていこうと思います。