genichin
996127f215
Preserve ledger venue provenance ( #39 )
...
* feat: preserve ledger venue provenance
* fix: satisfy ledger test lint ratchet
* fix: advance image migration inventory
2026-09-19 19:30:32 +09:00
genichin
567d662913
fix(portfolios): replay corporate-action cost basis ( #38 )
2026-09-19 17:07:14 +09:00
genichin
c7d8235bde
fix: make corporate actions atomic and recoverable
Publish verified PortfolioHub image / publish (push) Canceled after 0s
Publish verified PortfolioHub image / verify (push) Canceled after 0s
2026-09-13 19:33:07 +09:00
genichin
1010d257ad
chore(release): prepare v0.3.1
2026-09-13 15:32:27 +09:00
genichin
fa824dfd36
fix corporate action runtime blockers
2026-09-13 14:22:41 +09:00
genichin
925c6b4fa4
fix corporate action replay and trade filtering
2026-09-13 14:17:32 +09:00
genichin
cb19c35d23
fix corporate action replay invariants
2026-09-13 14:12:04 +09:00
genichin
14c118f503
fix corporate action ledger replay invariants
2026-09-13 14:04:30 +09:00
genichin
a4664f5991
feat(portfolio): expose corporate actions in unified ledger
2026-09-13 13:52:50 +09:00
genichin
77468631b1
feat(portfolio): expose corporate action and replay consolidation
2026-09-13 13:47:46 +09:00
copilot-swe-agent[bot] and genichin
e261a41b7f
fix(ledger): split dividend response schema and harden decimal tests
...
Co-authored-by: genichin <4282227+genichin@users.noreply.github.com >
2026-09-09 13:21:24 +00:00
copilot-swe-agent[bot] and genichin
d3601d32dc
fix(ledger): keep legacy amount wire type and preserve dividend tax decimals
...
Co-authored-by: genichin <4282227+genichin@users.noreply.github.com >
2026-09-09 13:00:23 +00:00
copilot-swe-agent[bot] and genichin
fde5b33f05
fix(ledger): preserve exact decimal amount in manual and unified responses
...
Co-authored-by: genichin <4282227+genichin@users.noreply.github.com >
2026-09-09 12:41:36 +00:00
copilot-swe-agent[bot] and genichin
a36b451a3d
fix(manual-ledger): harden schema init race and sanitize error responses
...
Co-authored-by: genichin <4282227+genichin@users.noreply.github.com >
2026-09-09 11:38:32 +00:00
copilot-swe-agent[bot] and genichin
a71c91f6ef
fix: add unified ledger amount and enforce manual decimal precision
...
Co-authored-by: genichin <4282227+genichin@users.noreply.github.com >
2026-09-09 02:23:32 +00:00
copilot-swe-agent[bot] and genichin
ccde81b7a0
feat: support manual dividend ledger entries
...
Co-authored-by: genichin <4282227+genichin@users.noreply.github.com >
2026-09-09 02:04:02 +00:00
genichin
5d6a0ad013
feat(portfolios): allow unassigned strategy creation
2026-08-22 21:21:24 +09:00
genichin
ac742b1150
feat(portfolios): add unified ledger history API
2026-08-20 12:01:28 +09:00
genichin
75e55fde9c
feat(api): expose strategy nick on portfolio items
2026-08-16 13:13:39 +09:00
genichin
e6a90800ec
feat(strategy): expose configurable nick contract
2026-08-15 23:38:18 +09:00
genichin
e90519ad39
fix(daemons): block owner transfer while assigned
2026-08-15 13:20:02 +09:00
genichin
e2102b6f2b
feat(portfolios): persist and validate daemon assignment on create/update
...
POST /v1/portfolios now forwards a non-null managed_by_daemon_id into
create persistence, and both create and PATCH apply the same daemon
validation contract (UUID format -> 422, missing/foreign -> 404,
inactive -> 409, admin target-owner basis). Daemon validation locks the
daemon row FOR SHARE inside the portfolio write transaction so
validation and write form one atomic decision boundary.
Adds domain errors, repository protocol/signature updates, API/PostgreSQL
tests (POST->GET persistence, no partial state on failure, assignment vs
deactivation race), and contract/data-model documentation.
2026-08-15 12:56:53 +09:00
genichin
6e02d92282
Add ProofLine criteria documentation and Strategy Catalog v1 implementation
...
- Add acceptance criteria documentation (AC-0013 through AC-0023)
- Add Line-0003 discovery documentation
- Implement Strategy Catalog v1 with new database migration
- Update portfolio API endpoints and schemas
- Refactor strategy and portfolio services
- Add strategy management CLI commands
- Update domain models with strategy catalog support
- Add comprehensive tests for v1 strategies
- Update design documentation (data model, interfaces, runtime flows)
2026-08-15 11:18:31 +09:00
genichin
93840800fa
feat(portfolios): expose ledger investment aggregates
...
Add reversal-aware grouped manual-ledger aggregates to portfolio list responses and align the single-portfolio return summary with the same semantics.\n\nRefs #23
2026-08-13 13:23:31 +09:00
genichin
b3447f699e
feat(api): add owner-scoped manual ledger endpoint
2026-07-14 19:49:03 +09:00
genichin and Claude Fable 5
8a07742049
feat(req-055): expose strategy & market meta fields in PortfolioItem response (additive)
...
Adds 4 additive fields to GET /v1/portfolios (and single-portfolio) response:
- active_strategy_id (str|null): portfolios.active_strategy_id raw value
- strategy_name (str|null): strategy_sets.name via LEFT JOIN
- strategy_params (dict): strategy_sets.config JSON parsed; {} on missing/invalid
- markets (list[str]): assets.markets; [] on missing/empty
_SELECT_PORTFOLIO extended with LEFT JOIN strategy_sets; _row_to_portfolio
parses new columns (row[19-21]) with JSON error isolation (WARNING log, no 500).
_portfolio_to_item maps all 4 new fields. Existing 16 fields unchanged.
N+1 prevented: single SQL JOIN for both list and single-item paths.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
2026-07-04 11:05:51 +09:00
genichin and Claude Opus 4.8
2dcbafb7a8
fix(dcy-011/bat-022): GET /v1/admin/daemons 목록 엔드포인트 추가 — UI 계약 누락(405) 해소 (라이브 통합테스트 결함)
...
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
2026-06-28 18:20:13 +09:00
genichin and Claude Sonnet 4.6
d24058d863
feat(bat-022): daemon CRUD admin API + self-service credential management (REQ-052/053/054)
...
- POST/PATCH/deactivate/activate /v1/admin/daemons — admin-only daemon CRUD (REQ-053)
- GET/PUT/DELETE /v1/daemons/{daemon_id}/credential — user-owned scoped credential management (REQ-052)
- Owner re-assignment auto-invalidates BrokerCredential via update_daemon_owner() (REQ-053 AC-4)
- Deactivation auto-revokes service tokens via revoke_tokens_by_daemon_id() (REQ-022 reuse, REQ-053 AC-6)
- DELETE /v1/admin/daemons/{id} → 405 (hard delete not provided, REQ-053 AC-8)
- All responses exclude app_key/app_secret; Fernet encryption at rest (REQ-054)
- Service-token → 403 on credential endpoints (REQ-052 AC-10)
- Admin ownership scope enforced: admin cannot write other user's credential (REQ-052 AC-9)
- REQ-051 regression: 4 service-token guard tests pass (REQ-054 AC-7)
- 44 new tests, 565 total passed (521 baseline + 44 new), 0 failures
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
2026-06-28 14:18:37 +09:00
genichin and Claude Sonnet 4.6
51b7cbee35
feat(bat-020): daemon-scoped 브로커 인증정보 (REQ-046~051)
...
- REQ-046: BrokerCredential.daemon_id 필드 추가, repository 시그니처 갱신
- REQ-047: alembic revision Step1(daemon_id NULL 컬럼 추가), Step2(PK 전환, dev/test DB 한정)
- REQ-048: backfill-daemon-id CLI subcommand (--dry-run/--force/--broker 지원)
- REQ-049: GET /v1/user_info daemon-scoped 단일 broker 전달 (brokers→broker, daemon_id 없으면 403)
- REQ-050: credential set/list/remove --daemon-id 옵션 추가 (daemon_slug 해석)
- REQ-051: 보안 격리 - service-token 전용, web 토큰 차단, 로그 app_secret 비노출, graceful degrade
비가역 결재 게이트: REQ-047 Step2(PK 전환)는 사장님 결재 후 실DB 적용 예정(이 batch는 revision 코드만)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
2026-06-28 00:45:46 +09:00
genichin and Claude Sonnet 4.6
c5288a8c42
feat(bat-019): REQ-044 GET /v1/assets require_read + REQ-045 GET /v1/daemons caller-scope
...
REQ-044: list_catalog_assets 의존성을 require_admin → require_read로 완화.
asset 쓰기(POST/PATCH/DELETE)는 require_admin 유지.
REQ-045: GET /v1/daemons 신규 엔드포인트 — caller 소유 데몬만 반환(require_read).
user_id=None(env 토큰)은 빈 목록 200. DaemonResponse/DaemonListResponse 스키마 추가.
기존 테스트(test_v1.py, test_asset_catalog.py, test_daemon_assignment.py, test_tags_master.py)
REQ-044 권한 완화에 맞게 업데이트. test_v1_daemons.py 신규 추가(13 케이스).
pytest 472 passed, 0 failed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
2026-06-27 10:36:04 +09:00
genichin and Claude Sonnet 4.6
d224d716f6
fix(holdings): /holdings/cost-basis WAC row에 fee_amount 편입 (QC보정)
...
get_holdings_cost_basis 핸들러의 row dict에 fee_amount 누락으로
/holdings/cost-basis의 cost_basis_per_unit이 매수 수수료 미편입값을
반환하던 버그 수정. /pnl/realized 핸들러와 동일하게 e.fee_amount 포함.
테스트: buy fee>0 케이스(1000.5 단언) + fee=0 회귀 케이스 추가.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
2026-06-26 20:34:03 +09:00
genichin and Claude Opus 4.8
d93c0bcaf5
feat(holdings): REQ-043 현재 보유 평단(WAC) read — GET /v1/portfolios/{id}/holdings/cost-basis (BAT-018, PR #14 )
...
dcy-008(confirmed)/REQ-043(Approved)/BAT-018. trex-core dcy-034 FR-7 cold-start seed 의존. AC 11/11, QC PASS. worktree+PR 워크플로 첫 파일럿.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
2026-06-26 00:07:43 +09:00
genichin and Claude Opus 4.8
bd34450ee9
feat(pnl): trade history + realized PnL API (WAC) — BAT-017, REQ-039~042 Implemented
...
- GET /v1/portfolios/{id}/trades and GET /v1/portfolios/{id}/pnl/realized endpoints
- Weighted Average Cost (WAC) realized PnL calculation in app/domain/pnl.py
- cost_basis and data_completeness_warning returned in pnl API response
- Test coverage: 50 passed (WAC 20 + trades 12 + pnl 18), full 427 passed regression ✓
- WAC validated against 199,300 unit e2e test cases
- DB migration: none required
- QC: qc-reviewer PASS-WITH-NOTES; team lead confirm-batch-verification → release-candidate
- Remaining non-blocking: symbol filter edge case testing, HTTP_422 deprecation
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
2026-06-18 16:45:01 +09:00
genichin and Claude Opus 4.8
6b812b6035
fix: GET /v1/user_info 500 on missing broker_credentials table (issue #9 )
...
trex-core reported GET /v1/user_info returning 500 for valid service/daemon
tokens (whoami → daemon_id), degrading the daemon and holding new trades. The
reported hypothesis (service-token None deref) was a misdiagnosis. Root cause:
app/api/v1_user_info.py: credentials = repo.list_broker_credentials(...)
psycopg.errors.UndefinedTable: relation "broker_credentials" does not exist
The broker_credentials table was missing and the handler only caught
AttributeError, so the DB error propagated to a bare 500.
Two fixes:
1. Handler now degrades gracefully when broker-credential lookup fails — returns
empty brokers and still serves daemon_id/user_id/permission, which do not
depend on broker credentials. This is what trex-core's whoami needs.
2. ensure_schema() now also CREATE TABLE broker_credentials (same shape as
migration 20260502_0014). ensure_schema-bootstrapped DBs were missing it,
since previously only the alembic path created it.
Added tests/test_v1.py regression: broker-credential lookup raising a DB error
must yield HTTP 200 with daemon_id, not 500. Verified against the real DB
(was 500 → now 200 + daemon_id). Full suite 377 passed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com >
2026-06-06 10:17:30 +09:00
genichin
44f2102d26
feat: consolidate ledger trade writes into portfolio_ledger
...
- add ledger consolidation migration and remove ledger_trades usage
- return portfolio state after v1 ledger trade writes
- deprecate legacy buy/sell endpoints with deprecation headers
- add BAT-016, DCY-006, and REQ-036~038 documentation
- update repository models and tests for unified ledger entries
2026-06-05 20:55:24 +09:00
genichin
2470c0a00c
feat: apply rel-001 feedback cleanup
2026-06-05 13:57:46 +09:00
genichin and Claude Opus 4.7
84de34c301
feat: REQ-028 add display_name to GET /v1/portfolios response
...
- Portfolio domain model + PortfolioItem schema에 display_name 필드 추가
- _SELECT_PORTFOLIO에 a.display_name JOIN 보강, _portfolio_to_item 매퍼 전달
- REQ-028 CHG-20260601-01/02: Implemented → Approved → Implemented
- AC-13 신설 (display_name == joined assets.display_name)
- BAT-009 verification.md: AC-13 매핑 + augmentation history 누적
- REL-001 verification checklist 재실행 evidence 갱신 (368 PASSED, 로컬 smoke 5건 통과)
- tests/test_v1.py: dead 중복 GET /v1/assets 섹션 제거 (두 번째 동명 정의가 첫 번째를 override하던 잔재)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com >
2026-06-01 14:00:59 +00:00
genichin
136ae16885
feat: add portfolio item symbol to v1 responses
2026-05-24 13:09:37 +09:00
genichin and Claude Opus 4.7
58899b1a94
feat: REQ-005 assets table tag apply/remove SQL alignment (BAT-013)
...
- REQ-005 CHG-20260521-02 follow-up: clarify AC-1/AC-5 to target assets table
- Add append_asset_tag_id/remove_asset_tag_id on PostgresPortfolioRepository
- Replace internal calls in apply_asset_tag/remove_asset_tag routes (HTTP contract unchanged)
- 7 new regression tests: method existence, SQL target table, error branches, idempotency guard
- Update existing AC-1/AC-5 assertions to verify new methods + portfolios methods uncalled
- Documentation: runtime-flows.md flow body + change log; rel-001 includes BAT-013
- REQ-005 transition: Approved → Implemented (CHG-20260521-03) via BAT-013 verification
- Total tests: 362 → 369 passed
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-22 00:04:33 +09:00
genichin and Claude Opus 4.7
9038f41010
feat: REQ-002/REQ-010 implementation — assets.tag_ids column + GET /v1/assets admin catalog (BAT-012)
...
- REQ-002 scope redefinition: portfolios.tag_ids → assets.tag_ids UUID[] column with GIN index
- REQ-010 augmentation: GET /v1/assets redesigned as admin catalog endpoint (admin-only, no token_type branching)
- Asset tagging infrastructure: tag_ids column, archived flag synthesis for inactive tags, list_assets N+1 optimization
- DB migration 20260521_0023: assets.tag_ids UUID[] NOT NULL DEFAULT '{}', idx_assets_tag_ids_gin
- Test suite: 17 new test cases for assets.tag_ids + GET /v1/assets AC-9~12 (362 tests total)
- Documentation: runtime flows, release baseline, batch verification all updated
- BAT-012 added to REL-001 Included Batch and marked release-candidate
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-21 23:37:08 +09:00
genichin and Claude Sonnet 4.6
6add0ade29
feat: REQ-001~018 Implemented 전환, REQ-010 GET /v1/assets admin catalog 재정의, REL-001 draft
...
- confirm-req-implemented: REQ-001~018 (17건, REQ-013 제외) Approved → Implemented
- BAT-001(REQ-009/011/014), BAT-002(REQ-010/012/015), BAT-003(REQ-001/002/003/006)
- BAT-004(REQ-004/005), BAT-005(REQ-007/008), BAT-006(REQ-016/017/018)
- CHG-20260521-01 entry 각 REQ에 추가; SRS index Recent Change Log 갱신
- REQ-010 CHG-20260521-02: GET /v1/assets admin catalog 전용 재정의
- 기존 token_type 분기 portfolio 조회 코드 제거, admin permission + list_assets() 호출로 대체
- AssetCatalogListResponse 스키마 추가 (items/total)
- REQ-010 Status: Implemented → Approved (재검증 필요)
- 테스트 343건 전체 통과: service/user token 403, admin token 200 + catalog schema 검증
- migration 보강: portfolios_asset_migration market 컬럼 부재 fallback,
portfolio_tags 빈 테이블 early-return, service_token index fix autocommit_block 정리
- docs/releases/rel-001: REL-001 draft 추가 (BAT-001~011 포함)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-21 10:17:39 +00:00
genichin and Claude Sonnet 4.6
4bf6b554a7
feat: v1 portfolio mutation, sub-resources, ledger path migration (BAT-008~011)
...
dcy-003/004 기반 v1 API surface 완성 및 BAT-008~011 구현·검증 완료:
- BAT-008 (REQ-019~021,024): 토큰 surface baseline 문서 갱신
- BAT-009 (REQ-025~028): POST/PATCH/DELETE/GET /v1/portfolios CRUD 신설
- _require_write_token, _get_portfolio_or_404, soft delete, daemon-scoped list
- BAT-010 (REQ-030~032): portfolio tag/comment 서브 라우트 신설 + baseline 갱신
- GET/POST/DELETE /v1/portfolios/{id}/tags
- POST/GET/PATCH/DELETE /v1/portfolios/{id}/comments
- BAT-011 (REQ-029): ledger path migration
- POST /v1/assets/{asset_id}/ledger/trades → /v1/portfolios/{portfolio_id}/ledger/trades
- v1_ledger.py 제거, disabled 차단(409) 추가
- test_v1.py / test_daemon_assignment.py 구 path 갱신
- 신규 tests: test_v1_portfolios_crud.py, test_v1_portfolios_list.py,
test_v1_portfolios_tags_comments.py, test_v1_portfolios_ledger.py
- 전체 suite: 340 passed
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-21 07:25:39 +00:00
genichin and Claude Sonnet 4.6
c815ce39b6
feat: dcy-003/004 토큰 surface 개편 및 daemon lifecycle 정책 구현 (BAT-006/007)
...
BAT-006 (REQ-016/017/018):
- client token 발급 경로 제거 (issue_client_token, POST /auth/tokens, 관련 스키마/테스트)
- service-token rotate unique index revoked_at IS NULL 조건 추가 (Alembic CONCURRENTLY 마이그레이션)
- POST /auth/service-tokens body daemon_id forward 누락 보정 (1-line fix)
BAT-007 (REQ-022/023):
- daemon deactivate 시 바인딩 service token 자동 revoke (CLI --force 옵션 + revoke_tokens_by_daemon_id)
- NULL daemon_id legacy token 진단 CLI (migrate-null-daemon --dry-run)
거버넌스 문서: dcy-003/004 Discovery, REQ-016~023/025~032 신규, BAT-006/007 전체 산출물
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-21 01:03:39 +00:00
genichin and Claude Sonnet 4.6
d4b841bc37
feat: 태그 HTTP API(BAT-004) 및 pfhub tag CLI + baseline 문서 갱신(BAT-005)
...
BAT-004 (REQ-004, REQ-005):
- app/api/v1_tags.py: POST /v1/tags, GET /v1/tags, PATCH /v1/tags/{id}/deactivate
- app/api/v1_portfolios.py: POST/DELETE /v1/portfolios/{id}/tags
- app/api/v1_assets.py: POST/DELETE /v1/assets/{id}/tags 엔드포인트 추가
- app/schemas/v1.py: TagItem, TagCreateRequest, TagListResponse, TagApplyRequest/Response 추가
- app/repositories/portfolio_repository.py, postgres.py: append/remove_portfolio_tag_id 추가
- app/main.py: v1_portfolios_router, v1_tags_router 등록
- tests/test_tags_http_api.py: 22개 HTTP API 테스트
BAT-005 (REQ-007, REQ-008):
- app/cli/commands/tag.py: pfhub tag create/list/deactivate/apply/remove 7개 커맨드 신규
- app/cli/main.py: tag_app 등록
- app/cli/commands/portfolio.py: pfhub portfolio tag add/list/remove 완전 제거(breaking change)
- app/cli/core/utils.py: print_tag_table + list[Tag] render 분기 추가
- tests/test_tags_cli.py: REQ-007 AC-1~9 커버 24개 CLI 테스트 신규
- tests/test_cli.py: 제거된 portfolio tag 테스트 2개 삭제
- docs/data-model.md, interface-contract.md, project-structure.md, runtime-flows.md: 태그 모델 baseline 갱신(REQ-008)
- docs/batches/: BAT-004, BAT-005 전체 산출물(release-candidate)
247 passed
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-20 01:16:13 +00:00
genichin
158929b2d9
feat: asset catalog API, 태그 DB 기초, 마이그레이션 3건 및 도메인/테스트 갱신 (2026-05-19)
2026-05-19 22:15:55 +00:00
genichin
e2226e28b6
feat: implement asset catalog database foundation (BAT-001, REQ-009/011/014)
...
Asset Catalog Model Implementation (BAT-001):
- Introduce assets table with UUID PK, symbol UNIQUE, markets TEXT[] array
- Define MarketCode enum (KRX, NXT, SOR, NASDAQ, NYSE, UPBIT, BITHUMB)
- Add Asset domain model with catalog properties
- Implement asset CRUD protocols in portfolio_repository
- Add PostgreSQL asset CRUD operations with GIN index on markets
Portfolio Model Refactoring (REQ-011):
- Add portfolios.asset_id UUID FK to assets(asset_id) ON DELETE RESTRICT
- Remove portfolios.symbol and portfolios.market columns
- Update Portfolio domain model to reference asset_id instead of symbol/market
- Refactor all portfolio queries to JOIN assets catalog
- Update all repository methods to use asset references
Data Migration (REQ-014):
- Create 20260519_0017 Alembic revision for assets table creation
- Create 20260519_0018 Alembic revision for atomic data migration:
* Extract unique symbol combinations from portfolios
* Aggregate markets using ARRAY_AGG(DISTINCT market)
* Populate assets catalog with extracted data
* Update portfolios.asset_id to reference new assets
* Remove legacy symbol/market columns in single transaction
- Implement migration with rollback support
Requirements Approved (REQ-001~008):
- REQ-001~008 transitioned from Proposed to Approved
- Complete tag model requirement set with implementation readiness
New Requirements Approved (REQ-009~015):
- REQ-009: assets table schema (approved, included in BAT-001)
- REQ-010: admin asset catalog CRUD (approved, future BAT-002)
- REQ-011: portfolios asset_id FK (approved, included in BAT-001)
- REQ-012: portfolio create catalog validation (approved, future BAT-002)
- REQ-013: GET /v1/assets token branching (approved, future BAT-002)
- REQ-014: portfolios data migration (approved, included in BAT-001)
- REQ-015: asset catalog baseline docs (approved)
Code Changes:
- app/domain/models.py: Add Asset model, MarketCode enum, Portfolio asset_id FK
- app/repositories/portfolio_repository.py: Define asset CRUD protocol
- app/repositories/postgres.py: Implement asset operations with full CRUD
- app/api/v1_assets.py: Remove symbol/market direct references
- app/cli/commands/portfolio.py: Update portfolio commands for asset references
- app/schemas/portfolio.py: Update portfolio schema with asset_id
- All portfolio operations throughout codebase: Use asset references
Testing:
- Add test_asset_catalog.py for asset CRUD operations
- Verify REQ-009 AC-1~5 (asset catalog creation, lookup, uniqueness)
- Verify REQ-011 AC-1~5 (FK constraint, portfolio asset reference)
- Verify REQ-014 AC-1~6 (migration atomicity, data correctness, rollback)
- Update existing tests for asset model usage
Documentation:
- Create BAT-001 batch documents (planning, design, implementation, verification)
- Update dcy-001 with implementation details and confirmed architecture
- Add 8 new requirement documents (REQ-009~015)
- Update docs/discovery/index.md with batch entry
Impact:
- Database: assets catalog table, portfolios refactored to reference assets
- Migration: 2 new Alembic revisions (0017 assets, 0018 portfolio migration)
- API: Symbol/market now accessed through asset references
- CLI: Portfolio commands require asset reference pattern
- All existing portfolio data preserved and correctly migrated
2026-05-19 15:59:20 +00:00
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
genichin
2e1298a978
fix: enforce trade-write permission check on v1 ledger trade endpoint
...
Security Fix:
- Update v1_ledger.py to require trade_write permission instead of read
- Fix authentication dependency from require_read to require_trade_write
- Ensure trade operations cannot be performed with read-only service tokens
Test Coverage:
- Add test_v1_ledger_trade_requires_trade_write_permission() to verify permission boundary
- Confirm read-only tokens are rejected with 403 Forbidden status
- Validate repository methods are not called on permission failure
Documentation:
- Add new Discovery dcy-005 for production admin bootstrap and operator access
- Update docs/discovery/index.md with dcy-005 entry
- Update release rel-001 with additional verification notes and issue references
2026-05-11 14:17:27 +00:00
genichin
a5b5e7a93c
fix: resolve SRS conflicts from batch verification analysis (CONFLICT-1~4)
...
Conflict Resolutions:
- CONFLICT-1 (High): Fix REQ-006 ownership scope — implement owner_user_id filtering
* Change app/api/v1_assets.py: owner_user_id=None → owner_user_id=auth.user_id
* Update docs/runtime-flows.md to reflect service-token owner-scoped portfolio filtering
* Add regression test in tests/test_v1.py for ownership boundary
- CONFLICT-2 (Medium): Transition REQ-001/002/003 to Implemented
* REQ-001: local-db-validation-scenarios (via confirm-req-implemented bat-007)
* REQ-002: alembic-runtime-schema-ownership (via confirm-req-implemented bat-007)
* REQ-003: local-db-operations-runbook-and-baseline-updates (via confirm-req-implemented bat-007)
* Update docs/srs/index.md with status transitions
- CONFLICT-3 (Low): Document REQ-012 rotate lifecycle
* Add rotate lifecycle notes to REQ-012 (change-req req-012)
* Clarify runtime_id change behavior and trex-basic reconnection requirements
- CONFLICT-4 (Low): Clarify REQ-005 AC-2 endpoint path
* Change REQ-005 AC-2: 'POST /auth/tokens or equivalent' → 'POST /auth/service-tokens'
* Update docs/srs/index.md change log with change-req entries
Documentation Updates:
- Update BAT-001 verification status with conflict resolution evidence
- Update release rel-001 with verified status confirmation
- Add change log entries for all conflict resolutions with dates and references
Testing:
- Add ownership boundary test to test_v1.py
- Verify filter works with auth.user_id context
2026-05-11 11:57:21 +00:00
genichin
545d4da413
feat(REQ-006): implement v1 assets endpoint with verification
...
- Add v1_assets.py API endpoint for asset list retrieval
- Add AssetResponse schema to v1.py
- Implement comprehensive test coverage in test_v1.py
- Update requirement verification with implementation evidence
- Update SRS index to mark REQ-006 as Implemented
- Document acceptance criteria validation results
2026-05-03 13:36:27 +00:00