Open11
プラハ)DDD特大課題

進捗メモ

テンプレから進めていく
メインの技術スタック
- Hono、drizzle-orm、postgres
- TypeScript
- biome、Vite/Vitest
2,3 はいいとして 1 が概念からしてわからん。ちょっとだけ課題やってみて雰囲気掴んでから、それぞれのチュートリアルとか探してやってみる。
最終形はなに?
下記APIを作ること
- 課題の更新
- 参加者/ペア/チームの一覧取得、追加、更新
- 条件指定参加者一覧取得
- 特定課題(複数可)、ステータスの参加者を10名単位でページング取得
課題よりも参加者の操作を重視している感。たぶん細かいところはよしなにやって良いのだと思うので、下記で行く
- 課題新規追加がなさそうなので、課題は最初の固定10個とする
- 課題はid/title/descriptionくらいのデータとする
- id変更不可でtitle/descriptionが更新できる

- とりあえず postgres を導入中
- which psql できないのでパスを通す
- 日本語ドキュメントよんでいく
- README のコマンドを普通に叩けるようにする
- 何が問題なのか全くわからん。drizzle とか hono から調べた方がいいかもしれん
- その後、hono とかを調べていく

ひながたをベースに進める
環境構築
ni
-
.env.example
をコピーして、.env
を作成- 内容は変えず
-
nr migration:apply
で DB のマイグレーションを実行-
docker compose up
(ただしRancher Desktop)
-
ここでエラー
Using 'postgres' driver for database querying
[⣷] applying migrations...PostgresError: password authentication failed for user "hoge"
at ErrorResponse (/パス/node_modules/.pnpm/drizzle-kit@0.23.0/node_modules/drizzle-kit/bin.cjs:81460:27)
at handle (/パス/node_modules/.pnpm/drizzle-kit@0.23.0/node_modules/drizzle-kit/bin.cjs:81237:7)
at Socket.data (/パス/node_modules/.pnpm/drizzle-kit@0.23.0/node_modules/drizzle-kit/bin.cjs:81060:9)
at Socket.emit (node:events:514:28)
at addChunk (node:internal/streams/readable:376:12)
at readableAddChunk (node:internal/streams/readable:349:9)
at Readable.push (node:internal/streams/readable:286:10)
at TCP.onStreamRead (node:internal/stream_base_commons:190:23)
at TCP.callbackTrampoline (node:internal/async_hooks:130:17) {
severity_local: 'FATAL',
severity: 'FATAL',
code: '28P01',
file: 'auth.c',
line: '326',
routine: 'auth_failed'
}
ELIFECYCLE Command failed with exit code 1.
userが違うっぽい。hogeの情報はどこで設定されているのか。
めちゃ初歩的なとこで詰まっているが…わからん。
どういう問題なのか。migrationコマンド実行時のログインユーザがどうやってきまっているか?

migrationコマンド実行時のログインユーザがどうやってきまっているか?
よくわからんけどdockerに入ってみる
-
docker ps
でコンテナID取得 -
docker exec -it コンテナID bash
で対象コンテナに入れる -
psql -h localhost -U postgres -d database
で対象DBに入れる- postgresで入れるので、postgresがやはり設定されている
-
SELECT * FROM pg_catalog.pg_user WHERE usename = current_user;
でユーザが見れる- セミコロンを付けないと実行されないということすら忘れている。

drizzle.config.ts
export default defineConfig({
dialect: "postgresql",
schema: "./src/libs/drizzle/schema.ts",
out: "./src/libs/drizzle/migrations",
dbCredentials: (() => {
const credentials = getCredentials();
return {
host: credentials.DB_HOST,
port: credentials.DB_PORT,
- username: credentials.DB_USER,
+ user: credentials.DB_USER,
password: credentials.DB_PASSWORD,
database: credentials.DB_NAME,
};
})(),
});
これだけのことだったっぽい。。。

