diff --git a/.stagepilot/bootstrap/baseline.yaml b/.stagepilot/bootstrap/baseline.yaml new file mode 100644 index 0000000..e08024f --- /dev/null +++ b/.stagepilot/bootstrap/baseline.yaml @@ -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 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' \ No newline at end of file diff --git a/bootstrap/source-allowlist.txt b/bootstrap/source-allowlist.txt new file mode 100644 index 0000000..a8a25c1 --- /dev/null +++ b/bootstrap/source-allowlist.txt @@ -0,0 +1,12 @@ +# Relative paths from selected source .github directory. +# Files +copilot-instructions.md + +# Directories +agents/ +instructions/ +prompts/ +runbooks/ +scripts/ +skills/ +templates/ \ No newline at end of file diff --git a/docs/batches/index.md b/docs/batches/index.md new file mode 100644 index 0000000..2ca31b0 --- /dev/null +++ b/docs/batches/index.md @@ -0,0 +1,10 @@ +# Batch Index + +## 목적 +- 이 문서는 batch delivery 단위의 전역 인덱스다. +- 각 batch는 `docs/batches//` 아래에서 profile(`standard` | `batch-lite`)에 맞는 산출물을 관리한다. + +## Batch Register + +| BAT ID | Profile | Status | Included REQ | Discovery | Folder | +| --- | --- | --- | --- | --- | --- | \ No newline at end of file diff --git a/docs/data-model.md b/docs/data-model.md new file mode 100644 index 0000000..e9138a9 --- /dev/null +++ b/docs/data-model.md @@ -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. \ No newline at end of file diff --git a/docs/discovery/index.md b/docs/discovery/index.md new file mode 100644 index 0000000..8c9f028 --- /dev/null +++ b/docs/discovery/index.md @@ -0,0 +1,8 @@ +# Discovery 전체 인덱스 + + + +## Discovery 목록 + +| ID | 날짜 | 이슈명 | 문서 | 상태 | +|---|---|---|---|---| \ No newline at end of file diff --git a/docs/interface-contract.md b/docs/interface-contract.md new file mode 100644 index 0000000..26b00fe --- /dev/null +++ b/docs/interface-contract.md @@ -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 :: 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. \ No newline at end of file diff --git a/docs/project-structure.md b/docs/project-structure.md new file mode 100644 index 0000000..fcc6ca5 --- /dev/null +++ b/docs/project-structure.md @@ -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. \ No newline at end of file diff --git a/docs/releases/index.md b/docs/releases/index.md new file mode 100644 index 0000000..ef485a5 --- /dev/null +++ b/docs/releases/index.md @@ -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 | +| --- | --- | --- | --- | --- | --- | \ No newline at end of file diff --git a/docs/runtime-flows.md b/docs/runtime-flows.md new file mode 100644 index 0000000..27fab17 --- /dev/null +++ b/docs/runtime-flows.md @@ -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. \ No newline at end of file diff --git a/docs/srs/index.md b/docs/srs/index.md new file mode 100644 index 0000000..67c789c --- /dev/null +++ b/docs/srs/index.md @@ -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//req-XXX_.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//` 폴더명도 같은 문자열을 사용한다. +- 각 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 + +- 없음 \ No newline at end of file