feat: unify card runtime and event-driven web ui
This commit is contained in:
parent
0edf8c3fef
commit
4dfb7ca3cc
105 changed files with 17382 additions and 8505 deletions
103
routes/workbench.py
Normal file
103
routes/workbench.py
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from fastapi import APIRouter, Depends, Request
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from app_dependencies import get_runtime
|
||||
from card_store import normalize_card_id
|
||||
from route_helpers import read_json_request
|
||||
from session_store import normalize_session_chat_id
|
||||
from web_runtime import WebAppRuntime
|
||||
from workbench_store import (
|
||||
delete_workbench_item,
|
||||
load_workbench_items,
|
||||
persist_workbench_item,
|
||||
promote_workbench_item,
|
||||
)
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/workbench")
|
||||
async def get_workbench(request: Request) -> JSONResponse:
|
||||
chat_id = normalize_session_chat_id(str(request.query_params.get("chat_id", "web") or "web"))
|
||||
if not chat_id:
|
||||
return JSONResponse({"error": "invalid chat id"}, status_code=400)
|
||||
try:
|
||||
items = load_workbench_items(chat_id)
|
||||
except ValueError as exc:
|
||||
return JSONResponse({"error": str(exc)}, status_code=400)
|
||||
except Exception as exc:
|
||||
return JSONResponse({"error": f"failed to load workbench: {exc}"}, status_code=500)
|
||||
return JSONResponse({"items": items})
|
||||
|
||||
|
||||
@router.post("/workbench")
|
||||
async def upsert_workbench(
|
||||
request: Request,
|
||||
runtime: WebAppRuntime = Depends(get_runtime),
|
||||
) -> JSONResponse:
|
||||
try:
|
||||
payload = await read_json_request(request)
|
||||
except ValueError as exc:
|
||||
return JSONResponse({"error": str(exc)}, status_code=400)
|
||||
|
||||
item = persist_workbench_item(payload)
|
||||
if item is None:
|
||||
return JSONResponse({"error": "invalid workbench payload"}, status_code=400)
|
||||
await runtime.publish_workbench_changed(item.get("chat_id"))
|
||||
return JSONResponse({"status": "ok", "item": item}, status_code=201)
|
||||
|
||||
|
||||
@router.delete("/workbench/{item_id}")
|
||||
async def delete_workbench(
|
||||
item_id: str,
|
||||
request: Request,
|
||||
runtime: WebAppRuntime = Depends(get_runtime),
|
||||
) -> JSONResponse:
|
||||
chat_id = normalize_session_chat_id(str(request.query_params.get("chat_id", "web") or "web"))
|
||||
if not chat_id:
|
||||
return JSONResponse({"error": "invalid chat id"}, status_code=400)
|
||||
if not normalize_card_id(item_id):
|
||||
return JSONResponse({"error": "invalid workbench item id"}, status_code=400)
|
||||
try:
|
||||
removed = delete_workbench_item(chat_id, item_id)
|
||||
except ValueError as exc:
|
||||
return JSONResponse({"error": str(exc)}, status_code=400)
|
||||
except Exception as exc:
|
||||
return JSONResponse({"error": f"failed to delete workbench item: {exc}"}, status_code=500)
|
||||
if not removed:
|
||||
return JSONResponse({"error": "workbench item not found"}, status_code=404)
|
||||
await runtime.publish_workbench_changed(chat_id)
|
||||
return JSONResponse({"status": "ok", "item_id": item_id})
|
||||
|
||||
|
||||
@router.post("/workbench/{item_id}/promote")
|
||||
async def promote_workbench(
|
||||
item_id: str,
|
||||
request: Request,
|
||||
runtime: WebAppRuntime = Depends(get_runtime),
|
||||
) -> JSONResponse:
|
||||
try:
|
||||
payload = await read_json_request(request)
|
||||
except ValueError:
|
||||
payload = {}
|
||||
|
||||
chat_id = normalize_session_chat_id(str(payload.get("chat_id", "web") or "web"))
|
||||
if not chat_id:
|
||||
return JSONResponse({"error": "invalid chat id"}, status_code=400)
|
||||
if not normalize_card_id(item_id):
|
||||
return JSONResponse({"error": "invalid workbench item id"}, status_code=400)
|
||||
try:
|
||||
card = promote_workbench_item(chat_id, item_id)
|
||||
except FileNotFoundError:
|
||||
return JSONResponse({"error": "workbench item not found"}, status_code=404)
|
||||
except ValueError as exc:
|
||||
return JSONResponse({"error": str(exc)}, status_code=400)
|
||||
except RuntimeError as exc:
|
||||
return JSONResponse({"error": str(exc)}, status_code=500)
|
||||
except Exception as exc:
|
||||
return JSONResponse({"error": f"failed to promote workbench item: {exc}"}, status_code=500)
|
||||
await runtime.publish_workbench_changed(chat_id)
|
||||
await runtime.publish_cards_changed(card.get("chat_id"))
|
||||
return JSONResponse({"status": "ok", "card": card, "item_id": item_id})
|
||||
Loading…
Add table
Add a link
Reference in a new issue