feat(validation): complete validation editor and master data modules

This commit is contained in:
Schubert Ferenc 2026-07-10 22:42:03 +02:00
parent 2b5c765e41
commit f73a24df13
73 changed files with 10194 additions and 0 deletions

View file

@ -0,0 +1,216 @@
from __future__ import annotations
from typing import Any
from fastapi import APIRouter, Depends, Query, Response
from sqlalchemy import func, select
from sqlalchemy.orm import Session
from app.api.dependencies import current_user
from app.db.session import get_session
from app.models.contact import Contact
from app.models.customer import Customer
from app.models.device import Device
from app.models.equipment import Equipment
from app.models.location import Location
from app.models.validation import Validation
from app.schemas.common import PaginatedResponse
from app.schemas.domain import (
ContactCreate,
ContactRead,
ContactUpdate,
CustomerCreate,
CustomerRead,
CustomerUpdate,
DeviceCreate,
DeviceRead,
DeviceUpdate,
EquipmentCreate,
EquipmentRead,
EquipmentUpdate,
LocationCreate,
LocationRead,
LocationUpdate,
ValidationCreate,
ValidationRead,
ValidationUpdate,
)
from app.services.domain_service import CrudService, DomainServices
router = APIRouter(tags=["domain"], dependencies=[Depends(current_user)])
@router.get("/dashboard")
def dashboard(session: Session = Depends(get_session)) -> dict[str, int]:
return {
"customers": session.scalar(select(func.count()).select_from(Customer)) or 0,
"locations": session.scalar(select(func.count()).select_from(Location)) or 0,
"contacts": session.scalar(select(func.count()).select_from(Contact)) or 0,
"devices": session.scalar(select(func.count()).select_from(Device)) or 0,
"equipment": session.scalar(select(func.count()).select_from(Equipment)) or 0,
"validations": session.scalar(select(func.count()).select_from(Validation)) or 0,
}
def paging(
page: int = Query(default=1, ge=1),
page_size: int = Query(default=20, ge=1, le=100),
search: str | None = Query(default=None, max_length=120),
) -> dict[str, Any]:
return {"page": page, "page_size": page_size, "search": search}
def commit_create(session: Session, service: CrudService, payload):
item = service.create(payload.model_dump())
session.commit()
session.refresh(item)
return item
def commit_update(session: Session, service: CrudService, item_id: str, payload):
item = service.update(item_id, payload.model_dump())
session.commit()
session.refresh(item)
return item
def commit_delete(session: Session, service: CrudService, item_id: str) -> Response:
service.delete(item_id)
session.commit()
return Response(status_code=204)
@router.get("/customers", response_model=PaginatedResponse[CustomerRead])
def list_customers(params: dict = Depends(paging), session: Session = Depends(get_session)):
return DomainServices(session).customers.list(**params)
@router.post("/customers", response_model=CustomerRead, status_code=201)
def create_customer(payload: CustomerCreate, session: Session = Depends(get_session)):
return commit_create(session, DomainServices(session).customers, payload)
@router.put("/customers/{item_id}", response_model=CustomerRead)
def update_customer(item_id: str, payload: CustomerUpdate, session: Session = Depends(get_session)):
return commit_update(session, DomainServices(session).customers, item_id, payload)
@router.delete("/customers/{item_id}", status_code=204)
def delete_customer(item_id: str, session: Session = Depends(get_session)):
return commit_delete(session, DomainServices(session).customers, item_id)
@router.get("/locations", response_model=PaginatedResponse[LocationRead])
def list_locations(params: dict = Depends(paging), session: Session = Depends(get_session)):
return DomainServices(session).locations.list(**params)
@router.post("/locations", response_model=LocationRead, status_code=201)
def create_location(payload: LocationCreate, session: Session = Depends(get_session)):
return commit_create(session, DomainServices(session).locations, payload)
@router.put("/locations/{item_id}", response_model=LocationRead)
def update_location(item_id: str, payload: LocationUpdate, session: Session = Depends(get_session)):
return commit_update(session, DomainServices(session).locations, item_id, payload)
@router.delete("/locations/{item_id}", status_code=204)
def delete_location(item_id: str, session: Session = Depends(get_session)):
return commit_delete(session, DomainServices(session).locations, item_id)
@router.get("/contacts", response_model=PaginatedResponse[ContactRead])
def list_contacts(params: dict = Depends(paging), session: Session = Depends(get_session)):
return DomainServices(session).contacts.list(**params)
@router.post("/contacts", response_model=ContactRead, status_code=201)
def create_contact(payload: ContactCreate, session: Session = Depends(get_session)):
return commit_create(session, DomainServices(session).contacts, payload)
@router.put("/contacts/{item_id}", response_model=ContactRead)
def update_contact(item_id: str, payload: ContactUpdate, session: Session = Depends(get_session)):
return commit_update(session, DomainServices(session).contacts, item_id, payload)
@router.delete("/contacts/{item_id}", status_code=204)
def delete_contact(item_id: str, session: Session = Depends(get_session)):
return commit_delete(session, DomainServices(session).contacts, item_id)
@router.get("/devices", response_model=PaginatedResponse[DeviceRead])
def list_devices(params: dict = Depends(paging), session: Session = Depends(get_session)):
return DomainServices(session).devices.list(**params)
@router.post("/devices", response_model=DeviceRead, status_code=201)
def create_device(payload: DeviceCreate, session: Session = Depends(get_session)):
return commit_create(session, DomainServices(session).devices, payload)
@router.put("/devices/{item_id}", response_model=DeviceRead)
def update_device(item_id: str, payload: DeviceUpdate, session: Session = Depends(get_session)):
return commit_update(session, DomainServices(session).devices, item_id, payload)
@router.delete("/devices/{item_id}", status_code=204)
def delete_device(item_id: str, session: Session = Depends(get_session)):
return commit_delete(session, DomainServices(session).devices, item_id)
@router.get("/equipment", response_model=PaginatedResponse[EquipmentRead])
def list_equipment(params: dict = Depends(paging), session: Session = Depends(get_session)):
return DomainServices(session).equipment.list(**params)
@router.post("/equipment", response_model=EquipmentRead, status_code=201)
def create_equipment(payload: EquipmentCreate, session: Session = Depends(get_session)):
return commit_create(session, DomainServices(session).equipment, payload)
@router.put("/equipment/{item_id}", response_model=EquipmentRead)
def update_equipment(item_id: str, payload: EquipmentUpdate, session: Session = Depends(get_session)):
return commit_update(session, DomainServices(session).equipment, item_id, payload)
@router.delete("/equipment/{item_id}", status_code=204)
def delete_equipment(item_id: str, session: Session = Depends(get_session)):
return commit_delete(session, DomainServices(session).equipment, item_id)
@router.get("/validations", response_model=PaginatedResponse[ValidationRead])
def list_validations(params: dict = Depends(paging), session: Session = Depends(get_session)):
return DomainServices(session).validations.list(**params)
@router.get("/validations/next-report-number")
def next_report_number(session: Session = Depends(get_session)) -> dict[str, str]:
count = session.scalar(select(func.count()).select_from(Validation)) or 0
return {"report_number": f"VAL-{count + 1:05d}"}
@router.get("/validations/{item_id}", response_model=ValidationRead)
def get_validation(item_id: str, session: Session = Depends(get_session)):
item = DomainServices(session).validations.repository.get(item_id)
if item is None:
from fastapi import HTTPException
raise HTTPException(status_code=404, detail="Resource not found")
return item
@router.post("/validations", response_model=ValidationRead, status_code=201)
def create_validation(payload: ValidationCreate, session: Session = Depends(get_session)):
return commit_create(session, DomainServices(session).validations, payload)
@router.put("/validations/{item_id}", response_model=ValidationRead)
def update_validation(item_id: str, payload: ValidationUpdate, session: Session = Depends(get_session)):
return commit_update(session, DomainServices(session).validations, item_id, payload)
@router.delete("/validations/{item_id}", status_code=204)
def delete_validation(item_id: str, session: Session = Depends(get_session)):
return commit_delete(session, DomainServices(session).validations, item_id)