Add ProofLine criteria documentation and Strategy Catalog v1 implementation
- Add acceptance criteria documentation (AC-0013 through AC-0023) - Add Line-0003 discovery documentation - Implement Strategy Catalog v1 with new database migration - Update portfolio API endpoints and schemas - Refactor strategy and portfolio services - Add strategy management CLI commands - Update domain models with strategy catalog support - Add comprehensive tests for v1 strategies - Update design documentation (data model, interfaces, runtime flows)
This commit is contained in:
+25
-1
@@ -102,6 +102,28 @@
|
||||
- Only `status="active"` assets can be referenced when creating a new portfolio.
|
||||
- Deactivated assets do not affect existing portfolios; only new creation is blocked.
|
||||
|
||||
## Entity: `StrategySet`
|
||||
|
||||
- Purpose: stable, reusable strategy catalog entry selected by portfolio mutations through its ID
|
||||
- Source of Truth: `strategy_sets`; migration `20260814_0029` adds lifecycle and revision fields and seeds/reuses the canonical `target_value` / `{}` entry
|
||||
- Lifecycle: active → updated with monotonically increasing revision → optionally inactive → deleted only when unreferenced
|
||||
|
||||
### Key Fields
|
||||
|
||||
- id :: text :: stable strategy ID; never changes during PATCH
|
||||
- name/config :: text :: strategy identity/configuration pair; unique together
|
||||
- nick :: text :: unique derived display key (`name:sha1(config)[:12]`), recomputed from the latest row state under the PATCH row lock
|
||||
- status :: text :: `active` or `inactive`; inactive entries remain valid historical references but cannot be newly assigned
|
||||
- revision :: integer :: starts at 1 and increments once per effective mutation; no-op PATCH does not increment
|
||||
- created_at/updated_at :: timestamptz :: creation and last effective mutation timestamps
|
||||
|
||||
### Relationships and Deletion
|
||||
|
||||
- `portfolios.active_strategy_id` and entries in `portfolios.avabile_strategies` reference strategy IDs.
|
||||
- New selection uses a strategy `FOR SHARE` lock in the same transaction as portfolio persistence; PATCH/DELETE use `FOR UPDATE` so concurrent mutation, inactivation, and deletion serialize.
|
||||
- Deletion is rejected while either reference form exists. The reference check and delete share one transaction, preventing check-then-delete orphan races. Inactivation does not rewrite existing portfolio references.
|
||||
- Trade snapshot persistence does not write either strategy-selection column. Strategy selection is owned only by portfolio create/update paths, so stale BUY/SELL state cannot resurrect a deleted strategy reference.
|
||||
|
||||
## Entity: `Portfolio`
|
||||
|
||||
- Purpose: represent an owned investment portfolio with balances, strategy references, tags, comments, and trading history
|
||||
@@ -116,7 +138,8 @@
|
||||
- symbol :: text :: display symbol populated via JOIN on assets (read-only, not stored in portfolios)
|
||||
- status :: text :: `"enabled"` (active, default) | `"disabled"` (soft-deleted); set to `"disabled"` by `DELETE /v1/portfolios/{id}`; only `status` can be mutated on a disabled portfolio (restoration via PATCH); all other writes → HTTP 409
|
||||
- owner_user_id :: text|null :: owning user reference for attribution and authorization
|
||||
- active_strategy_id :: text|null :: currently selected strategy-set reference
|
||||
- active_strategy_id :: text|null :: currently selected stable strategy-catalog ID; create requires an active strategy and update may select another active strategy
|
||||
- strategy_revision :: integer|null :: read-only revision joined from the currently referenced StrategySet; subsequent API reads expose the latest committed shared config revision
|
||||
- cash_balance :: double precision :: current cash snapshot after the latest ledger event
|
||||
- asset_quantity :: double precision :: current holdings snapshot after the latest ledger event
|
||||
- managed_by_daemon_id :: text|null :: soft reference to daemons.id; controls daemon-scoped API access; NULL = unassigned (fail-closed for ledger writes and asset listing); set to NULL on soft delete; added by migration 20260513_0016
|
||||
@@ -333,6 +356,7 @@
|
||||
|
||||
- Alembic revisions in migrations/versions/ are the ordered schema history for persistent environments.
|
||||
- app/repositories/postgres.py includes ensure_schema() for bootstrap safety, but long-term schema evolution should run through Alembic.
|
||||
- Current Alembic head is `20260814_0029`; its strategy columns, default seed, and constraints are guarded for ensure_schema-first and repeatable execution.
|
||||
- Comments, tags, auth tokens, and ledger rows are normalized into dedicated tables keyed to users or portfolios.
|
||||
|
||||
## Current Gaps / Planned Changes
|
||||
|
||||
Reference in New Issue
Block a user