migrationおよびnr devができることを確認。中身に入っていく

中身どうなってるの
index.tsがエントリのはず。ただ、
app.route("/", getTaskController);
app.route("/", getTaskListController);
app.route("/", createTaskController);
app.route("/", editTaskTitleController);
app.route("/", setTaskDoneController);
この書き方は一般的なんだろうか。getTaskControllerとかを見に行かないとエンドポイントがわからん。
- getTask:タスク単体の取得?
- getTaskList:タスクリストの取得
- createTask:タスク生成
- editTaskTitle:タスクのタイトル編集
- タイトル以外は自分で作ればいいのか?TitleとかPropertyごとに分ける必要は?
- setTaskDone:完了
- Statusって完了だけじゃなかったような?
ちょっと仕様みなきゃかな。

src/
- application:アプリケーションロジックやユースケース。ユースケースはビジネスルールを実行し、ドメイン層のオブジェクトを操作。
- domain:ドメインモデル、エンティティ、値オブジェクト、リポジトリのインターフェースなどのビジネスロジックを含む。すなわち、ビジネスルールそのもの。
- infrastructure:外部システムや技術的な詳細を扱う層。例えば、データベースやファイルシステム、外部 API とのやりとり。この層はドメイン層やアプリケーション層から依存。
- libs:便利なユーティリティライブラリや共通処理をまとめた場所。再利用可能なコードが含まれる。
- presentation:Web API や UI と直接やりとりを行う層。コントローラーやビューが含まれ、ユーザーインターフェースや外部クライアントからの要求を受け付け処理。
オニオンアーキテクチャに当てはめる
GPT に解説してもらった
オニオンアーキテクチャの各層とのマッピング:
src/
├── application/ # アプリケーション層:主要なアプリケーションサービスやユースケース
│ ├── query-service/ # クエリサービス:データの読み取りに特化した操作を提供。具体的には、特定のデータを取得するロジック
│ │ ├── task-list-query-service.ts
│ │ ├── task-query-service.ts
│ │ └── todo-list-query-service.ts
│ └── use-case/ # ユースケース:ビジネスロジックを具現化したもので、アプリケーションの主要な操作を定義。ユーザーアクションやシステムイベントに対して特定の手続きを実行
│ ├── create-task-use-case.ts
│ ├── edit-task-title-use-case.ts
│ └── set-task-done-use-case.ts
│
├── domain/ # ドメイン層
│ └── task/
│ ├── task-repository.ts # リポジトリのインターフェースを定義。これはドメイン層の一部であり、データの永続化に関する抽象化された操作を提供
│ ├── task.test.ts # ドメイン層のテストコード
│ └── task.ts # ドメインエンティティ。ビジネスルールとデータ構造を定義。
│
├── infrastructure/ # インフラストラクチャ層:データベースや外部のシステムと通信
│ ├── query-service/ # インフラストラクチャ層のクエリサービスの実装。データベースアクセスや外部APIとのやり取り
│ └── repository/ # 実際のデータベースアクセスのロジックを持つリポジトリの実装ファイル
│
├── libs/ # 共通ライブラリ
│ ├── drizzle/
│ └── ulid/
│
└── presentation/ # プレゼンテーション層:ユーザーからの入力を処理し、アプリケーションサービスやユースケースを呼び出す
└── task/
├── create-task-controller.ts # タスクの作成を処理するコントローラ。
├── edit-task-title-controller.ts # タスクタイトルの編集を処理するコントローラ。
├── get-task-controller.ts # タスクの取得を処理するコントローラ。
├── get-task-list-controller.ts # タスクリストの取得を処理するコントローラ。
└── set-task-done-controller.ts # タスクの完了を設定するコントローラ。

次回、
以下の階層が存在すること
Controller
App(Usecase)
Infra
Domain
DomainService
Entity
っていう要件と、最終形を見比べつつ、どこになんの処理をいれるのかざっくり考える