64 lines
2.4 KiB
Python
64 lines
2.4 KiB
Python
from uuid import uuid4
|
|
|
|
from fastapi import APIRouter, HTTPException
|
|
|
|
from app.db import fetch_project_or_404, get_conn, utcnow
|
|
from app.models import Project, ProjectCreate, ProjectUpdate
|
|
|
|
router = APIRouter(prefix="/projects", tags=["projects"])
|
|
|
|
|
|
@router.post("", response_model=Project, status_code=201)
|
|
def create_project(payload: ProjectCreate) -> Project:
|
|
if not payload.name.strip():
|
|
raise HTTPException(status_code=400, detail="name is required")
|
|
now = utcnow()
|
|
record = {
|
|
"id": str(uuid4()),
|
|
"name": payload.name.strip(),
|
|
"external_ref": payload.external_ref,
|
|
"created_at": now,
|
|
"updated_at": now,
|
|
}
|
|
with get_conn() as conn:
|
|
conn.execute(
|
|
"INSERT INTO projects (id, name, external_ref, created_at, updated_at) VALUES (%s, %s, %s, %s, %s)",
|
|
(record["id"], record["name"], record["external_ref"], record["created_at"], record["updated_at"]),
|
|
)
|
|
conn.commit()
|
|
return Project.model_validate(record)
|
|
|
|
|
|
@router.get("", response_model=list[Project])
|
|
def list_projects() -> list[Project]:
|
|
with get_conn() as conn:
|
|
rows = conn.execute(
|
|
"SELECT id, name, external_ref, created_at, updated_at FROM projects ORDER BY created_at ASC"
|
|
).fetchall()
|
|
return [Project.model_validate(row) for row in rows]
|
|
|
|
|
|
@router.get("/{project_id}", response_model=Project)
|
|
def get_project(project_id: str) -> Project:
|
|
with get_conn() as conn:
|
|
return Project.model_validate(fetch_project_or_404(conn, project_id))
|
|
|
|
|
|
@router.patch("/{project_id}", response_model=Project)
|
|
def update_project(project_id: str, payload: ProjectUpdate) -> Project:
|
|
with get_conn() as conn:
|
|
current = fetch_project_or_404(conn, project_id)
|
|
if payload.name is not None:
|
|
if not payload.name.strip():
|
|
raise HTTPException(status_code=400, detail="name cannot be empty")
|
|
current["name"] = payload.name.strip()
|
|
if payload.external_ref is not None:
|
|
current["external_ref"] = payload.external_ref
|
|
current["updated_at"] = utcnow()
|
|
conn.execute(
|
|
"UPDATE projects SET name = %s, external_ref = %s, updated_at = %s WHERE id = %s",
|
|
(current["name"], current["external_ref"], current["updated_at"], project_id),
|
|
)
|
|
conn.commit()
|
|
return Project.model_validate(current)
|