Parent: #612
Depends on: #615
背景
現在の人物検出/cropはBase64画像を返す一時previewで、UIにも「保存されない」と明記されている。crop単位のCCIP抽出には安定したregion IDが必要だが、全検出結果や画像blobを無条件に保存すると容量・lifecycle・watcher処理が複雑になる。remote AI実行では transparent が転送されない既存不整合もある。
設計方針
- 検出結果はephemeralのまま維持する
- ユーザーが選択・保存したものだけ
media_regions へ登録する
- bbox、元画像寸法、label/score、detector/version、source revisionを正本とし、Base64/blobはDBへ保存しない
- 表示画像は元画像から生成し、region revision・source更新時刻・render/segmenter versionをkeyに派生cacheする
- 独立ファイルが必要な場合だけ明示的にmaterializeし、child mediaと
derivative relationを作る
スコープ
- regionの保存・一覧・更新・削除・render・materialize API/UI
- bbox範囲、元画像revision、削除cascade、cache invalidation
- remote crop呼び出しへの
transparent 転送修正
- domain/contract/OpenAPIとPostgreSQL/PGliteのテスト
非スコープ
- 検出結果の自動全件保存
- crop画像本体のDB保存
- crop CCIP embedding・類似検索
受け入れ条件
主な参照
apps/server/src/infrastructure/api/routers/ai-router.ts:100
apps/server/src/infrastructure/api/routers/ai-router.ts:111
packages/ui/src/character-crop-modal.tsx:72
packages/core/src/domain/tagging/schemas.ts:102
packages/db/src/schema.ts:678
評価反映(2026-07-18)
本節をregion永続化の最終仕様とする。本文にある「検出結果はephemeral」「選択したものだけ保存」「自動全件保存は非スコープ」および対応する旧受け入れ条件は、本節で置き換える。
永続化境界
登録済みmediaを対象とする処理では、検出済み・手動作成済みのregionを常にmedia_regionsへ保存する。保存するのは座標と再現用metadataであり、crop画像本体ではない。
- 検出APIは永続化済みregion IDを返す
- 再検出・再送で同じregionが無制限に増えないよう、media revision、detector/model version、検出結果を基にした決定的なidempotency規則を定義する
- 手動追加・bbox編集も保存対象とする
- 元画像revisionが変わったregionはcurrentとして黙って再利用せず、staleとして再検出・再確認の対象にする
- crop画像は必要時に元画像から生成し、materializeを明示した場合だけchild mediaとderivative relationを作る
一方、file inputなど登録済みmedia IDを持たないpreviewはFKの親がないためephemeralのままとする。保存操作を提供する場合は、先にmediaとしてimport/materializeしてからregionを関連付ける。
UI契約
現在の「データは保存されない」という一律の説明は削除し、実行modeごとに次を明示する。
- media-backed mode: 「検出した領域情報(座標・検出metadata)は保存されます。crop画像本体は保存されません」
- file-preview mode: 「このファイルの検出結果はpreviewのみで保存されません」
media-backed modeでmodal open時の自動検出を維持する場合、modalを開くことでregionが永続化されることをUIとテストで明示する。見えない副作用を避けるため明示的な検出操作へ変更する場合も、検出実行後は同じ永続化規則を適用する。
追加受け入れ条件
Parent: #612
Depends on: #615
背景
現在の人物検出/cropはBase64画像を返す一時previewで、UIにも「保存されない」と明記されている。crop単位のCCIP抽出には安定したregion IDが必要だが、全検出結果や画像blobを無条件に保存すると容量・lifecycle・watcher処理が複雑になる。remote AI実行では
transparentが転送されない既存不整合もある。設計方針
media_regionsへ登録するderivativerelationを作るスコープ
transparent転送修正非スコープ
受け入れ条件
主な参照
apps/server/src/infrastructure/api/routers/ai-router.ts:100apps/server/src/infrastructure/api/routers/ai-router.ts:111packages/ui/src/character-crop-modal.tsx:72packages/core/src/domain/tagging/schemas.ts:102packages/db/src/schema.ts:678評価反映(2026-07-18)
本節をregion永続化の最終仕様とする。本文にある「検出結果はephemeral」「選択したものだけ保存」「自動全件保存は非スコープ」および対応する旧受け入れ条件は、本節で置き換える。
永続化境界
登録済みmediaを対象とする処理では、検出済み・手動作成済みのregionを常に
media_regionsへ保存する。保存するのは座標と再現用metadataであり、crop画像本体ではない。一方、file inputなど登録済みmedia IDを持たないpreviewはFKの親がないためephemeralのままとする。保存操作を提供する場合は、先にmediaとしてimport/materializeしてからregionを関連付ける。
UI契約
現在の「データは保存されない」という一律の説明は削除し、実行modeごとに次を明示する。
media-backed modeでmodal open時の自動検出を維持する場合、modalを開くことでregionが永続化されることをUIとテストで明示する。見えない副作用を避けるため明示的な検出操作へ変更する場合も、検出実行後は同じ永続化規則を適用する。
追加受け入れ条件