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'
+12
View File
@@ -0,0 +1,12 @@
# Relative paths from selected source .github directory.
# Files
copilot-instructions.md
# Directories
agents/
instructions/
prompts/
runbooks/
scripts/
skills/
templates/
+10
View File
@@ -0,0 +1,10 @@
# Batch Index
## 목적
- 이 문서는 batch delivery 단위의 전역 인덱스다.
- 각 batch는 `docs/batches/<BAT_ID>/` 아래에서 profile(`standard` | `batch-lite`)에 맞는 산출물을 관리한다.
## Batch Register
| BAT ID | Profile | Status | Included REQ | Discovery | Folder |
| --- | --- | --- | --- | --- | --- |
+113
View File
@@ -0,0 +1,113 @@
# Portfolio Hub Data Model
- Baseline Mode: observed
- Baseline Seed: .stagepilot/bootstrap/baseline.yaml
- Status: confirmed
- Owner: repository-maintainers
- Last Updated (KST): 2026-04-30 22:13
- Source Discovery / Batch: bootstrap-baseline
## Project 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.
## Primary Persistence Backend
- PostgreSQL or TimescaleDB via psycopg with Alembic-managed migrations.
## Purpose
- This document captures the approved cross-cutting data model baseline for the project.
- It is a shared reference for REQ drafting, batch design, implementation, verification, migration planning, and handoff.
## Scope
- Covers core entities, relationships, states, persistence mappings, and shared consistency rules.
- Does not duplicate full functional acceptance criteria already owned by REQ documents.
- Does not replace ORM definitions, migration files, or generated schema artifacts.
## Model Summary
- Portfolio :: owned investment portfolio with balances, strategy references, tags, comments, and ledger history
- User :: authenticated principal that owns portfolios and receives client or service tokens
## Entity: `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 are 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 retrieved in created_at descending order.
## Entity: `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.
## Shared 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 / Integration 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 / Planned Changes
- 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.
## Update Triggers
- Update this document when a core entity, key field, or relationship changes.
- Update this document when lifecycle or persistence behavior changes.
- Update this document when a batch introduces a migration, backfill, or breaking data assumption.
## Change Log
- 2026-04-30 KST: Bootstrap baseline created from repository observation for initial StagePilot adoption.
+8
View File
@@ -0,0 +1,8 @@
# Discovery 전체 인덱스
<!-- 아래 테이블은 /new-discovery 실행 시 자동 갱신된다. 수동 편집 금지. -->
## Discovery 목록
| ID | 날짜 | 이슈명 | 문서 | 상태 |
|---|---|---|---|---|
+114
View File
@@ -0,0 +1,114 @@
# Portfolio Hub Interface Contract
- Baseline Mode: observed
- Baseline Seed: .stagepilot/bootstrap/baseline.yaml
- Status: confirmed
- Owner: repository-maintainers
- Last Updated (KST): 2026-04-30 22:13
- Source Discovery / Batch: bootstrap-baseline
- Primary Runtime: mixed
## Project 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.
## Purpose
- This document captures the approved external and cross-boundary interface contracts for the project.
- It is a cross-cutting reference for REQ drafting, batch design, implementation, verification, and handoff.
## Scope
- Covers externally visible APIs, CLI surfaces, events, files, or batch I/O contracts.
- Does not duplicate full business requirements already owned by REQ documents.
- Does not replace low-level code references or generated API artifacts.
## Interface Summary
- Primary HTTP API :: manage authentication, portfolios, strategy sets, and users over JSON HTTP endpoints
- PortfolioHub CLI :: provide command-line access to health checks, database setup, users, portfolios, strategies, and service tokens
## Interface: `Primary HTTP API`
- Type: http-api
- Consumers / Producers: authenticated clients, operators, and downstream services
- Purpose: manage authentication, portfolios, strategy sets, and users over JSON HTTP endpoints
- Stability: internal
### Inputs
- Authorization: Bearer <token> :: required for protected routes and mapped to read, trade-write, or admin permissions
- JSON request bodies :: carry login, token issuance, user CRUD, strategy-set CRUD, portfolio mutations, comments, and tags
- Route and query parameters :: select users, tokens, portfolios, filters, recent history windows, comments, and tags
### Outputs
- JSON response models :: responses are shaped by app/schemas/auth.py, app/schemas/user.py, and app/schemas/portfolio.py
- HTTP 201, 200, and 204 status codes :: create, read or update, and delete semantics respectively
- GET /health payload :: returns {"status": "ok"} for readiness checks
### Error Contract
- 401 Unauthorized :: invalid credentials, invalid token, or missing token on protected routes
- 403 Forbidden :: insufficient permission or token issuance policy violation
- 404 Not Found :: missing user, token, portfolio, comment, tag, or strategy set
- 422 Unprocessable Entity :: FastAPI or Pydantic request validation failure
### Compatibility Rules
- Route prefixes /health, /auth, /users, /strategy-sets, and /portfolios define the current internal API surface.
- Permission semantics read, trade-write, and admin must stay aligned across auth guards and token metadata.
- Breaking route or schema changes require REQ and Batch documentation updates before release.
## Interface: `PortfolioHub CLI`
- Type: cli
- Consumers / Producers: operators and automation
- Purpose: provide command-line access to health checks, database setup, users, portfolios, strategies, and service tokens
- Stability: internal
### Inputs
- pfhub subcommands :: include user, portfolio, strategy, service-token, health-check, init-db, and migrate-db command families
- Flags and options :: include --format table|json, --force confirmations, and operation-specific mutation arguments
- Environment configuration :: app/core/config.py resolves PORTFOLIOHUB_* and TIMESCALEDB_* values before command execution
### Outputs
- Table or JSON console rendering :: read flows emit structured operator output suitable for manual review or automation
- One-time token reveal :: issued client or service tokens are shown once and then only masked metadata remains
- Process exit status :: command success or failure is communicated through standard CLI exit behavior
### Error Contract
- Typer validation errors :: invalid arguments or missing required options stop the command before execution
- Confirmation refusal :: write commands abort unless the operator confirms or passes --force
- Persistence and auth failures :: disabled DB mode, connectivity issues, or permission problems surface as command errors
### Compatibility Rules
- Command names and primary flags should remain stable for internal automation.
- Write commands require explicit confirmation unless --force is present.
- JSON output should remain machine-readable across additive command evolution.
## 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 settings.
- Secret and token values are only revealed once at issuance time and are masked afterwards.
## Current Gaps / Planned Changes
- External consumer versioning policy is still implicit and not published as a separate contract artifact.
- Service-token lifecycle and ownership rules may continue to evolve as authorization requirements mature.
- OpenAPI publication and CLI reference generation are not yet automated.
## Update Triggers
- Update this document when an externally visible API, event, CLI, or file contract changes.
- Update this document when a batch changes compatibility, validation, or error behavior.
- Update this document when a new external consumer or producer is introduced.
## Change Log
- 2026-04-30 KST: Bootstrap baseline created from repository observation for initial StagePilot adoption.
+134
View File
@@ -0,0 +1,134 @@
# Portfolio Hub Project Structure
- Baseline Mode: observed
- Baseline Seed: .stagepilot/bootstrap/baseline.yaml
- Status: confirmed
- Owner: repository-maintainers
- Last Updated (KST): 2026-04-30 22:13
- Source Discovery / Batch: bootstrap-baseline
## Project 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.
## Tech Stack
- Python 3.12
- FastAPI
- Typer
- Pydantic Settings
- Psycopg
- Alembic
- PostgreSQL/TimescaleDB
- Docker Compose
## Primary Runtime
- Type: mixed
- Planned Entry Points:
- uvicorn app.main:app :: serve the authenticated HTTP API, OpenAPI docs, and startup bootstrap hooks
- pfhub :: run operational CLI commands for health, users, portfolios, strategies, and service tokens
- alembic upgrade head :: apply ordered database schema migrations for persistent environments
## Purpose
- This document is the current approved repository and package structure baseline.
- It is a cross-cutting reference document for Discovery, REQ, Batch Design, Batch Verification, and implementation updates.
## Scope
- Covers the top-level repository layout and package or module boundaries.
- Does not duplicate detailed business rules, acceptance criteria, or implementation-only function signatures.
## Top-Level Structure
```text
.
|-- .github/
| |-- instructions/
| |-- prompts/
| |-- runbooks/
| |-- scripts/
| |-- skills/
| `-- templates/
|-- .stagepilot/
| `-- bootstrap/
|-- .vendor/
| `-- stage-pilot/
|-- app/
| |-- api/
| |-- cli/
| |-- core/
| |-- db/
| |-- domain/
| |-- repositories/
| |-- schemas/
| `-- services/
|-- docs/
| |-- batches/
| |-- discovery/
| |-- releases/
| `-- srs/
|-- migrations/
| `-- versions/
|-- tests/
|-- temp/
|-- README.md
|-- alembic.ini
|-- docker-compose.local-test.yml
`-- pyproject.toml
```
## Package / Module Responsibilities
- .github/
- Hosts StagePilot skills, document templates, and helper scripts such as stagepilot-doctor and stagepilot-bootstrap-seed.
- app/api/
- Defines FastAPI route surfaces for health, authentication, users, strategy sets, and portfolios.
- app/cli/
- Defines the Typer entrypoint, command groups, output helpers, and operator-facing command flows.
- app/core/
- Owns configuration loading, auth guards, security helpers, and shared error handling.
- app/domain/
- Holds framework-light domain models shared by services, routes, and repositories.
- app/repositories/
- Provides the repository protocol, repository factory, and concrete Postgres persistence implementation.
- app/schemas/
- Defines request and response schemas for HTTP contracts.
- app/services/
- Implements business logic for auth, portfolios, strategy sets, and users.
- migrations/
- Stores Alembic environment files and ordered schema revisions for persistent database changes.
- tests/
- Covers API behavior, auth flows, CLI behavior, domain services, portfolio comments, tags, ownership, and users.
- docs/
- Stores active SDLC indices and cross-cutting baseline documents.
## Dependency Rules
- Interface layers in app/api/ and app/cli/ should reach persistence through app/services/ and app/repositories/factory.py rather than importing database code directly.
- app/domain/models.py remains the shared contract between services, repositories, and interface adapters.
- app/repositories/postgres.py owns SQL details; migrations/versions/ owns ordered schema evolution history.
- app/core/config.py is the shared configuration source for both the FastAPI app and the Typer CLI.
- tests/ should prefer public API, CLI, or service entrypoints over asserting against private persistence details unless a regression requires it.
## Shared Boundaries
- PortfolioRepository is the abstraction boundary between business logic and concrete persistence.
- Settings and auth primitives are shared across API requests, CLI commands, and startup bootstrap behavior.
- docs/ holds SDLC source-of-truth artifacts, while temp/ remains scratch or legacy material outside the active document flow.
- .vendor/stage-pilot/ is a vendored upstream toolkit and should not be treated as the active host source of truth.
## Current Gaps / Planned Changes
- No active Discovery, REQ, Batch, or Release units exist yet; this baseline only bootstraps the document structure.
- The non-DB repository path intentionally raises a feature-not-ready error when persistence is disabled.
- Redis and Loki settings exist, but their runtime ownership and module boundaries are not yet represented in active docs.
## Update Triggers
- Update this document when package boundaries change.
- Update this document when new top-level runtime or domain modules are added.
- Update this document when a batch changes the approved structure baseline.
## Change Log
- 2026-04-30 KST: Bootstrap baseline created from repository observation for initial StagePilot adoption.
+10
View File
@@ -0,0 +1,10 @@
# Release Index
## 목적
- 이 문서는 release 단위의 전역 인덱스다.
- 각 release는 하나 이상의 release-candidate batch를 묶고, profile(`docs-only` | `tooling` | `app-service`)에 맞는 배포와 후속 환류를 추적한다.
## Release Register
| REL ID | Profile | Status | Included Batch | Discovery/REQ Input | Link |
| --- | --- | --- | --- | --- | --- |
+74
View File
@@ -0,0 +1,74 @@
# Portfolio Hub Runtime Flows
- Baseline Mode: observed
- Baseline Seed: .stagepilot/bootstrap/baseline.yaml
- Status: confirmed
- Owner: repository-maintainers
- Last Updated (KST): 2026-04-30 22:13
- Source Discovery / Batch: bootstrap-baseline
- Primary Runtime: mixed
## Project Summary
- PortfolioHub exposes portfolio management and trading ledger workflows through a FastAPI service and a companion CLI.
## Purpose
- This document is the current approved execution-flow baseline for the project.
- It is a cross-cutting reference document for Discovery, REQ, Batch Design, Batch Verification, and implementation updates.
## Scope
- Covers representative command and runtime flows.
- Does not duplicate full acceptance criteria or low-level implementation details.
## Covered Entry Points
- uvicorn app.main:app :: serve the authenticated HTTP API, OpenAPI docs, and startup bootstrap hooks
- pfhub :: run operational CLI commands for health, users, portfolios, strategies, and service tokens
- alembic upgrade head :: apply ordered database schema migrations for persistent environments
## Shared Components
- app/core/config.py Settings loading and environment normalization
- app/core/auth.py permission guards and auth context resolution
- app/services/* business logic for auth, users, portfolios, and strategy sets
- app/repositories/factory.py repository selection and Postgres config construction
- app/repositories/postgres.py Postgres persistence, schema bootstrap, and query execution
## Flow: `HTTP API Request Handling`
1. Uvicorn loads app.main:app, which creates the FastAPI application from create_app().
2. create_app() loads Settings, registers middleware and routers, and wires exception handlers.
3. During lifespan startup, the app optionally bootstraps an initial admin user when DB mode and bootstrap credentials are configured.
4. Incoming requests pass through auth and permission dependencies before services mutate state or query persistence.
5. Services call the repository factory, which returns PostgresPortfolioRepository only when PORTFOLIOHUB_DB_ENABLED=true.
6. Routes serialize domain results into app/schemas response models or return HTTP 204 for deletion flows.
## Flow: `CLI Operational Command Execution`
1. The pfhub entrypoint builds a Typer application and injects Settings, console output, and a repository factory into AppContext.
2. Command groups parse arguments, confirmations, and output format selection before invoking the relevant service or repository methods.
3. Database setup commands use the shared settings layer to target the configured PostgreSQL or TimescaleDB instance.
4. Read commands print table or JSON output, while write commands require explicit confirmation unless --force is supplied.
5. Command failures surface as validation errors, feature-not-ready errors, or persistence and auth exceptions.
## Flow Constraints
- Persistence-dependent HTTP and CLI flows require PORTFOLIOHUB_DB_ENABLED=true plus valid TimescaleDB connection settings.
- Permission levels read, trade-write, and admin must map consistently across API guards, issued tokens, and CLI mutations.
- Request validation and auth resolution should happen before persistence mutation or response rendering.
- The health endpoint remains unauthenticated so infrastructure can probe readiness without a token.
## Current Gaps / Planned Changes
- End-to-end validation against a real PostgreSQL or TimescaleDB deployment is still pending.
- Redis and Loki are configured as supporting infrastructure but are not yet represented as explicit runtime flows.
- Ownership-scoped authorization remains an open evolution area after bootstrap.
## Update Triggers
- Update this document when a command entry point changes.
- Update this document when a runtime orchestration path changes.
- Update this document when a batch changes the approved flow baseline.
## Change Log
- 2026-04-30 KST: Bootstrap baseline created from repository observation for initial StagePilot adoption.
+87
View File
@@ -0,0 +1,87 @@
# Software Requirement Specification Index
## 목적
- 이 문서는 프로젝트의 SRS 운영 기준과 requirement 목록을 관리하는 entry point이다.
- 개별 requirement의 상세 내용은 타입별 폴더 하위 `req-XXX_*.md` 파일에서 관리한다.
## 사용 방법
1. 새로운 requirement가 필요하면 `Next Requirement ID`를 확인하고 `docs/srs/req-template.md`를 복사해 `docs/srs/<Type>/req-XXX_<slug>.md` 파일을 생성한다.
2. 초안 작성은 `draft-req`, 승인 전환은 `confirm-req`, 변경 대응은 `change-req`, 구현 완료 전환은 `confirm-req-implemented` skill을 기준으로 수행한다.
3. 작성 또는 수정 후 누락과 모호성을 점검한다.
4. requirement 추가 또는 변경 후 `Next Requirement ID`, `Requirement Register`, `Recent Change Log Summary`를 함께 갱신한다.
5. `Proposed` requirement를 승인하려면 승인 준비 상태와 blocker를 점검한다.
6. `Approved` requirement는 구현 이슈나 작업 항목으로 연결한다.
7. 구현과 검증이 끝난 requirement는 `confirm-req-implemented` skill로 완료 전환 가능 여부를 점검한다.
8. requirement 변경 시 `change-req` skill을 기준으로 해당 REQ 파일의 `Change Log`를 먼저 갱신한 뒤 본문을 수정한다.
9. 구현 전에는 관련 REQ 파일과 최근 `Change Log`를 기준으로 변경 범위를 판단한다.
## 상태 정의
- Proposed: 초안 상태이며 구현 기준으로 확정되지 않음
- Approved: 구현 기준으로 승인됨
- Implemented: 구현과 검증이 완료됨
- Deprecated: 더 이상 유지하지 않음
## Status Transition Evidence
### Proposed -> Approved
- `Status`, `Type`, `Priority`, `Owner`, `Intent`, `Requirement`, `Acceptance Criteria`, `Impacted Area`, `Change Log`가 모두 존재해야 한다.
- `Type`은 아래 분류 도표에서 정확하게 하나로 지정되어야 한다.
- `Acceptance Criteria`는 구현 판단에 사용할 수 있을 정도로 구체적이어야 한다.
- 미해결 assumption 또는 open question이 있으면 `Notes`에 명시하고, 승인 blocker 여부를 판단해야 한다.
- 승인 전환 시 해당 REQ 파일의 `Change Log`에 status 변경 사유를 기록해야 한다.
### Approved -> Implemented
- 각 `Acceptance Criteria`에 대해 test, manual verification, 또는 구현 결과 중 최소 1개의 evidence가 있어야 한다.
- evidence는 requirement 문서 자체 또는 연결된 구현/검증 결과에서 추적 가능해야 한다.
- 미충족 `Acceptance Criteria`가 있으면 `Implemented`로 전환하지 않는다.
- 구현 완료 전환 시 잔여 리스크와 미검증 영역이 있으면 `Change Log`에 기록해야 한다.
- 상태 전환은 `confirm-req-implemented` skill을 기준으로 수행한다.
### Requirement Change Handling
- 기존 REQ 본문(`Requirement`, `Acceptance Criteria`, `Impacted Area`)을 수정하기 전에는 새 `Change Log` 항목을 만든다.
- `Change Log`에는 최소한 `Acceptance Criteria Delta`, `Impacted Area Delta`, `Delivery Trace Delta`, `Revalidation Impact`, `Validation Plan`이 포함되어야 한다.
- 변경이 기존 구현 또는 verification evidence를 무효화하면 `Implemented` requirement는 `Approved`로 되돌린다.
- 변경이 승인 전제 자체를 다시 검토하게 만들면 `Approved` 또는 `Implemented` requirement를 `Proposed`로 되돌릴 수 있다.
- 상태 되돌림이 발생하면 `Requirement Register`와 `Recent Change Log Summary`도 함께 갱신한다.
## Requirement 타입 분류 도표
| 타입 | 정의 | 예시 |
|------|------|------|
| **Configuration** | 설정 옵션, 커스터마이징 포인트 | 설정 파라미터, 환경 변수, 옵션 항목 |
| **Data** | 데이터 구조, 저장/로드, 파일 형식, 스키마 | 설정 파일 형식, DB 스키마, API 구조 |
| **Deployment** | 배포 방식, 운영 절차, 배포 환경 | 컨테이너 배포, 스택 관리, 운영 가이드 |
| **Documentation** | 문서 작성, 가이드, 매뉴얼, 안내서 | 사용자 가이드, API 문서, 튜토리얼 |
| **Exception** | 오류 처리, 예외 복구, 재시도 전략 | 오류 복구, 검증 실패 처리, 폴백 전략 |
| **Installation** | 시스템 설치, 환경 구성, 초기화 절차 | Docker 이미지 빌드, DB 마이그레이션, 사전 조건 설정 |
| **Integration** | 외부 시스템 연동, 플러그인, 확장 | 3rd party 연동, 플러그인 인터페이스 |
| **Interface** | 사용자 상호작용 방식 (UI, API, CLI, 제어방식) | CLI 명령어, API 엔드포인트, 웹 UI 기능 |
| **Migration** | 데이터 이전, 버전 업그레이드 | 데이터 마이그레이션, 버전 호환성 |
| **Non-Functional** | 성능, 보안, 확장성, 호환성, 신뢰성 | 성능 목표, 보안 정책, 확장성 |
| **Testing** | 테스트 전략, QA 요구사항, 검증 방식 | 테스트 커버리지, 회귀 테스트, 수락 기준 |
## Requirement 작성 규칙
- 각 requirement는 고유 ID를 가진다. 예: `REQ-001`
- 다음 신규 requirement 번호의 source of truth는 이 문서의 `Next Requirement ID` 섹션이다.
- 새 requirement를 추가하거나 ID 충돌이 발생할 수 있는 변경을 했으면 `Next Requirement ID`를 함께 갱신한다.
- 각 requirement는 `Type`을 명시해야 한다. 위 분류 도표 중 정확하게 하나로 선택하며, `docs/srs/<Type>/` 폴더명도 같은 문자열을 사용한다.
- 각 requirement는 `Intent`, `Requirement`, `Acceptance Criteria`, `Impacted Area`를 반드시 포함한다.
- 모호한 표현("개선한다", "적절히 처리한다") 대신 관찰 가능하고 test 가능한 문장을 사용한다.
- requirement 변경 사항은 해당 REQ 파일의 `Change Log`에 기록한다.
- requirement 변경 시 영향 받는 batch/release와 재검증 필요 여부를 `Change Log`에 남긴다.
- `Recent Change Log Summary`는 최신 5건만 유지한다.
- status 전환은 `Status Transition Evidence` 기준을 따른다.
## Next Requirement ID
- Current: `REQ-001`
- Rule: `Requirement Register`에 있는 가장 큰 REQ 번호보다 정확히 1 커야 한다.
## Requirement Register
| ID | Title | Type | Status | Priority | Owner | Link |
| --- | --- | --- | --- | --- | --- | --- |
## Recent Change Log Summary
- 없음