refactor: fix architectural issues across frontend and backend
Address all architecture review findings: P0 fixes: - Add API key authentication for admin endpoints (analytics, replay, openapi) and WebSocket connections via ADMIN_API_KEY env var - Add PostgreSQL-backed PgSessionManager and PgInterruptManager for multi-worker production deployments (in-memory defaults preserved) P1 fixes: - Implement actual tool generation in OpenAPI approve_job endpoint using generate_tool_code() and generate_agent_yaml() - Add missing clarification, interrupt_expired, and tool_result message handlers in frontend ChatPage P2 fixes: - Replace monkey-patching on CompiledStateGraph with typed GraphContext - Replace 9-param dispatch_message with WebSocketContext dataclass - Extract duplicate _envelope() into shared app/api_utils.py - Replace mutable module-level counter with crypto.randomUUID() - Remove hardcoded mock data from ReviewPage, use api.ts wrappers - Remove `as any` type escape from ReplayPage All 516 tests passing, 0 TypeScript errors.
This commit is contained in:
@@ -3,16 +3,23 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from typing import TYPE_CHECKING, Annotated, Any
|
||||
from typing import TYPE_CHECKING, Annotated
|
||||
|
||||
from fastapi import APIRouter, HTTPException, Query, Request
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query, Request
|
||||
|
||||
from app.api_utils import envelope
|
||||
from app.auth import require_admin_api_key
|
||||
|
||||
_THREAD_ID_PATTERN = re.compile(r"^[a-zA-Z0-9\-_]{1,128}$")
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from psycopg_pool import AsyncConnectionPool
|
||||
|
||||
router = APIRouter(prefix="/api", tags=["replay"])
|
||||
router = APIRouter(
|
||||
prefix="/api",
|
||||
tags=["replay"],
|
||||
dependencies=[Depends(require_admin_api_key)],
|
||||
)
|
||||
|
||||
_COUNT_CONVERSATIONS_SQL = """
|
||||
SELECT COUNT(*) FROM conversations
|
||||
@@ -38,10 +45,6 @@ async def get_pool(request: Request) -> AsyncConnectionPool:
|
||||
return request.app.state.pool
|
||||
|
||||
|
||||
def _envelope(data: Any, *, success: bool = True, error: str | None = None) -> dict:
|
||||
return {"success": success, "data": data, "error": error}
|
||||
|
||||
|
||||
@router.get("/conversations")
|
||||
async def list_conversations(
|
||||
request: Request,
|
||||
@@ -62,7 +65,7 @@ async def list_conversations(
|
||||
)
|
||||
rows = await cursor.fetchall()
|
||||
|
||||
return _envelope({
|
||||
return envelope({
|
||||
"conversations": [dict(row) for row in rows],
|
||||
"total": total,
|
||||
"page": page,
|
||||
@@ -119,4 +122,4 @@ async def get_replay(
|
||||
for s in page_steps
|
||||
],
|
||||
}
|
||||
return _envelope(data)
|
||||
return envelope(data)
|
||||
|
||||
Reference in New Issue
Block a user