File size: 4,068 Bytes
43e23ba 270c1c7 43e23ba 270c1c7 43e23ba 270c1c7 43e23ba 270c1c7 43e23ba 270c1c7 43e23ba 270c1c7 43e23ba | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | """
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"}
|