Law/app/api/admin/config.py
2026-02-22 10:57:49 +03:00

182 lines
6.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from sqlalchemy.exc import IntegrityError
from app.db.session import get_db
from app.core.deps import require_role
from app.schemas.universal import UniversalQuery
from app.schemas.admin import TopicUpsert, StatusUpsert, FormFieldUpsert
from app.models.topic import Topic
from app.models.status import Status
from app.models.form_field import FormField
from app.services.universal_query import apply_universal_query
router = APIRouter()
def _topic_row(row: Topic):
return {"id": str(row.id), "code": row.code, "name": row.name, "enabled": row.enabled, "sort_order": row.sort_order}
def _status_row(row: Status):
return {
"id": str(row.id),
"code": row.code,
"name": row.name,
"enabled": row.enabled,
"sort_order": row.sort_order,
"is_terminal": row.is_terminal,
}
def _form_field_row(row: FormField):
return {
"id": str(row.id),
"key": row.key,
"label": row.label,
"type": row.type,
"required": row.required,
"enabled": row.enabled,
"sort_order": row.sort_order,
"options": row.options,
}
@router.post("/topics/query")
def query_topics(uq: UniversalQuery, db: Session = Depends(get_db), admin=Depends(require_role("ADMIN"))):
q = apply_universal_query(db.query(Topic), Topic, uq)
total = q.count()
rows = q.offset(uq.page.offset).limit(uq.page.limit).all()
return {"rows": [_topic_row(r) for r in rows], "total": total}
@router.post("/topics", status_code=201)
def create_topic(payload: TopicUpsert, db: Session = Depends(get_db), admin=Depends(require_role("ADMIN"))):
row = Topic(**payload.model_dump())
try:
db.add(row)
db.commit()
db.refresh(row)
except IntegrityError:
db.rollback()
raise HTTPException(status_code=400, detail="Тема с таким кодом уже существует")
return _topic_row(row)
@router.patch("/topics/{id}")
def update_topic(id: str, payload: TopicUpsert, db: Session = Depends(get_db), admin=Depends(require_role("ADMIN"))):
row = db.query(Topic).filter(Topic.id == id).first()
if not row:
raise HTTPException(status_code=404, detail="Тема не найдена")
for k, v in payload.model_dump().items():
setattr(row, k, v)
try:
db.add(row)
db.commit()
db.refresh(row)
except IntegrityError:
db.rollback()
raise HTTPException(status_code=400, detail="Тема с таким кодом уже существует")
return _topic_row(row)
@router.delete("/topics/{id}")
def delete_topic(id: str, db: Session = Depends(get_db), admin=Depends(require_role("ADMIN"))):
row = db.query(Topic).filter(Topic.id == id).first()
if not row:
raise HTTPException(status_code=404, detail="Тема не найдена")
db.delete(row)
db.commit()
return {"status": "удалено"}
@router.post("/statuses/query")
def query_statuses(uq: UniversalQuery, db: Session = Depends(get_db), admin=Depends(require_role("ADMIN"))):
q = apply_universal_query(db.query(Status), Status, uq)
total = q.count()
rows = q.offset(uq.page.offset).limit(uq.page.limit).all()
return {"rows": [_status_row(r) for r in rows], "total": total}
@router.post("/statuses", status_code=201)
def create_status(payload: StatusUpsert, db: Session = Depends(get_db), admin=Depends(require_role("ADMIN"))):
row = Status(**payload.model_dump())
try:
db.add(row)
db.commit()
db.refresh(row)
except IntegrityError:
db.rollback()
raise HTTPException(status_code=400, detail="Статус с таким кодом уже существует")
return _status_row(row)
@router.patch("/statuses/{id}")
def update_status(id: str, payload: StatusUpsert, db: Session = Depends(get_db), admin=Depends(require_role("ADMIN"))):
row = db.query(Status).filter(Status.id == id).first()
if not row:
raise HTTPException(status_code=404, detail="Статус не найден")
for k, v in payload.model_dump().items():
setattr(row, k, v)
try:
db.add(row)
db.commit()
db.refresh(row)
except IntegrityError:
db.rollback()
raise HTTPException(status_code=400, detail="Статус с таким кодом уже существует")
return _status_row(row)
@router.delete("/statuses/{id}")
def delete_status(id: str, db: Session = Depends(get_db), admin=Depends(require_role("ADMIN"))):
row = db.query(Status).filter(Status.id == id).first()
if not row:
raise HTTPException(status_code=404, detail="Статус не найден")
db.delete(row)
db.commit()
return {"status": "удалено"}
@router.post("/form-fields/query")
def query_form_fields(uq: UniversalQuery, db: Session = Depends(get_db), admin=Depends(require_role("ADMIN"))):
q = apply_universal_query(db.query(FormField), FormField, uq)
total = q.count()
rows = q.offset(uq.page.offset).limit(uq.page.limit).all()
return {"rows": [_form_field_row(r) for r in rows], "total": total}
@router.post("/form-fields", status_code=201)
def create_form_field(payload: FormFieldUpsert, db: Session = Depends(get_db), admin=Depends(require_role("ADMIN"))):
row = FormField(**payload.model_dump())
try:
db.add(row)
db.commit()
db.refresh(row)
except IntegrityError:
db.rollback()
raise HTTPException(status_code=400, detail="Поле формы с таким ключом уже существует")
return _form_field_row(row)
@router.patch("/form-fields/{id}")
def update_form_field(id: str, payload: FormFieldUpsert, db: Session = Depends(get_db), admin=Depends(require_role("ADMIN"))):
row = db.query(FormField).filter(FormField.id == id).first()
if not row:
raise HTTPException(status_code=404, detail="Поле формы не найдено")
for k, v in payload.model_dump().items():
setattr(row, k, v)
try:
db.add(row)
db.commit()
db.refresh(row)
except IntegrityError:
db.rollback()
raise HTTPException(status_code=400, detail="Поле формы с таким ключом уже существует")
return _form_field_row(row)
@router.delete("/form-fields/{id}")
def delete_form_field(id: str, db: Session = Depends(get_db), admin=Depends(require_role("ADMIN"))):
row = db.query(FormField).filter(FormField.id == id).first()
if not row:
raise HTTPException(status_code=404, detail="Поле формы не найдено")
db.delete(row)
db.commit()
return {"status": "удалено"}