feat(portfolios): persist and validate daemon assignment on create/update

POST /v1/portfolios now forwards a non-null managed_by_daemon_id into
create persistence, and both create and PATCH apply the same daemon
validation contract (UUID format -> 422, missing/foreign -> 404,
inactive -> 409, admin target-owner basis). Daemon validation locks the
daemon row FOR SHARE inside the portfolio write transaction so
validation and write form one atomic decision boundary.

Adds domain errors, repository protocol/signature updates, API/PostgreSQL
tests (POST->GET persistence, no partial state on failure, assignment vs
deactivation race), and contract/data-model documentation.
This commit is contained in:
2026-08-15 12:56:53 +09:00
parent bb3bb5d3f0
commit e2102b6f2b
10 changed files with 861 additions and 7 deletions
+2
View File
@@ -97,6 +97,7 @@ class _FakeRepo:
profit_buffer: float,
active_strategy_id: str | None,
avabile_strategies: list[str] | None,
managed_by_daemon_id: str | None = None,
) -> Portfolio:
p = Portfolio(
portfolio_id=portfolio_id,
@@ -111,6 +112,7 @@ class _FakeRepo:
price=asset_price,
profit_buffer=profit_buffer,
tag_ids=[],
managed_by_daemon_id=managed_by_daemon_id,
)
self._portfolios[portfolio_id] = p
return p