Files
badoHair_be/app/routers/admin/services.py
belviskhoremk d2dc43b16f Initial Commit
2026-05-12 00:34:21 +00:00

89 lines
2.6 KiB
Python

from fastapi import APIRouter, Depends
from pydantic import BaseModel, Field
import asyncpg
from app.core.responses import ok
from app.dependencies import get_db, require_admin
from app.exceptions import NotFoundError
router = APIRouter(prefix="/services", tags=["Admin — Services"])
class ServiceCreate(BaseModel):
name: str = Field(min_length=1, max_length=120)
description: str | None = None
duration_minutes: int = Field(default=60, ge=5, le=480)
price: float = Field(default=0.0, ge=0)
is_active: bool = True
class ServiceUpdate(BaseModel):
name: str | None = Field(None, min_length=1, max_length=120)
description: str | None = None
duration_minutes: int | None = Field(None, ge=5, le=480)
price: float | None = Field(None, ge=0)
is_active: bool | None = None
@router.get("")
async def list_services(
db: asyncpg.Connection = Depends(get_db),
_: dict = Depends(require_admin),
):
rows = await db.fetch(
"SELECT * FROM services ORDER BY price ASC, name ASC"
)
return ok([dict(r) for r in rows])
@router.post("", status_code=201)
async def create_service(
body: ServiceCreate,
db: asyncpg.Connection = Depends(get_db),
_: dict = Depends(require_admin),
):
row = await db.fetchrow(
"""
INSERT INTO services (name, description, duration_minutes, price, is_active)
VALUES ($1, $2, $3, $4, $5)
RETURNING *
""",
body.name, body.description, body.duration_minutes, body.price, body.is_active,
)
return ok(dict(row))
@router.put("/{service_id}")
async def update_service(
service_id: str,
body: ServiceUpdate,
db: asyncpg.Connection = Depends(get_db),
_: dict = Depends(require_admin),
):
updates = {k: v for k, v in body.model_dump().items() if v is not None}
if not updates:
row = await db.fetchrow("SELECT * FROM services WHERE id = $1", service_id)
if not row:
raise NotFoundError("service")
return ok(dict(row))
set_clauses = [f"{k} = ${i + 2}" for i, k in enumerate(updates)]
row = await db.fetchrow(
f"UPDATE services SET {', '.join(set_clauses)}, updated_at = now() WHERE id = $1 RETURNING *",
service_id, *updates.values(),
)
if not row:
raise NotFoundError("service")
return ok(dict(row))
@router.delete("/{service_id}", status_code=204)
async def delete_service(
service_id: str,
db: asyncpg.Connection = Depends(get_db),
_: dict = Depends(require_admin),
):
result = await db.execute("DELETE FROM services WHERE id = $1", service_id)
if result == "DELETE 0":
raise NotFoundError("service")