chore: initialize StagePilot baseline documentation and discovery/SRS/batches/releases structure

This commit is contained in:
2026-04-30 13:19:48 +00:00
parent 7e9fbc1418
commit e362de205f
10 changed files with 723 additions and 0 deletions
+161
View File
@@ -0,0 +1,161 @@
schema_version: 1
capture_mode: observed
project:
repository_name: 'portfolio-hub'
display_name: 'Portfolio Hub'
summary: 'PortfolioHub exposes portfolio management and trading ledger workflows through a FastAPI service and a companion CLI.'
primary_domain: 'portfolio management and trading ledger services'
stack:
tech_stack:
- 'Python 3.12'
- 'FastAPI'
- 'Typer'
- 'Pydantic Settings'
- 'Psycopg'
- 'Alembic'
- 'PostgreSQL/TimescaleDB'
- 'Docker Compose'
runtime:
primary_runtime: 'mixed'
primary_entrypoints:
- name: 'uvicorn app.main:app'
purpose: 'serve the authenticated HTTP API, OpenAPI docs, and startup bootstrap hooks'
- name: 'pfhub'
purpose: 'run operational CLI commands for health, users, portfolios, strategies, and service tokens'
- name: 'alembic upgrade head'
purpose: 'apply ordered database schema migrations for persistent environments'
interfaces:
contracts:
- name: 'Primary HTTP API'
type: 'http-api'
actors: 'authenticated clients, operators, and downstream services'
purpose: 'manage authentication, portfolios, strategy sets, and users over JSON HTTP endpoints'
stability: 'internal'
inputs:
- 'Authorization: Bearer <token> headers for protected routes'
- 'JSON request bodies for login, token issuance, user CRUD, strategy-set CRUD, and portfolio mutations'
- 'Route and query parameters for portfolio IDs, filters, comments, tags, and strategy lookups'
outputs:
- 'JSON responses defined by app/schemas/* response models'
- 'HTTP 201, 200, and 204 status codes matching create, read/update, and delete flows'
- 'GET /health readiness payload of {"status": "ok"}'
errors:
- '401 Unauthorized for invalid credentials or invalid tokens'
- '403 Forbidden for insufficient permission or token policy violations'
- '404 Not Found for missing users, tokens, portfolios, comments, tags, or strategy sets'
- '422 Unprocessable Entity for request validation failures'
compatibility_rules:
- 'Route prefixes /health, /auth, /users, /strategy-sets, and /portfolios form the current internal surface'
- 'Permission semantics read, trade-write, and admin must stay aligned across guards and token metadata'
- 'Breaking route or schema changes require REQ and Batch updates before release'
- name: 'PortfolioHub CLI'
type: 'cli'
actors: 'operators and automation'
purpose: 'provide command-line access to health checks, database setup, users, portfolios, strategies, and service tokens'
stability: 'internal'
inputs:
- 'pfhub subcommands and options such as user, portfolio, strategy, service-token, init-db, and migrate-db'
- '--format table|json and --force flags for automation-safe execution'
- 'PORTFOLIOHUB_* and TIMESCALEDB_* environment variables loaded through app/core/config.py'
outputs:
- 'Rich console tables or JSON payloads for read operations'
- 'One-time token reveal plus masked token metadata on issuance flows'
- 'Exit status and console error output for validation or operational failures'
errors:
- 'Typer argument and option validation failures'
- 'confirmation refusal for write commands without --force'
- 'database connectivity or disabled-persistence failures when DB-backed flows are invoked'
compatibility_rules:
- 'Command group names and flags should remain stable for internal automation'
- 'Write commands require explicit confirmation unless --force is supplied'
- 'JSON output should remain machine-readable across minor command additions'
shared_constraints:
- 'Token permission levels gate both HTTP and CLI mutations consistently.'
- 'DB-backed endpoints and commands require PORTFOLIOHUB_DB_ENABLED=true plus valid TimescaleDB configuration.'
- 'Secrets and token values are only shown once at issuance time and are masked afterwards.'
current_gaps:
- 'External consumer versioning policy is still implicit and not published as a separate artifact.'
- 'Redis and Loki are configured in settings but do not yet appear as first-class runtime contracts.'
- 'Ownership-scoped authorization and service-token policy may continue to evolve in later batches.'
structure:
planned_top_level_areas:
- path: '.github/'
responsibility: 'repository automation, StagePilot skills, templates, and bootstrap scripts'
- path: 'app/'
responsibility: 'FastAPI routes, Typer CLI, domain logic, repositories, and schemas'
- path: 'docs/'
responsibility: 'active SDLC documents and shared cross-cutting baselines'
- path: 'migrations/'
responsibility: 'Alembic environment and ordered schema revisions'
- path: 'tests/'
responsibility: 'API, CLI, service, and persistence regression coverage'
data_model:
persistence_backend: 'PostgreSQL or TimescaleDB via psycopg with Alembic-managed migrations'
entities:
- name: 'Portfolio'
purpose: 'represent an owned investment portfolio with balances, strategy references, tags, comments, and trading history'
source_of_truth: 'portfolios table with dependent portfolio_ledger, portfolio_comments, and portfolio_tags tables'
lifecycle: 'created -> updated by trade and cash operations -> reset or deleted'
key_fields:
- 'portfolio_id :: text :: stable portfolio primary key'
- 'symbol :: text :: traded asset symbol for the portfolio'
- 'owner_user_id :: text|null :: owning user reference for attribution and authorization'
- 'active_strategy_id :: text|null :: currently selected strategy-set reference'
- 'cash_balance :: double precision :: current cash snapshot after the latest ledger event'
- 'asset_quantity :: double precision :: current holdings snapshot after the latest ledger event'
relationships:
- 'User :: owner_user_id links a portfolio to its owning user when ownership is assigned'
- 'StrategySet :: active_strategy_id and avabile_strategies connect reusable strategy definitions'
- 'LedgerEntry, PortfolioComment, PortfolioTag :: child records are keyed by portfolio_id'
state_rules:
- 'Portfolio names are required and backfilled from symbol when older rows are migrated.'
- 'Balance-changing commands must update snapshot fields and append a ledger row together.'
- 'Tags are unique per portfolio and comments are ordered by created_at descending for retrieval.'
- name: 'User'
purpose: 'represent an authenticated principal that can own portfolios and receive client or service tokens'
source_of_truth: 'users table with dependent auth_tokens rows'
lifecycle: 'bootstrapped or created -> updated -> deactivated or deleted'
key_fields:
- 'id :: text :: stable user primary key'
- 'username :: text :: unique login and CLI lookup key'
- 'email :: text|null :: unique contact identity when present'
- 'permission :: text :: baseline role of read, trade-write, or admin'
- 'is_active :: boolean :: authentication and authorization gate'
- 'last_login_at :: timestamptz|null :: latest successful login timestamp'
relationships:
- 'AuthToken :: user_id links issued client and service tokens to the owning user'
- 'Portfolio :: portfolios.owner_user_id ties portfolios to a managing user'
- 'TokenPrincipal :: runtime auth resolution derives principals from persisted tokens and users'
state_rules:
- 'username and email remain unique identifiers when present.'
- 'Bootstrap admin creation only runs when the users table is empty and DB mode is enabled.'
- 'Permission changes affect both API guards and CLI mutation capabilities.'
consistency_rules:
- 'auth_tokens.user_id and portfolios.owner_user_id should resolve to existing users before protected flows run.'
- 'strategy_sets.name plus config, strategy_sets.nick, and service token names have uniqueness constraints.'
- 'Portfolio snapshot fields and portfolio_ledger history must stay synchronized across mutations.'
persistence_notes:
- '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.'
- 'Comments, tags, auth tokens, and ledger rows are normalized into dedicated tables keyed to users or portfolios.'
current_gaps:
- 'Production-like migration verification against a real PostgreSQL or TimescaleDB instance is still pending.'
- 'Retention and archival rules are not yet documented for ledger, comment, or revoked-token records.'
- 'Future authorization changes may require stronger ownership constraints in schema or query paths.'
notes:
known_unknowns:
- 'Real database validation against a PostgreSQL or TimescaleDB deployment is not yet captured in active docs.'
- 'Redis and Loki integration boundaries are configured but not yet documented as baseline runtime flows.'
- 'The first real Discovery should define the next product or operational change after bootstrap.'
metadata:
captured_at_kst: '2026-04-30 22:13'
source: 'bootstrap-baseline'
updated_from: 'repo-observation'