Open11

プラハ)DDD特大課題

kzk4043kzk4043

進捗メモ

kzk4043kzk4043

テンプレから進めていく

メインの技術スタック

  1. Hono、drizzle-orm、postgres
  2. TypeScript
  3. biome、Vite/Vitest

2,3 はいいとして 1 が概念からしてわからん。ちょっとだけ課題やってみて雰囲気掴んでから、それぞれのチュートリアルとか探してやってみる。

最終形はなに?

下記APIを作ること

  • 課題の更新
  • 参加者/ペア/チームの一覧取得、追加、更新
  • 条件指定参加者一覧取得
    • 特定課題(複数可)、ステータスの参加者を10名単位でページング取得

課題よりも参加者の操作を重視している感。たぶん細かいところはよしなにやって良いのだと思うので、下記で行く

  • 課題新規追加がなさそうなので、課題は最初の固定10個とする
  • 課題はid/title/descriptionくらいのデータとする
  • id変更不可でtitle/descriptionが更新できる
kzk4043kzk4043
  • とりあえず postgres を導入中
  • README のコマンドを普通に叩けるようにする
    • 何が問題なのか全くわからん。drizzle とか hono から調べた方がいいかもしれん
  • その後、hono とかを調べていく
kzk4043kzk4043

一旦 hono とかの概念を軽く学習する

  • 次はここ
  • 次はここ
    • Docs にいっても良いかもしれん
    • これ →https://zenn.dev/link/comments/0e664bf0708320
    • 次回データの登録から

チュートリアルやったから、ddd-template を再度見てみるか
・立ち上げまでやってみる

kzk4043kzk4043

ひながたをベースに進める

環境構築

  • 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コマンド実行時のログインユーザがどうやってきまっているか?

kzk4043kzk4043

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;でユーザが見れる
    • セミコロンを付けないと実行されないということすら忘れている。
kzk4043kzk4043
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,
    };
  })(),
});

これだけのことだったっぽい。。。

kzk4043kzk4043

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

kzk4043kzk4043

中身どうなってるの

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って完了だけじゃなかったような?

ちょっと仕様みなきゃかな。

kzk4043kzk4043

src/

  1. application:アプリケーションロジックやユースケース。ユースケースはビジネスルールを実行し、ドメイン層のオブジェクトを操作。
  2. domain:ドメインモデル、エンティティ、値オブジェクト、リポジトリのインターフェースなどのビジネスロジックを含む。すなわち、ビジネスルールそのもの。
  3. infrastructure:外部システムや技術的な詳細を扱う層。例えば、データベースやファイルシステム、外部 API とのやりとり。この層はドメイン層やアプリケーション層から依存。
  4. libs:便利なユーティリティライブラリや共通処理をまとめた場所。再利用可能なコードが含まれる。
  5. 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    # タスクの完了を設定するコントローラ。
kzk4043kzk4043

次回、

以下の階層が存在すること
Controller
App(Usecase)
Infra
Domain
DomainService
Entity

っていう要件と、最終形を見比べつつ、どこになんの処理をいれるのかざっくり考える