Numidium / app /api /routes /projects.py
Madras1's picture
Upload 63 files
270c1c7 verified
"""
Projects API Routes - Workspace management
"""
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel
from typing import Optional, List
from datetime import datetime
from sqlalchemy.orm import Session
from app.api.deps import get_scoped_db
from app.models import Project, Entity, Relationship
router = APIRouter(prefix="/projects", tags=["Projects"])
class ProjectCreate(BaseModel):
name: str
description: Optional[str] = None
color: str = "#00d4ff"
icon: str = "folder"
class ProjectResponse(BaseModel):
id: str
name: str
description: Optional[str]
color: str
icon: str
entity_count: int = 0
created_at: datetime
class Config:
from_attributes = True
@router.get("", response_model=List[ProjectResponse])
def list_projects(db: Session = Depends(get_scoped_db)):
"""List all projects"""
projects = db.query(Project).order_by(Project.created_at.desc()).all()
result = []
for p in projects:
entity_count = db.query(Entity).filter(Entity.project_id == p.id).count()
result.append(ProjectResponse(
id=p.id,
name=p.name,
description=p.description,
color=p.color,
icon=p.icon,
entity_count=entity_count,
created_at=p.created_at
))
return result
@router.post("", response_model=ProjectResponse)
def create_project(project: ProjectCreate, db: Session = Depends(get_scoped_db)):
"""Create a new project"""
new_project = Project(
name=project.name,
description=project.description,
color=project.color,
icon=project.icon
)
db.add(new_project)
db.commit()
db.refresh(new_project)
return ProjectResponse(
id=new_project.id,
name=new_project.name,
description=new_project.description,
color=new_project.color,
icon=new_project.icon,
entity_count=0,
created_at=new_project.created_at
)
@router.get("/{project_id}", response_model=ProjectResponse)
def get_project(project_id: str, db: Session = Depends(get_scoped_db)):
"""Get project by ID"""
project = db.query(Project).filter(Project.id == project_id).first()
if not project:
raise HTTPException(status_code=404, detail="Project not found")
entity_count = db.query(Entity).filter(Entity.project_id == project_id).count()
return ProjectResponse(
id=project.id,
name=project.name,
description=project.description,
color=project.color,
icon=project.icon,
entity_count=entity_count,
created_at=project.created_at
)
@router.delete("/{project_id}")
def delete_project(project_id: str, db: Session = Depends(get_scoped_db)):
"""Delete project and optionally its entities"""
project = db.query(Project).filter(Project.id == project_id).first()
if not project:
raise HTTPException(status_code=404, detail="Project not found")
# Set entities and relationships to no project (null)
db.query(Entity).filter(Entity.project_id == project_id).update({"project_id": None})
db.query(Relationship).filter(Relationship.project_id == project_id).update({"project_id": None})
db.delete(project)
db.commit()
return {"message": f"Project '{project.name}' deleted"}
@router.put("/{project_id}")
def update_project(project_id: str, project: ProjectCreate, db: Session = Depends(get_scoped_db)):
"""Update project"""
existing = db.query(Project).filter(Project.id == project_id).first()
if not existing:
raise HTTPException(status_code=404, detail="Project not found")
existing.name = project.name
existing.description = project.description
existing.color = project.color
existing.icon = project.icon
db.commit()
return {"message": "Project updated"}