Files
portfolio-hub/docs/batches/bat-024_20260714_manual-ledger-api/verification.md
T

3.3 KiB

BAT-024 Verification

Status

  • Stage: draft-batch-verification
  • Result: PASS (developer self-verification)
  • Date: 2026-07-14 KST

Scope

  • REQ-056: owner-scoped 수동 장부 입력 HTTP API
  • Implemented endpoints:
    • POST /v1/portfolios/{portfolio_id}/ledger/manual
    • GET /v1/portfolios/{portfolio_id}/ledger/manual
    • GET /v1/portfolios/{portfolio_id}/returns/summary
  • Preserved endpoint:
    • POST /v1/portfolios/{portfolio_id}/ledger/trades

Evidence

Static/syntax

python3 -m compileall app
exit_code=0

Full regression

PYTHONPATH=. uv run python -m pytest -q --override-ini addopts=''
594 passed, 12 warnings in 37.24s
exit_code=0

Warnings are pre-existing Starlette/FastAPI deprecation warnings around TestClient/httpx and HTTP_422 constants; no failures.

Targeted regression

PYTHONPATH=. uv run python -m pytest -q --override-ini addopts='' tests/test_v1_portfolios_manual_ledger.py tests/test_v1_portfolios_crud.py tests/test_v1_portfolios_trades.py
45 passed, 8 warnings in 5.63s
exit_code=0

AC mapping

AC area Evidence
Existing /ledger/trades remains service-token broker write tests/test_v1_portfolios_trades.py included in targeted regression; existing tests pass
Manual endpoint owner-scoped user/session only test_manual_write_rejects_service_token, test_owner_mismatch_returns_403
Manual BUY effect + after-snapshot test_manual_buy_updates_snapshot_and_returns_total_value_after
Insufficient cash/quantity/buffer conflict policy test_insufficient_cash_rejected_as_409 plus repository conflict mapping
daemon-managed confirmation test_daemon_managed_requires_confirmation_then_records_evidence
PROFIT vs WITHDRAW return semantics test_profit_is_exposed_separately_from_net_contributed_capital
Manual history includes total_value_after test_manual_history_returns_total_value_after
Regression: CRUD/list/trades unaffected Full regression 590 passed; targeted CRUD/trades pass

QC FAIL remediation evidence

The first independent QC run against the pre-amend implementation found three blockers; all were fixed before this verification snapshot:

  • Admin session tokens no longer bypass owner scope for manual write/history/return summary endpoints.
  • Amount/reversal actions reject explicit fee/tax fields with HTTP 422.
  • REVERSAL target-not-found now maps to HTTP 404 LEDGER_ENTRY_NOT_FOUND.

Added regression coverage in tests/test_v1_portfolios_manual_ledger.py:

  • test_admin_session_does_not_bypass_manual_owner_scope
  • test_admin_session_does_not_bypass_manual_read_owner_scope
  • test_amount_actions_reject_fee_and_tax_fields
  • test_reversal_rejects_fee_tax_and_missing_target

Notes / follow-up risks

  • The implementation adds additive bootstrap columns via ensure_schema() for portfolio_ledger: source, target_ledger_entry_id, confirmation_evidence, actor_user_id.
  • No Alembic migration file was added in this batch. Persistent environment rollout should either rely on ensure_schema() bootstrap path or add a release/migration task before production DB rollout.
  • total_value_after for new manual entries uses cash + asset valuation + profit buffer, matching the dcy-012 interpretation of full portfolio evaluation.