Files
portfolio-hub/docs/srs/Migration/req-009_v1-api-db-schema-migration.md
T
genichin e6b6a8715b feat: implement daemon model with registry and single-asset assignment (BAT-010, REQ-023/028)
Core Implementation (BAT-010):
- Add daemon registry schema and CRUD operations (req-023)
- Implement single-daemon asset assignment constraint (one asset per daemon)
- Add daemon_id field to service_token for daemon identification
- Add daemon.py CLI module for daemon management commands
- Add 20260513_0016_daemon_model.py migration for daemon tables

API Changes:
- GET /v1/assets: include daemon_id in AssetResponse
- POST /v1/assets/{asset_id}/ledger/trades: require daemon token binding
- GET /v1/user_info: include daemon metadata
- Enhanced service-token rotate to preserve daemon bindings

CLI Commands:
- pfhub daemon register --name <name> --runtime-id <runtime-id>
- pfhub daemon list
- pfhub daemon get <daemon-id>
- pfhub daemon revoke <daemon-id>

Requirements (REQ-023, REQ-028):
- REQ-023: Daemon Registry and Service Token Daemon Binding (Interface, Approved)
  * AC-1: daemon CRUD operations
  * AC-2: service token daemon binding for POST /v1/assets/{asset_id}/ledger/trades
  * AC-3: single daemon per asset (exact-one assignment model)
- REQ-028: README.md Daemon Provisioning Runbook update (Documentation, Approved)

Documentation:
- Add dcy-006 Discovery for daemon-id and single-daemon asset assignment
- Update README.md with Daemon Provisioning Runbook section
- Add BAT-010 batch documentation with planning, implementation, verification
- Update rel-006 release document (daemon model implementation)
- Update data-model.md with daemon and daemon_asset_assignment tables
- Update interface-contract.md with daemon registry APIs
- Update runtime-flows.md with daemon lifecycle flows

Breaking Changes:
- REQ-005~009, REQ-011~012 status reverted to Approved due to revised contract
  * daemon_id field addition and exact-one asset assignment requirement
  * Existing Implemented evidence invalidated by contract revision
  * BAT-001/002/008 re-verification required

Testing:
- Add test_daemon_registry.py for daemon CRUD operations
- Add test_daemon_assignment.py for single-asset assignment constraints
- Update test_auth.py, test_cli.py, test_v1.py for daemon support
- Verify daemon token binding in trade endpoint authorization

Impact:
- Database: 2 new tables (daemons, daemon_asset_assignments)
- Migration: 20260513_0016 creates daemon model schema
- CLI: 4 new daemon subcommands
- API: daemon_id propagation through v1 endpoints
- Verification: BAT-001/002/008 re-verification gates next release
2026-05-13 23:07:24 +00:00

185 lines
9.2 KiB
Markdown

