Global labels: remove project_id, endpoints at /labels
Some checks failed
Deploy Tracker / deploy (push) Failing after 3s
Some checks failed
Deploy Tracker / deploy (push) Failing after 3s
Labels are now app-wide, not project-scoped.
GET/POST /labels, PATCH/DELETE /labels/{id}
This commit is contained in:
parent
1f57f869ba
commit
009789ad8b
@ -1,4 +1,4 @@
|
||||
"""Labels API — CRUD for project-scoped labels."""
|
||||
"""Labels API — CRUD for global labels."""
|
||||
|
||||
import uuid
|
||||
|
||||
@ -26,31 +26,27 @@ class LabelUpdate(BaseModel):
|
||||
|
||||
class LabelOut(BaseModel):
|
||||
id: str
|
||||
project_id: str
|
||||
name: str
|
||||
color: str
|
||||
|
||||
|
||||
@router.get("/projects/{project_id}/labels", response_model=list[LabelOut])
|
||||
async def list_labels(project_id: str, db: AsyncSession = Depends(get_db)):
|
||||
result = await db.execute(
|
||||
select(Label).where(Label.project_id == uuid.UUID(project_id)).order_by(Label.name)
|
||||
)
|
||||
return [LabelOut(id=str(l.id), project_id=str(l.project_id), name=l.name, color=l.color) for l in result.scalars()]
|
||||
@router.get("/labels", response_model=list[LabelOut])
|
||||
async def list_labels(db: AsyncSession = Depends(get_db)):
|
||||
result = await db.execute(select(Label).order_by(Label.name))
|
||||
return [LabelOut(id=str(l.id), name=l.name, color=l.color) for l in result.scalars()]
|
||||
|
||||
|
||||
@router.post("/projects/{project_id}/labels", response_model=LabelOut)
|
||||
@router.post("/labels", response_model=LabelOut)
|
||||
async def create_label(
|
||||
project_id: str,
|
||||
req: LabelCreate,
|
||||
current_member: Member = Depends(get_current_member),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
label = Label(project_id=uuid.UUID(project_id), name=req.name, color=req.color)
|
||||
label = Label(name=req.name, color=req.color)
|
||||
db.add(label)
|
||||
await db.commit()
|
||||
await db.refresh(label)
|
||||
return LabelOut(id=str(label.id), project_id=str(label.project_id), name=label.name, color=label.color)
|
||||
return LabelOut(id=str(label.id), name=label.name, color=label.color)
|
||||
|
||||
|
||||
@router.patch("/labels/{label_id}", response_model=LabelOut)
|
||||
@ -70,7 +66,7 @@ async def update_label(
|
||||
label.color = req.color
|
||||
await db.commit()
|
||||
await db.refresh(label)
|
||||
return LabelOut(id=str(label.id), project_id=str(label.project_id), name=label.name, color=label.color)
|
||||
return LabelOut(id=str(label.id), name=label.name, color=label.color)
|
||||
|
||||
|
||||
@router.delete("/labels/{label_id}")
|
||||
@ -83,8 +79,6 @@ async def delete_label(
|
||||
label = result.scalar_one_or_none()
|
||||
if not label:
|
||||
raise HTTPException(404, "Label not found")
|
||||
# Remove task associations
|
||||
await db.execute(select(TaskLabel).where(TaskLabel.label_id == label.id))
|
||||
await db.delete(label)
|
||||
await db.commit()
|
||||
return {"ok": True}
|
||||
|
||||
@ -54,15 +54,12 @@ class Step(Base):
|
||||
|
||||
|
||||
class Label(Base):
|
||||
"""Project-scoped labels (like Jira)."""
|
||||
"""Global labels (app-wide)."""
|
||||
__tablename__ = "labels"
|
||||
|
||||
project_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), ForeignKey("projects.id"), nullable=False)
|
||||
name: Mapped[str] = mapped_column(String(100), nullable=False)
|
||||
name: Mapped[str] = mapped_column(String(100), unique=True, nullable=False)
|
||||
color: Mapped[str] = mapped_column(String(7), default="#6366f1") # hex color
|
||||
|
||||
project: Mapped["Project"] = relationship()
|
||||
|
||||
|
||||
class TaskLabel(Base):
|
||||
"""Many-to-many: tasks ↔ labels."""
|
||||
|
||||
Loading…
Reference in New Issue
Block a user