feat(REQ-005): implement TrEx Basic V1 API contract with auth, assets, ledger, and user endpoints

- Add V1 API routes for assets, ledger, and user info with complete CRUD operations
- Implement authentication scopes and request validation via auth_routes.py
- Extend schemas with V1-specific models for accounts, holdings, and positions
- Add database queries and aggregations for P&L, performance, and account data
- Include comprehensive test coverage for all V1 endpoints and integration flows
- Update batch and release documentation with implementation and verification evidence
- Sync project structure and runtime flows per V1 API contract requirements

Closes implementation phase of BAT-001 (TrEx Basic V1 API Contract)
This commit is contained in:
2026-05-02 11:37:42 +00:00
parent ce63c75c9c
commit 3509606c7e
17 changed files with 1159 additions and 124 deletions
+26 -15
View File
@@ -4,7 +4,7 @@ from __future__ import annotations
from datetime import datetime
from decimal import Decimal
from typing import Literal
from typing import Any, Literal
from pydantic import BaseModel, Field
@@ -15,21 +15,22 @@ from pydantic import BaseModel, Field
class AssetItem(BaseModel):
asset_id: str
broker: str
market: str | None = None
symbol: str
name: str
market: str | None = None
status: str
cash_balance: float
asset_quantity: float
price: float
profit_buffer: float
active_strategy_id: str | None = None
available_strategies: list[str] | None = None
cash: float
quantity: float
broker_type: str
strategy_id: str | None = None
strategy_params: dict[str, Any] = {}
updated_at: datetime | None = None
# Additional informational fields
name: str | None = None
price: float | None = None
profit_buffer: float | None = None
tags: list[str] | None = None
owner_user_id: str | None = None
created_at: datetime | None = None
updated_at: datetime | None = None
last_trade_at: datetime | None = None
@@ -42,14 +43,24 @@ class AssetsResponse(BaseModel):
# GET /v1/user_info
# ---------------------------------------------------------------------------
class BrokerItem(BaseModel):
broker: str
account_ref: str
credential_payload: dict[str, Any] | None = None
credential_version: int = 1
last_rotated_at: datetime | None = None
class UserInfoResponse(BaseModel):
runtime_id: str
trading_enabled: bool
disabled_reason: str | None = None
brokers: list[BrokerItem] = []
# Additional informational fields
user_id: str
username: str
email: str | None = None
permission: str
is_active: bool
disabled_reason: str | None = None
runtime_id: str
# ---------------------------------------------------------------------------
@@ -79,4 +90,4 @@ class LedgerTradeResponse(BaseModel):
tax_amount: float
executed_at: datetime
recorded_at: datetime | None = None
created: bool
status: Literal["new", "duplicate"] = "new"