feat: implement v1 consumer API endpoints with runtime_id support (REQ-004~010)
- Generate runtime_id for service-token issuance (CLI and API)
- Implement GET /v1/assets endpoint with asset view and strategy_params
- Implement GET /v1/user_info endpoint with trading_enabled and broker credentials
- Implement POST /v1/assets/{asset_id}/ledger/trades with idempotency support
- Update auth service to support runtime_id tracking and credential encryption
- Add comprehensive test coverage for v1 endpoints (dcy-002 implementation)
- Update postgres repository for ledger and broker credential queries
- Ensure all tests pass for feature validation
This commit is contained in:
@@ -38,7 +38,8 @@ _SELECT_AUTH_TOKEN = """
|
||||
expires_at,
|
||||
last_used_at,
|
||||
revoked_at,
|
||||
created_at
|
||||
created_at,
|
||||
runtime_id
|
||||
FROM auth_tokens
|
||||
"""
|
||||
|
||||
@@ -133,6 +134,7 @@ class PostgresPortfolioRepository:
|
||||
token_hash TEXT NOT NULL UNIQUE,
|
||||
permission TEXT NOT NULL,
|
||||
token_type TEXT NOT NULL,
|
||||
runtime_id TEXT,
|
||||
expires_at TIMESTAMPTZ,
|
||||
last_used_at TIMESTAMPTZ,
|
||||
revoked_at TIMESTAMPTZ,
|
||||
@@ -140,6 +142,7 @@ class PostgresPortfolioRepository:
|
||||
)
|
||||
"""
|
||||
)
|
||||
cur.execute("ALTER TABLE auth_tokens ADD COLUMN IF NOT EXISTS runtime_id TEXT")
|
||||
cur.execute(
|
||||
"""
|
||||
CREATE INDEX IF NOT EXISTS idx_auth_tokens_user_created
|
||||
@@ -300,6 +303,7 @@ class PostgresPortfolioRepository:
|
||||
last_used_at=row[7] if len(row) > 7 else None,
|
||||
revoked_at=row[8] if len(row) > 8 else None,
|
||||
created_at=row[9] if len(row) > 9 else None,
|
||||
runtime_id=row[10] if len(row) > 10 else None,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
@@ -532,6 +536,7 @@ class PostgresPortfolioRepository:
|
||||
permission: str,
|
||||
token_type: str,
|
||||
expires_at: datetime | None = None,
|
||||
runtime_id: str | None = None,
|
||||
) -> AuthToken:
|
||||
self.ensure_schema()
|
||||
with self._connect().cursor() as cur:
|
||||
@@ -542,14 +547,14 @@ class PostgresPortfolioRepository:
|
||||
cur.execute(
|
||||
"""
|
||||
INSERT INTO auth_tokens (
|
||||
id, user_id, name, token_prefix, token_hash, permission, token_type, expires_at
|
||||
id, user_id, name, token_prefix, token_hash, permission, token_type, expires_at, runtime_id
|
||||
)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)
|
||||
RETURNING
|
||||
id, user_id, name, token_prefix, permission, token_type,
|
||||
expires_at, last_used_at, revoked_at, created_at
|
||||
expires_at, last_used_at, revoked_at, created_at, runtime_id
|
||||
""",
|
||||
(token_id, user_id, name, token_prefix, token_hash, permission, token_type, expires_at),
|
||||
(token_id, user_id, name, token_prefix, token_hash, permission, token_type, expires_at, runtime_id),
|
||||
)
|
||||
row = cur.fetchone()
|
||||
return self._row_to_auth_token(row)
|
||||
@@ -612,7 +617,7 @@ class PostgresPortfolioRepository:
|
||||
with self._connect().cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
SELECT t.id, t.user_id, t.permission, t.token_type
|
||||
SELECT t.id, t.user_id, t.permission, t.token_type, t.runtime_id
|
||||
FROM auth_tokens t
|
||||
WHERE token_hash = %s
|
||||
AND t.revoked_at IS NULL
|
||||
@@ -629,6 +634,7 @@ class PostgresPortfolioRepository:
|
||||
user_id=row[1],
|
||||
permission=row[2],
|
||||
token_type=row[3],
|
||||
runtime_id=row[4] if len(row) > 4 else None,
|
||||
)
|
||||
|
||||
def get(self, portfolio_id: str) -> Portfolio:
|
||||
|
||||
Reference in New Issue
Block a user