はじめに
ソースリポジトリ: kamae-scala
Kamae(構え)— 備えの姿勢。
Kamae Scalaは、サーバーサイドのScala 3ドメインコードを型で守り、レビューしやすくするための設計スタンスとガイド集である。kamae-rs や kamae-ts と同じ思想を、Scala 3のイディオム(opaque types、sealed traits、Either、エフェクト型)に落とし込んでいる。
すべてのリファレンスを通読する必要はない。今のタスクに関係するトピックだけを開けばよい。各リファレンス末尾の レビュー観点 に、そのトピックのコードレビューで確認すべき項目がある。
何を目指すか
Section titled “何を目指すか”Kamaeが守りたいのは、次のような失敗である。
- 文字列や数値のまま混在するドメイン概念
statusフィールドとオプショナル列で表せてしまう無効な状態throwや.get/.headに頼る想定内の失敗処理- API JSONやDB行をそのままドメイン型として使う境界の曖昧さ
- ログ・メトリクス・エラーへのPII漏洩
- 状態変更とドメインイベントの非アトミックな永続化
Scala 3では、opaque types、value class、sealed trait / enum、検証付き apply / from ファクトリ、Either[DomainError, T] といった型機能で、実用的な範囲でこれらをコンパイル時または構築時に弾く。
- 意味を型で表す — opaque types、sealed traits、
enum、検証付きコンストラクタでドメイン概念をモデル化する。 - 無効な遷移を型で封じる — ソース状態ごとに遷移メソッドや型を分け、網羅的な
matchで分岐を閉じる。 Eitherで失敗を明示する — ドメイン固有のエラー ADTとともにEither[DomainError, T]を使い、ドメインコードではthrow、???、unsafe.getを避ける。- 境界で一度パースする — 外部データはDTO / 行ケースクラスに入れてから検証付き変換でドメイン型へ変換する。
- ユースケースは小さく配線する — ポート(trait)経由で依存を受け取り、アダプタはコンポジションルートで注入する。
- 集約の変更はトランザクション内に — 実用的な範囲で、ユースケースごとに集約の変更を1つのトランザクション境界に収める。
- PII とシークレットは内側に — マスキング用ラッパーの内側に置き、観測経路ではデフォルトでマスクする。
- JNI / ネイティブは境界に閉じる — ドメインロジックからは排除し、必要なら文書化された不変条件を持つ小さな安全APIの背後に隠す。
- 品質ゲートを揃える — scalafmt・scalafix・テスト・Scaladocをクリーンに保ち、CIをレビュー前提と一致させる。
これらは強い既定であり、絶対ではない。既存のプロジェクト慣習と矛盾する場合は慣習に従い、ドメイン安全性に影響する逸脱は短い説明を残す。
前提となるツールチェーン
Section titled “前提となるツールチェーン”新規プロジェクトの既定は次のとおり。既存コードベースでは、まずリポジトリの慣習を確認する。
- Scala 3.3+(
ThisBuild / scalaVersion) - sbt 1.10+(
project/build.properties) - Java 17以上(LTS)
- フォーマットは scalafmt、lintは scalafix(プロジェクトで採用している場合)
状況別の読み方
Section titled “状況別の読み方”新規ドメインを設計するとき
Section titled “新規ドメインを設計するとき”既存コードベースへ段階的に導入するとき
Section titled “既存コードベースへ段階的に導入するとき”オブザーバビリティと PII だけ見るとき
Section titled “オブザーバビリティと PII だけ見るとき”- PII 保護
- ロギングとメトリクス
- テストのアサーションは テストデータ
インフラ・開発環境の整備
Section titled “インフラ・開発環境の整備”| 関心 | リファレンス |
|---|---|
| ユースケース配線、DI | アプリケーション配線 |
| Cats Effect / ZIO の選び方 | エフェクトシステム |
| サービス間契約、HTTP / gRPC | サービス境界 |
| ストリーム、継続クエリ | ストリームと継続クエリ |
| マクロ、derive | ドメインマクロ |
| JNI、ネイティブ | JNI / ネイティブ境界 |
| テスト、フィクスチャ | テストデータ |
| プロパティベーステスト | プロパティベーステスト |
| フォーマット、lint、品質ゲート | 品質ゲート |
| 公開 API の Scaladoc | 公開 API のドキュメント |
| ローカル開発・ブートストラップ | 開発環境 |
| スキルリポジトリの開発 | スキルリポジトリの開発 |
| CI | CI セットアップ |
依存ライブラリ
Section titled “依存ライブラリ”プロジェクトの build.sbt に応じて、必要なときだけ ライブラリガイド を参照する。
| 用途 | ガイド付きライブラリ | 検出のみ(ローカル慣習の参考) |
|---|---|---|
| エフェクト | cats、zio | monix |
| シリアライズ | circe | play-json、json4s、upickle |
| 検証 / 単位 | refined | squants |
| PII / シークレット | secrets パターン | — |
| 永続化 | doobie | slick、quill、skunk |
| ストリーム | fs2 | pekko-stream、zio-streams |
| 設定 | pureconfig | — |
| テスト | scalacheck | munit、scalatest、weaver |
新しいリファレンスに全文スニペットをコピーせず、次の定義へリンクする。
| トピック | 正規リファレンス |
|---|---|
| ハッピーパスのユースケース | 状態遷移 — ユースケースを薄く保つ |
| 永続化エラーのマッピング | エラーハンドリング — Either による早期リターン |
| リポジトリポート | 永続化、集約、イベント — 責務でリポジトリを分離する |
| エンドツーエンドコード | タクシー配車の例 |
| 品質ゲートのコマンド | 品質ゲート — ベースラインコマンド |
リファレンス一覧
Section titled “リファレンス一覧”- アプリケーション配線
- 段階的導入
- ドメインモデリング
- 状態遷移
- エラーハンドリング
- 境界防御
- PII 保護
- ロギングとメトリクス
- JNI / ネイティブ境界
- 品質ゲート
- 公開 API のドキュメント
- CI セットアップ
- 開発環境
- スキルリポジトリの開発
- 永続化、集約、イベント
- ORM アダプター
- ストリームと継続クエリ
- ドメインマクロ
- エフェクトシステム
- サービス境界
- テストデータ
- プロパティベーステスト
タクシー配車の例 で、opaque ID、分離した状態型、型付き遷移、ドメインイベントの流れを一通り追える。