タスク・決済・マッチングに関するフィールドレベルの設計決定を記録する。
1. タスクの位置情報
| 項目 | 決定内容 |
|---|
| 方式 | location_text (NOT NULL) + lat / lng (nullable) |
| 根拠 | フリーランス新法で実施場所の明示が義務付けられている |
location_text — 実施場所をフリーテキストで保持。NOT NULL にすることで法令準拠を強制する
lat / lng — 位置ベースマッチング用。任意入力のため nullable
- 入力 UI は郵便番号入力 → フリーテキスト補完の想定
未決事項
workers テーブル側の位置情報カラムも同じ方針(location_text NOT NULL + lat/lng nullable)で揃えるか
2. payment_due_days の制約
| 項目 | 決定内容 |
|---|
| 方式 | DB CHECK 制約 + サーバー側バリデーションの二重チェック |
| 上限 | 60日以内(フリーランス新法の支払期限) |
- DB 層:
CHECK (payment_due_days <= 60) でデータ整合性を保証
- サーバー層: アプリケーションバリデーションで同じ制約を適用し、意味のあるエラーメッセージを返す
- クライアント層: サーバーからのエラーメッセージを受けて表示するだけ(クライアント側に独自バリデーションは持たない)
3. マッチングの粒度
| 項目 | 決定内容 |
|---|
| 方式 | 1タスク : N人オファー(最初の受諾者が勝ち) |
| テーブル | matches で 1:N を許容する設計 |
- 1つのタスクに対して複数の受注候補者にオファーを出せる
- 最初に受諾した者がマッチ成立(先着方式)
将来の拡張
- オークション形式など、マッチング形式を選択できるようにする
- タスク投稿時にマッチング形式(先着 / オークション / 指名)を指定する想定
4. 代理受領型の payments 設計
| 項目 | 決定内容 |
|---|
| 決済フロー | collected_at → paid_out_at の2段階 |
| 支払期限 | タスク完了日から60日以内 |
| 手数料 | platform_fee カラムを明示的に保持 |
collected_at — 依頼者から代金を回収した日時
paid_out_at — 受注者へ報酬を振り込んだ日時
due_date — タスク完了日 + 60日以内で算出
platform_fee — 集計・分析用に明示的にカラムとして保持する
5. 追加テーブル: イベントストア方式
| 項目 | 決定内容 |
|---|
| 方式 | 単一のイベントテーブルに各種イベントを格納 |
| 目的 | 改ざん防止・紛争対応・監査証跡 |
以下の要件を1つのイベントテーブルでカバーする:
| 用途 | 説明 | MVPスコープ |
|---|
| 取引条件スナップショット | タスク作成・受諾時点の条件を不変レコードとして保存。紛争時の証拠 | ○ |
| notifications | タスクの状態変化に応じた通知イベント | ○ |
| reviews | タスク完了後の評価 | × (MVP後) |
インデックス設計方針
- イベント種別(
event_type)+ 対象エンティティ(entity_id)の複合インデックス
- 時系列クエリ用に
created_at のインデックス
- 紛争対応の検索用に
entity_type + entity_id + created_at の複合インデックス
参考ドキュメント