feat: add portfolio ownership model, auth guards, and migration
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Persistence and Migrations
|
||||
|
||||
- Related REQ: `REQ-001`, `REQ-003`
|
||||
- Related REQ: `REQ-001`, `REQ-003`, `REQ-004`
|
||||
|
||||
## 목표
|
||||
DB 기반 영속성 경로를 안정적으로 운영하고, 스키마 변경 이력과 문서 동기화를 일관되게 유지한다.
|
||||
@@ -28,7 +28,7 @@ DB 기반 영속성 경로를 안정적으로 운영하고, 스키마 변경 이
|
||||
## 스키마 문서 기준
|
||||
|
||||
- Source of truth: Alembic revisions in `migrations/versions`
|
||||
- Current baseline revision: `20260410_0009`
|
||||
- Current baseline revision: `20260413_0010`
|
||||
- 상세 테이블/컬럼/인덱스 제약은 이 문서가 Alembic revision과 동기화된 기준 문서다.
|
||||
|
||||
## 마이그레이션 운영 흐름
|
||||
@@ -158,7 +158,7 @@ Purpose:
|
||||
|
||||
Current baseline note:
|
||||
|
||||
- 아래 컬럼은 revision `20260403_0008`까지의 마이그레이션 기준이다.
|
||||
- 아래 컬럼은 revision `20260413_0010`까지의 마이그레이션 기준이다.
|
||||
|
||||
| Column | Type | Null | Default | Constraints / Notes |
|
||||
| --- | --- | --- | --- | --- |
|
||||
@@ -167,6 +167,7 @@ Current baseline note:
|
||||
| status | Text | NO | `enabled` | Portfolio status |
|
||||
| name | Text | NO | - | Asset name |
|
||||
| symbol | Text | NO | - | Trading symbol |
|
||||
| owner_user_id | Text | NO | - | FK to `users.id` |
|
||||
| cash_balance | Float | NO | - | Current cash balance |
|
||||
| asset_quantity | Float | NO | - | Current asset quantity |
|
||||
| asset_price | Float | NO | 0 | Current price snapshot |
|
||||
@@ -180,7 +181,7 @@ Current baseline note:
|
||||
Constraints:
|
||||
|
||||
- Primary key: `portfolio_id`
|
||||
- Foreign key constraints: none in baseline
|
||||
- Foreign key: `fk_portfolios_owner_user` on (`owner_user_id`) -> `users(id)`
|
||||
|
||||
#### portfolio_ledger
|
||||
|
||||
@@ -239,6 +240,7 @@ Constraints:
|
||||
| `idx_bot_principals_active_created` | `bot_principals` | `is_active`, `created_at` | no | active/inactive bot filtering |
|
||||
| `idx_portfolio_ledger_portfolio_time` | `portfolio_ledger` | `portfolio_id`, `recorded_at DESC` | no | recent ledger query |
|
||||
| `idx_portfolios_broker_status_updated` | `portfolios` | `broker`, `status`, `updated_at DESC` | no | broker/status recency filtering |
|
||||
| `idx_portfolios_owner_updated` | `portfolios` | `owner_user_id`, `updated_at DESC` | no | owner-scoped recency filtering |
|
||||
| `idx_portfolio_comments_portfolio_created` | `portfolio_comments` | `portfolio_id`, `created_at DESC` | no | reverse chronological comments |
|
||||
|
||||
Conditional migration behavior:
|
||||
@@ -248,9 +250,9 @@ Conditional migration behavior:
|
||||
|
||||
## Integrity Notes
|
||||
|
||||
현재 baseline은 DB-level FK constraint를 의도적으로 두지 않는다.
|
||||
현재 baseline은 필수 ownership 제약(`portfolios.owner_user_id` -> `users.id`)만 DB-level FK를 사용한다.
|
||||
|
||||
- logical relation은 application/repository logic이 관리한다.
|
||||
- ownership 외 logical relation은 application/repository logic이 관리한다.
|
||||
- 향후 FK constraint를 추가하면 migration ID와 함께 본 문서를 갱신한다.
|
||||
- application layer cascade:
|
||||
- 포트폴리오 삭제 시 연관 `portfolio_comments`를 hard delete 한다.
|
||||
@@ -273,6 +275,7 @@ Conditional migration behavior:
|
||||
| 20260403_0007 | migrations/versions/20260403_0007_bot_principal_permission_only.py | Remove `owner_user_id` and enforce bot-local permission model |
|
||||
| 20260403_0008 | migrations/versions/20260403_0008_portfolio_name_column.py | Add non-null `portfolios.name` and backfill from `symbol` |
|
||||
| 20260410_0009 | migrations/versions/20260410_0009_portfolio_comments_table.py | Add `portfolio_comments` table for per-portfolio memo history |
|
||||
| 20260413_0010 | migrations/versions/20260413_0010_portfolio_owner_user_id.py | Add `portfolios.owner_user_id`, backfill owner, create owner index, and add owner FK |
|
||||
|
||||
## Open Implementation Points
|
||||
- `portfolio_ledger`의 Timescale hypertable 강제 여부와 보존 정책(retention)을 확정한다.
|
||||
|
||||
Reference in New Issue
Block a user