69 lines
2.5 KiB
Python
69 lines
2.5 KiB
Python
"""FluentGerman.ai — Instruction management router (admin only)."""
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from sqlalchemy import select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.auth import require_admin
|
|
from app.database import get_db
|
|
from app.models import Instruction, InstructionType
|
|
from app.schemas import InstructionCreate, InstructionOut, InstructionUpdate
|
|
|
|
router = APIRouter(prefix="/api/instructions", tags=["instructions"], dependencies=[Depends(require_admin)])
|
|
|
|
|
|
@router.get("/", response_model=list[InstructionOut])
|
|
async def list_instructions(user_id: int | None = None, db: AsyncSession = Depends(get_db)):
|
|
query = select(Instruction).order_by(Instruction.created_at.desc())
|
|
if user_id is not None:
|
|
# Fetch per-user + global instructions
|
|
query = query.where((Instruction.user_id == user_id) | Instruction.user_id.is_(None))
|
|
result = await db.execute(query)
|
|
return result.scalars().all()
|
|
|
|
|
|
@router.post("/", response_model=InstructionOut, status_code=status.HTTP_201_CREATED)
|
|
async def create_instruction(body: InstructionCreate, db: AsyncSession = Depends(get_db)):
|
|
instruction = Instruction(
|
|
user_id=body.user_id,
|
|
title=body.title,
|
|
content=body.content,
|
|
type=InstructionType(body.type),
|
|
)
|
|
db.add(instruction)
|
|
await db.commit()
|
|
await db.refresh(instruction)
|
|
return instruction
|
|
|
|
|
|
@router.put("/{instruction_id}", response_model=InstructionOut)
|
|
async def update_instruction(
|
|
instruction_id: int, body: InstructionUpdate, db: AsyncSession = Depends(get_db)
|
|
):
|
|
result = await db.execute(select(Instruction).where(Instruction.id == instruction_id))
|
|
inst = result.scalar_one_or_none()
|
|
if not inst:
|
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Instruction not found")
|
|
|
|
if body.title is not None:
|
|
inst.title = body.title
|
|
if body.content is not None:
|
|
inst.content = body.content
|
|
if body.type is not None:
|
|
inst.type = InstructionType(body.type)
|
|
|
|
await db.commit()
|
|
await db.refresh(inst)
|
|
return inst
|
|
|
|
|
|
@router.delete("/{instruction_id}", status_code=status.HTTP_204_NO_CONTENT)
|
|
async def delete_instruction(instruction_id: int, db: AsyncSession = Depends(get_db)):
|
|
result = await db.execute(select(Instruction).where(Instruction.id == instruction_id))
|
|
inst = result.scalar_one_or_none()
|
|
if not inst:
|
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Instruction not found")
|
|
|
|
await db.delete(inst)
|
|
await db.commit()
|