feat(auth): single-admin password login (signed cookie) — gate tuning + Sources catalog, keep chat and document viewer public

This commit is contained in:
2026-08-23 19:58:39 -04:00
parent fc0d9a2d5c
commit cbc263a4b2
46 changed files with 1555 additions and 691 deletions
+14 -6
View File
@@ -1,11 +1,14 @@
"""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 ``<tuning>`` section (see
:func:`app.rag.prompts.build_steering_section` and
:func:`app.api.chat.chat`).
Admin-only CRUD under ``/api/steering`` (phase 16, A10 revised): notes
are owner instructions stored in Postgres (``steering_notes``) and read
into the system prompt of **every** chat turn as the ``<tuning>`` section
(see :func:`app.rag.prompts.build_steering_section` and
:func:`app.api.chat.chat`). The whole router sits behind
:func:`app.core.auth.require_admin` — anonymous callers get 403 on every
steering route (the chat turn itself reads the table in-process and
stays public).
"""
from __future__ import annotations
@@ -15,12 +18,17 @@ from fastapi import APIRouter, Depends, HTTPException, Response
from sqlalchemy import select
from sqlalchemy.orm import Session
from app.core.auth import require_admin
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"])
router = APIRouter(
prefix="/steering",
tags=["steering"],
dependencies=[Depends(require_admin)], # phase 16: tuning is admin-only
)
def load_steering_notes(db: Session) -> list[str]: