145 lines
4.3 KiB
Python
145 lines
4.3 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, Query
|
|
from sqlalchemy import text
|
|
from sqlalchemy.orm import Session
|
|
from typing import Any
|
|
|
|
from app.database import get_session
|
|
from app.auth import get_current_user
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
def _row(r) -> dict:
|
|
return dict(r._mapping)
|
|
|
|
|
|
@router.get("")
|
|
def list_checklists(
|
|
session: Session = Depends(get_session),
|
|
_: str = Depends(get_current_user),
|
|
) -> list[dict]:
|
|
rows = session.execute(text("SELECT * FROM checklists ORDER BY name")).fetchall()
|
|
return [_row(r) for r in rows]
|
|
|
|
|
|
@router.post("", status_code=201)
|
|
def create_checklist(
|
|
body: dict[str, Any],
|
|
session: Session = Depends(get_session),
|
|
_: str = Depends(get_current_user),
|
|
) -> dict:
|
|
row = session.execute(text("""
|
|
INSERT INTO checklists (name, scope) VALUES (:name, :scope) RETURNING *
|
|
"""), {"name": body.get("name"), "scope": body.get("scope", "colony")}).fetchone()
|
|
session.commit()
|
|
return _row(row)
|
|
|
|
|
|
@router.delete("/{id}", status_code=204)
|
|
def delete_checklist(
|
|
id: int,
|
|
session: Session = Depends(get_session),
|
|
_: str = Depends(get_current_user),
|
|
):
|
|
session.execute(text("DELETE FROM checklists WHERE id = :id"), {"id": id})
|
|
session.commit()
|
|
|
|
|
|
@router.get("/{id}/items")
|
|
def list_items(
|
|
id: int,
|
|
session: Session = Depends(get_session),
|
|
_: str = Depends(get_current_user),
|
|
) -> list[dict]:
|
|
rows = session.execute(text("""
|
|
SELECT * FROM checklist_items WHERE checklist_id = :id ORDER BY position
|
|
"""), {"id": id}).fetchall()
|
|
return [_row(r) for r in rows]
|
|
|
|
|
|
@router.post("/{id}/items", status_code=201)
|
|
def create_item(
|
|
id: int,
|
|
body: dict[str, Any],
|
|
session: Session = Depends(get_session),
|
|
_: str = Depends(get_current_user),
|
|
) -> dict:
|
|
row = session.execute(text("""
|
|
INSERT INTO checklist_items (checklist_id, text, position)
|
|
VALUES (:checklist_id, :text, :position) RETURNING *
|
|
"""), {
|
|
"checklist_id": id,
|
|
"text": body.get("text"),
|
|
"position": body.get("position", 0),
|
|
}).fetchone()
|
|
session.commit()
|
|
return _row(row)
|
|
|
|
|
|
@router.delete("/items/{item_id}", status_code=204)
|
|
def delete_item(
|
|
item_id: int,
|
|
session: Session = Depends(get_session),
|
|
_: str = Depends(get_current_user),
|
|
):
|
|
session.execute(text("DELETE FROM checklist_items WHERE id = :id"), {"id": item_id})
|
|
session.commit()
|
|
|
|
|
|
@router.get("/{id}/completions")
|
|
def list_completions(
|
|
id: int,
|
|
scope_id: int = Query(...),
|
|
session: Session = Depends(get_session),
|
|
_: str = Depends(get_current_user),
|
|
) -> list[dict]:
|
|
rows = session.execute(text("""
|
|
SELECT cc.*, ci.text, ci.position
|
|
FROM checklist_completions cc
|
|
JOIN checklist_items ci ON ci.id = cc.item_id
|
|
WHERE cc.checklist_id = :checklist_id AND cc.scope_id = :scope_id
|
|
ORDER BY ci.position
|
|
"""), {"checklist_id": id, "scope_id": scope_id}).fetchall()
|
|
return [_row(r) for r in rows]
|
|
|
|
|
|
@router.post("/{id}/completions/toggle")
|
|
def toggle_completion(
|
|
id: int,
|
|
body: dict[str, Any],
|
|
session: Session = Depends(get_session),
|
|
_: str = Depends(get_current_user),
|
|
) -> dict:
|
|
item_id = body.get("item_id")
|
|
scope_id = body.get("scope_id")
|
|
date = body.get("date")
|
|
completed_by = body.get("completed_by")
|
|
notes = body.get("notes")
|
|
|
|
existing = session.execute(text("""
|
|
SELECT id FROM checklist_completions
|
|
WHERE checklist_id = :checklist_id AND item_id = :item_id AND scope_id = :scope_id
|
|
"""), {"checklist_id": id, "item_id": item_id, "scope_id": scope_id}).fetchone()
|
|
|
|
if existing is not None:
|
|
session.execute(
|
|
text("DELETE FROM checklist_completions WHERE id = :id"),
|
|
{"id": existing._mapping["id"]},
|
|
)
|
|
session.commit()
|
|
return {"toggled": False}
|
|
else:
|
|
session.execute(text("""
|
|
INSERT INTO checklist_completions (checklist_id, item_id, scope_id, date, completed_by, notes)
|
|
VALUES (:checklist_id, :item_id, :scope_id, :date, :completed_by, :notes)
|
|
"""), {
|
|
"checklist_id": id,
|
|
"item_id": item_id,
|
|
"scope_id": scope_id,
|
|
"date": date,
|
|
"completed_by": completed_by,
|
|
"notes": notes,
|
|
})
|
|
session.commit()
|
|
return {"toggled": True}
|