"""Steering notes API — tune how Brain answers (phase 15, story ``steering-notes``). Stateless CRUD under ``/api/steering`` (A10): notes are owner instructions stored in Postgres (``steering_notes``) and read into the system prompt of **every** chat turn as the ```` section (see :func:`app.rag.prompts.build_steering_section` and :func:`app.api.chat.chat`). """ from __future__ import annotations import uuid from fastapi import APIRouter, Depends, HTTPException, Response from sqlalchemy import select from sqlalchemy.orm import Session from app.db import get_db from app.models import SteeringNote from app.schemas import SteeringNote as SteeringNoteOut from app.schemas import SteeringNoteIn, SteeringNoteList router = APIRouter(prefix="/steering", tags=["steering"]) def load_steering_notes(db: Session) -> list[str]: """All steering notes, oldest first (the order they are numbered in the ```` prompt section). Used by the chat turn (``app.api.chat``).""" rows = db.scalars( select(SteeringNote).order_by(SteeringNote.created_at.asc(), SteeringNote.id.asc()) ).all() return [row.note for row in rows] @router.get("", response_model=SteeringNoteList) def list_steering_notes( db: Session = Depends(get_db), # noqa: B008 ) -> SteeringNoteList: """All notes, newest first (the UI panel's display order).""" rows = db.scalars( select(SteeringNote).order_by(SteeringNote.created_at.desc(), SteeringNote.id.desc()) ).all() return SteeringNoteList( notes=[ SteeringNoteOut(id=row.id, note=row.note, created_at=row.created_at) for row in rows ] ) @router.post("", response_model=SteeringNoteOut, status_code=201) def create_steering_note( payload: SteeringNoteIn, db: Session = Depends(get_db), # noqa: B008 ) -> SteeringNoteOut: """Store one tuning instruction (trimmed, 1–2000 chars — 422 otherwise).""" row = SteeringNote(note=payload.note) db.add(row) db.commit() db.refresh(row) return SteeringNoteOut(id=row.id, note=row.note, created_at=row.created_at) @router.delete("/{note_id}", status_code=204) def delete_steering_note( note_id: uuid.UUID, db: Session = Depends(get_db), # noqa: B008 ) -> Response: """Remove a note; 404 when the id is unknown.""" row = db.get(SteeringNote, note_id) if row is None: raise HTTPException(status_code=404, detail="steering note not found") db.delete(row) db.commit() return Response(status_code=204)