# req-009: v1 API 지원을 위한 DB 스키마 migration 추가
- Status: Approved
- Type: Migration
- Priority: High
- Owner: repository-maintainers
## Intent
- dcy-002에서 요구하는 4개 DB 변경(portfolios.market 컬럼, auth_tokens.runtime_id 컬럼, broker_credentials 테이블, ledger_trades 테이블)을 Alembic revision으로 구현한다.
- dcy-006의 daemon-aware authorization 모델을 위해 `daemons` registry, `auth_tokens.daemon_id`, `portfolios.managed_by_daemon_id`, transition backfill 및 관련 제약을 같은 migration ownership 규칙 안에서 확장한다.
- IF NOT EXISTS 패턴을 유지해 REQ-002 정책을 준수한다(NFR-4).
## Requirement
- 다음 스키마 변경을 IF NOT EXISTS 패턴을 사용하는 신규 Alembic migration으로 추가해야 한다.
1. portfolios 테이블에 market TEXT NULLABLE 컬럼 추가 (기존 행은 NULL로 유지)
2. auth_tokens 테이블에 runtime_id TEXT UNIQUE NULLABLE 컬럼 추가
3. broker_credentials 테이블 신규 생성 (user_id, broker, account_ref, encrypted_payload, credential_version, last_rotated_at 포함)
4. ledger_trades 테이블 신규 생성 (ledger_entry_id PK, asset_id, order_id, execution_id, side, quantity, price, fee_amount, tax_amount, executed_at, recorded_at 포함, (asset_id, order_id, execution_id) unique constraint 포함)
5. daemons registry 테이블 신규 생성 (`daemon_id`, `owner_user_id`, stable slug/display metadata, 생성/갱신 시각 포함)
6. auth_tokens 테이블에 `daemon_id` NULLABLE FK 컬럼 추가, portfolios 테이블에 `managed_by_daemon_id` NULLABLE FK 컬럼 추가
7. transition migration은 기존 service-token과 portfolio의 daemon 관련 컬럼을 `NULL`로 backfill하고, post-cutover exact-one assignment로 수렴할 수 있도록 same-user consistency 및 invalid reference rejection을 위한 FK/check/unique 제약을 제공해야 한다.
## Acceptance Criteria
1. Given alembic upgrade head 실행 후, When portfolios 테이블을 조회하면, Then market TEXT NULLABLE 컬럼이 존재해야 한다.
2. Given alembic upgrade head 실행 후, When auth_tokens 테이블을 조회하면, Then runtime_id TEXT NULLABLE UNIQUE 컬럼이 존재해야 한다.
3. Given alembic upgrade head 실행 후, Then broker_credentials 테이블이 존재해야 한다.
4. Given alembic upgrade head 실행 후, Then ledger_trades 테이블이 존재해야 한다.
5. Given (asset_id, order_id, execution_id) 동일 조합으로 ledger_trades에 두 번 삽입 시, Then UniqueViolation이 발생해야 한다.
6. Given migration을 이미 실행한 DB에 동일 migration을 재실행하면, Then 에러 없이 완료되어야 한다(IF NOT EXISTS 보장).
7. Given portfolios 테이블의 기존 행, When migration 실행 후 조회하면, Then market 값이 NULL이어야 한다(기존 데이터 보정 없음, DECIDE_MARKET_DEFAULT Answered).
8. Given alembic upgrade head 실행 후, When schema를 조회하면, Then `daemons` 테이블과 `auth_tokens.daemon_id` 컬럼이 존재해야 한다.
9. Given alembic upgrade head 실행 후, When portfolios 테이블을 조회하면, Then `managed_by_daemon_id` 컬럼이 존재하고 기존 행은 `NULL`로 backfill되어 있어야 한다.
10. Given 존재하지 않는 `daemon_id`를 auth_tokens 또는 portfolios에 바인딩하려고 시도하면, Then FK 또는 동등 제약으로 거부되어야 하며, owner user 일관성을 깨는 binding/assignment는 DB 레벨 제약 또는 동등한 무결성 장치로 방지되어야 한다.
## Impacted Area
- Docs: docs/data-model.md (REQ-011에서 갱신 예정)
- Modules: migrations/versions/, app/domain/models.py, app/repositories/portfolio_repository.py, app/repositories/postgres.py
- Tests: tests/test_app.py 또는 migration 검증 테스트, daemon schema integrity 검증
## Notes
- NFR-4(IF NOT EXISTS 패턴) 준수 — REQ-002 Alembic migration 정책 기반.
- broker_credentials 테이블의 encrypted_payload 컬럼은 Fernet 암호화된 ciphertext를 TEXT로 저장한다. 암복호화 로직은 REQ-010 참조.
- 컬럼 상세 타입(NUMERIC vs FLOAT, TIMESTAMPTZ 등)은 설계 단계(draft-batch-design)에서 확정한다.
- daemon exact-one assignment의 steady-state `NOT NULL`/강제 cutover는 inventory/backfill 완료 이후 단계적으로 적용할 수 있다. transition migration은 `NULL` backfill을 허용하되 fail-open을 허용하면 안 된다.
- migration revision ID는 구현 시 기존 revision chain의 마지막 head를 down_revision으로 참조한다.
- Source Discovery: dcy-002 (영향 범위, NFR-4, DECIDE_MARKET_DEFAULT), dcy-006 (FR-1, FR-2, NFR-2, NFR-3)
## Change Log
### CHG-20260513-01
- Date: 2026-05-13
- Author: repository-maintainers
#### Change Summary
- runtime_id 중심 v1 migration REQ를 daemon registry/binding/assignment 스키마까지 포함하도록 확장하고, 기존 Implemented 상태를 Approved로 되돌림
#### Intent
- dcy-006의 daemon-aware model은 기존 REQ-009 구현 범위를 넘어서 `daemons`, `auth_tokens.daemon_id`, `portfolios.managed_by_daemon_id`, transition backfill, same-user consistency 제약을 추가로 요구한다. BAT-001/REL-001 migration evidence는 이 범위를 포함하지 않는다.
#### Acceptance Criteria Delta
- Added:
- AC-8: `daemons`, `auth_tokens.daemon_id`
- AC-9: `portfolios.managed_by_daemon_id` + NULL backfill
- AC-10: daemon FK / 무결성 제약
- Updated:
- Requirement 본문에 daemon registry 및 transition backfill 항목 추가
- Removed:
- none
#### Impacted Area Delta
- Docs:
- `docs/data-model.md`, `docs/runtime-flows.md`
- Modules:
- `migrations/versions/`, `app/domain/models.py`, `app/repositories/portfolio_repository.py`, `app/repositories/postgres.py`
- Tests:
- migration integrity / daemon schema constraint 검증
#### Delivery Trace Delta
- Batches:
- BAT-001 (release-candidate; REL-001 released input) — 기존 migration verification은 daemon schema, backfill, constraint evidence를 포함하지 않음
- Releases:
- REL-001 (released) — release facts는 runtime_id/broker_credentials/ledger_trades까지만 다루므로 revised migration REQ를 충족하지 않음
#### Revalidation Impact
- Reverification Needed: yes
- Existing Implementation Invalidated: yes
- Status Recommendation: rollback-to-approved
- Follow-up Action: dcy-006 후속 batch에서 신규 Alembic revision과 migration validation을 설계하고, cutover/backfill evidence를 release 단계에서 수집한다.
#### Validation Plan
- 현재 migration chain과 `app/repositories/postgres.py` schema ownership을 재검토해 daemon schema 추가 위치를 설계한다.
- 구현 후 alembic upgrade / re-run / invalid daemon reference 검증을 포함한 migration test plan을 수행한다.
### CHG-20260511-01
- Date: 2026-05-11
- Author: repository-maintainers
#### Change Summary
- Implemented 전환 — BAT-001 re-verified verification passed, confirm-req-implemented 게이트 통과
#### Intent
- BAT-001 verification.md (re-verified, 2026-05-03) AC-1~7 모두 코드 검토 PASS. DB 환경 실행 미확인은 non-blocker로 처리됨 (revision에 IF NOT EXISTS 패턴 전체 적용 확인). Blocking Issues 없음.
#### Acceptance Criteria Delta
- none
#### Impacted Area Delta
- none
#### Delivery Trace Delta
- Batches: BAT-001 (release-candidate)
- Releases: none
#### Revalidation Impact
- Reverification Needed: no
- Existing Implementation Invalidated: no
- Status Recommendation: implemented
- Follow-up Action: draft-release (BAT-001); 배포 전 Docker Compose 환경에서 실제 migration 실행 검증 권장
#### Validation Plan
- BAT-001 verification.md (re-verified) AC-1~7 코드 검토 evidence 연결 확인 완료
### CHG-20260502-02
- Date: 2026-05-02
- Author: repository-maintainers
#### Change Summary
- REQ-009 confirm-req 승인 전환 (Status: Proposed → Approved)
#### Intent
- 필수 필드(Status, Type, Priority, Owner, Intent, Requirement, Acceptance Criteria 7개, Impacted Area, Change Log) 모두 충족 확인 후 승인
#### Acceptance Criteria Delta
- No change
#### Impacted Area Delta
- No change
#### Delivery Trace Delta
- Batches:
- none
- Releases:
- none
#### Revalidation Impact
- Reverification Needed: no
- Existing Implementation Invalidated: no
- Status Recommendation: keep-current
- Follow-up Action: suggest-batch-reqs → draft-batch
### CHG-20260502-01
- Date: 2026-05-02
- Author: repository-maintainers
#### Change Summary
- REQ-009 최초 생성 (source Discovery: dcy-002)
#### Intent
- v1 API 지원에 필요한 DB 스키마 변경을 REQ backlog로 정규화
#### Acceptance Criteria Delta
- Added:
- 전체 Acceptance Criteria 신규 작성
#### Impacted Area Delta
- Docs:
- docs/data-model.md (REQ-011에서 갱신 예정)
- Modules:
- migrations/versions/ 신규 migration 파일
- app/domain/models.py 모델 필드 추가
- Tests:
- migration 검증 테스트
#### Delivery Trace Delta
- Batches:
- none
- Releases:
- none
#### Revalidation Impact
- Reverification Needed: no
- Existing Implementation Invalidated: no
- Status Recommendation: keep-current
- Follow-up Action: confirm-req 후 batch 배정. REQ-005, REQ-006, REQ-007, REQ-008과 함께 delivery 단위 구성 필수(runtime_id, market, broker_credentials, ledger_trades 모두 이 migration에 의존).