chore: initialize StagePilot baseline documentation and discovery/SRS/batches/releases structure
This commit is contained in:
@@ -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'
|
||||
Reference in New Issue
Block a user