- build.py: _TEMPLATE_COMPONENTS rewritten around the vet sample (53 kinds —
per-resource slices, jobs, worked appointment_reminder family, tests);
seed tokens dropped from the manifest ('sample: vet' instead)
- registry.py: get_app_component(kind) no longer renames item/example seeds;
prompts and tool docs updated to 'copy a slice and adapt'
- templates/README.md, 01_build_recipe, 40_ui_admin, wiki/03 updated off the
old seed scheme; repo inventory/config now exclude vet (docs move under
standards; react/vet itself is deleted in a later phase)
- regenerated MCP bundle, vendored templates, and site output
95 lines
2.6 KiB
Python
95 lines
2.6 KiB
Python
"""# Summary
|
|
|
|
Jobs route handlers — names must match openapi.yaml operationIds.
|
|
"""
|
|
from fastapi import Request, Response
|
|
|
|
from interfaces._common import delete_or_404, dump, paginate, read_or_404, svc
|
|
|
|
|
|
async def list_jobs(request: Request, limit: int = 20, offset: int = 0, status: str | None = None) -> dict:
|
|
"""List jobs (paginated, optionally filtered by status).
|
|
|
|
Args:
|
|
request (Request): Incoming request.
|
|
limit (int): Page size. Defaults to 20.
|
|
offset (int): Items to skip. Defaults to 0.
|
|
status (str | None): Filter by status (pending/processing/done/failed).
|
|
|
|
Returns:
|
|
dict: ``{"total": int, "items": list[Job]}``.
|
|
"""
|
|
docs = await svc(request, "job").search({})
|
|
items = [dump(d) for d in docs]
|
|
if status:
|
|
items = [row for row in items if row.get("status") == status]
|
|
return paginate(items, limit, offset)
|
|
|
|
|
|
async def create_job(request: Request, body: dict, response: Response) -> dict:
|
|
"""Create a job.
|
|
|
|
Args:
|
|
request (Request): Incoming request.
|
|
body (dict): Job fields (``id`` ignored).
|
|
response (Response): Response object; set to 201 on success.
|
|
|
|
Returns:
|
|
dict: The created job.
|
|
"""
|
|
response.status_code = 201
|
|
body.pop("id", None)
|
|
doc = await svc(request, "job").create(body)
|
|
return dump(doc)
|
|
|
|
|
|
async def get_job(request: Request, id: int) -> dict:
|
|
"""Fetch one job by id.
|
|
|
|
Args:
|
|
request (Request): Incoming request.
|
|
id (int): Job identifier.
|
|
|
|
Returns:
|
|
dict: The job document.
|
|
|
|
Raises:
|
|
HTTPException: 404 when the job does not exist.
|
|
"""
|
|
return dump(await read_or_404(svc(request, "job"), id, "job"))
|
|
|
|
|
|
async def update_job(request: Request, id: int, body: dict) -> dict:
|
|
"""Replace a job by id.
|
|
|
|
Args:
|
|
request (Request): Incoming request.
|
|
id (int): Job identifier.
|
|
body (dict): Full replacement payload.
|
|
|
|
Returns:
|
|
dict: The updated job.
|
|
|
|
Raises:
|
|
HTTPException: 404 when the job does not exist.
|
|
"""
|
|
await read_or_404(svc(request, "job"), id, "job")
|
|
body.pop("id", None)
|
|
doc = await svc(request, "job").update(id, body)
|
|
return dump(doc)
|
|
|
|
|
|
async def delete_job(request: Request, id: int, response: Response) -> None:
|
|
"""Delete a job by id.
|
|
|
|
Args:
|
|
request (Request): Incoming request.
|
|
id (int): Job identifier.
|
|
response (Response): Response object; set to 204 on success.
|
|
|
|
Raises:
|
|
HTTPException: 404 when the job does not exist.
|
|
"""
|
|
await delete_or_404(svc(request, "job"), id, "job")
|
|
response.status_code = 204
|