mirror of
http://88.130.71.182:3000/BlitTech/badoHair_be.git
synced 2026-06-13 08:49:46 +00:00
89 lines
2.6 KiB
Python
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")
|