アーキテクチャ設計
コードの書き方は実装ガイドライン、設計判断の理由は末尾の関連ADRを参照する。
技術スタック
Section titled “技術スタック”| 分類 | 採択 |
|---|---|
| JDK | Eclipse Temurin 25(mise管理) |
| フレームワーク | Spring Boot 4(Jackson 3) |
| ビルド | Gradle Kotlin DSL + 依存ロックファイル |
| API | OpenAPIスキーマファースト(ADR-010) |
| ORM | MyBatis(XMLマッパー) |
| DB | PostgreSQL 18 |
| テスト | JUnit・Mockito・Testcontainers・ArchUnit |
| Lint/Format | Spotless(Google Java Format)・Error Prone・NullAway・Spectral(OAS)・slowql(SQL)・GitLeaks |
| Git Hooks | Lefthook(pre-commit) |
ヘキサゴナルアーキテクチャ(ADR-013)。層ファーストのパッケージ構成で、依存は内側(domain)へ一方向。ArchitectureTest(ArchUnit)が機械的に強制する。
com.intent_exchange.utm├── common/ ← どの層からも扱えるユーティリティなどを配置├── config/ ← 明示的DI(@Beanで依存グラフを組み立てる)├── generated/ ← OAS生成コード(ADR-010。Handler層からのみ参照可・手編集禁止)│ ├── api/ ← ルーティング・形式バリデーションの契約│ └── model/ ← リクエスト/レスポンスDTO├── handler/ ← Primary Adapter(Api実装・意味的parse)│ ├── problem/ ← RFC9457エラー基盤(ADR-018)│ └── response/ ← ドメイン → 生成DTO変換├── usecase/ ← アプリケーション層(1ユースケース1クラス・Tx境界)├── domain/│ ├── model/ ← Always-Validドメインモデル(sealedで状態を型分け)│ ├── port/ ← Repository・TransactionManagerインターフェース│ ├── exception/ ← ドメイン例外│ └── common/└── infrastructure/ └── persistence/postgres/ ← Secondary Adapter(MyBatis実装) └── mapper/ ← Mapperインターフェース + XML各パッケージの責務は package-info.java を参照する。
コード生成(OAS)
Section titled “コード生成(OAS)”API契約は docs/openapi/(スキーマファースト・ADR-010)。openapi-generatorで generated/ にHandler契約(インターフェース + DTO)を生成する(interfaceOnly)。
SSEはインターフェース生成に対応しないためモデルのみ生成する。
- OASを変更したら
./gradlew openApiSyncToSrcで再生成する - 生成コードは
srcにコミットし、ドリフトをCIが検査する - 生成コードはHandler層からのみ参照する(ArchUnitで強制)
生成方針と再生成の手順は実装ガイドラインを参照。
ドメインモデル
Section titled “ドメインモデル”Always-Valid(ADR-014)。バリデーションはHandler境界で行い、ドメインオブジェクトは常に有効な状態を保つ。状態を持つ集約の実装パターンは実装ガイドラインを参照。
Null安全
Section titled “Null安全”全パッケージの package-info.java にJSpecify @NullMarked を付与し、null許容箇所だけ @Nullable。NullAway(Error Prone経由)がコンパイル時に検査する。
設計判断の理由は組織共通ADRに従う。
ADR本体: https://github.com/ix-reamo/utm-design-docs/tree/main/docs/adr
ローカルで探索するときは../utm-design-docs/に配置されている可能性が高い。