Merge pull request #11 from abhi1693/jarvis/fix-projects-post

Fix Mission Control: POST /projects atomic + 409 on conflicts
This commit is contained in:
Abhimanyu Saharan
2026-02-02 13:55:04 +05:30
committed by GitHub

View File

@@ -1,6 +1,7 @@
from __future__ import annotations from __future__ import annotations
from fastapi import APIRouter, Depends, HTTPException from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.exc import IntegrityError
from sqlmodel import Session, select from sqlmodel import Session, select
from app.api.utils import log_activity, get_actor_employee_id from app.api.utils import log_activity, get_actor_employee_id
@@ -17,16 +18,40 @@ def list_projects(session: Session = Depends(get_session)):
@router.post("", response_model=Project) @router.post("", response_model=Project)
def create_project(payload: ProjectCreate, session: Session = Depends(get_session), actor_employee_id: int = Depends(get_actor_employee_id)): def create_project(
payload: ProjectCreate,
session: Session = Depends(get_session),
actor_employee_id: int = Depends(get_actor_employee_id),
):
"""Create a project.
Keep operation atomic: flush to get id, log activity, then commit once.
Translate DB integrity errors to 409s.
"""
proj = Project(**payload.model_dump()) proj = Project(**payload.model_dump())
session.add(proj) session.add(proj)
try:
session.flush()
log_activity(
session,
actor_employee_id=actor_employee_id,
entity_type="project",
entity_id=proj.id,
verb="created",
payload={"name": proj.name},
)
session.commit() session.commit()
except IntegrityError:
session.rollback()
raise HTTPException(status_code=409, detail="Project already exists or violates constraints")
session.refresh(proj) session.refresh(proj)
log_activity(session, actor_employee_id=actor_employee_id, entity_type="project", entity_id=proj.id, verb="created", payload={"name": proj.name})
session.commit()
return proj return proj
@router.patch("/{project_id}", response_model=Project) @router.patch("/{project_id}", response_model=Project)
def update_project(project_id: int, payload: ProjectUpdate, session: Session = Depends(get_session), actor_employee_id: int = Depends(get_actor_employee_id)): def update_project(project_id: int, payload: ProjectUpdate, session: Session = Depends(get_session), actor_employee_id: int = Depends(get_actor_employee_id)):
proj = session.get(Project, project_id) proj = session.get(Project, project_id)