81 lines
2.7 KiB
Python
81 lines
2.7 KiB
Python
from __future__ import annotations
|
|
|
|
import uuid
|
|
from typing import Literal
|
|
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.core.errors import AppError
|
|
from app.models import Project
|
|
from app.schemas.project import ProjectCreate, ProjectRead, ProjectUpdate
|
|
|
|
|
|
class ProjectService:
|
|
@staticmethod
|
|
def list_projects(
|
|
db: Session,
|
|
limit: int = 50,
|
|
offset: int = 0,
|
|
name: str | None = None,
|
|
project_status: Literal["active", "archived", "all"] = "active",
|
|
) -> tuple[list[ProjectRead], int]:
|
|
query = db.query(Project).filter(Project.status != "deleted")
|
|
if project_status != "all":
|
|
query = query.filter(Project.status == project_status)
|
|
if name:
|
|
query = query.filter(Project.name == name.strip())
|
|
query = query.order_by(Project.created_at.desc())
|
|
total = query.count()
|
|
items = query.offset(offset).limit(limit).all()
|
|
return [ProjectRead.model_validate(item) for item in items], total
|
|
|
|
@staticmethod
|
|
def create_project(db: Session, payload: ProjectCreate) -> ProjectRead:
|
|
project = Project(
|
|
name=payload.name.strip(),
|
|
description=(payload.description or "").strip() or None,
|
|
region=payload.region or "Belgium and Belgian North Sea",
|
|
)
|
|
db.add(project)
|
|
db.commit()
|
|
db.refresh(project)
|
|
return ProjectRead.model_validate(project)
|
|
|
|
@staticmethod
|
|
def get_project(db: Session, project_id: uuid.UUID) -> ProjectRead | None:
|
|
project = db.get(Project, project_id)
|
|
if not project or project.status == "deleted":
|
|
return None
|
|
return ProjectRead.model_validate(project)
|
|
|
|
@staticmethod
|
|
def update_project(db: Session, project_id: uuid.UUID, payload: ProjectUpdate) -> ProjectRead | None:
|
|
project = db.get(Project, project_id)
|
|
if not project or project.status == "deleted":
|
|
return None
|
|
|
|
payload_data = payload.model_dump(exclude_unset=True)
|
|
changed = False
|
|
for key, value in payload_data.items():
|
|
if value is None:
|
|
continue
|
|
setattr(project, key, value)
|
|
changed = True
|
|
if not changed:
|
|
raise AppError(code="NO_CHANGES", message="No updatable fields provided", status_code=422)
|
|
|
|
db.add(project)
|
|
db.commit()
|
|
db.refresh(project)
|
|
return ProjectRead.model_validate(project)
|
|
|
|
@staticmethod
|
|
def delete_project(db: Session, project_id: uuid.UUID) -> bool:
|
|
project = db.get(Project, project_id)
|
|
if not project or project.status == "deleted":
|
|
return False
|
|
project.status = "deleted"
|
|
db.add(project)
|
|
db.commit()
|
|
return True
|