Files
geointel/backend/app/services/project_service.py
T
Codex 0aff8e3b8c
GeoIntel release gates / Compile, test, contracts and builds (push) Canceled after 0s
GeoIntel release gates / Python and npm vulnerability policy (push) Canceled after 0s
GeoIntel release gates / GIS image, SBOM and container scan (push) Canceled after 0s
feat(scope): make Belgium and North Sea operational default
2026-07-22 02:11:48 +02:00

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