Files
local-mcp/app/api/routes_instructions.py
cabbage 256a445e2f feat: add Clear History button to delete all consumed instructions
- Backend: instruction_service.clear_consumed() bulk-deletes consumed rows
- Backend: DELETE /api/instructions/consumed route (preserves pending)
- Frontend: Clear button in consumed panel header (hidden when empty)
- Frontend: SSE handler for history.cleared event - instant UI update
- Frontend: api.clearConsumed() fetch wrapper
2026-03-27 04:16:24 +08:00

81 lines
2.5 KiB
Python

"""
app/api/routes_instructions.py
HTTP endpoints for instruction CRUD.
"""
from __future__ import annotations
import logging
from fastapi import APIRouter, HTTPException, Query
from fastapi.responses import Response
from app.models import (
CreateInstructionRequest,
InstructionCreateResponse,
InstructionListResponse,
UpdateInstructionRequest,
)
from app.services import event_service, instruction_service
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/api/instructions", tags=["instructions"])
@router.get("", response_model=InstructionListResponse)
def list_instructions(
status: str = Query(default="all", pattern="^(pending|consumed|all)$")
):
items = instruction_service.list_instructions(status_filter=status)
return InstructionListResponse(items=items)
@router.post("", response_model=InstructionCreateResponse, status_code=201)
def create_instruction(body: CreateInstructionRequest):
item = instruction_service.create_instruction(body.content)
event_service.broadcast(
"instruction.created",
{"item": item.model_dump(mode="json")},
)
return InstructionCreateResponse(item=item)
@router.patch("/{instruction_id}", response_model=InstructionCreateResponse)
def update_instruction(instruction_id: str, body: UpdateInstructionRequest):
try:
item = instruction_service.update_instruction(instruction_id, body.content)
except KeyError:
raise HTTPException(status_code=404, detail="Instruction not found")
except PermissionError as exc:
raise HTTPException(status_code=409, detail=str(exc))
event_service.broadcast(
"instruction.updated",
{"item": item.model_dump(mode="json")},
)
return InstructionCreateResponse(item=item)
@router.delete("/consumed", status_code=200)
def clear_consumed_instructions():
"""Delete all consumed instructions. Pending instructions are never affected."""
count = instruction_service.clear_consumed()
event_service.broadcast("history.cleared", {"count": count})
return {"cleared": count}
@router.delete("/{instruction_id}", status_code=204)
def delete_instruction(instruction_id: str):
try:
instruction_service.delete_instruction(instruction_id)
except KeyError:
raise HTTPException(status_code=404, detail="Instruction not found")
except PermissionError as exc:
raise HTTPException(status_code=409, detail=str(exc))
event_service.broadcast("instruction.deleted", {"id": instruction_id})
return Response(status_code=204)