feat: remove workspace system, add pinned flows and label renames

Replace workspace system with pinned flows API (pin/unpin/list/reorder).
Rename user-facing labels: Tree→Flow, Procedure→Project. Add sidebar
nav sub-items for flow type filtering. Remove 11 workspace files,
add migrations 037-038, clean all workspace references.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Michael Chihlas
2026-02-15 12:06:10 -05:00
parent 336e37d018
commit 58a55f4d88
39 changed files with 1612 additions and 2288 deletions

View File

@@ -37,7 +37,6 @@ class CategoryResponse(CategoryBase):
display_order: int
is_active: bool
color: Optional[str] = None
workspace_id: Optional[UUID] = None
created_at: datetime
updated_at: datetime
tree_count: int = 0 # Computed field
@@ -55,7 +54,6 @@ class CategoryListResponse(BaseModel):
display_order: int
is_active: bool
color: Optional[str] = None
workspace_id: Optional[UUID] = None
tree_count: int = 0
class Config:

View File

@@ -245,3 +245,37 @@ class TreeValidationResponse(BaseModel):
"""Response for tree validation endpoint."""
can_publish: bool
errors: list[ValidationError] = []
# --- Pinned Flows Schemas ---
class PinnedFlowResponse(BaseModel):
"""A pinned flow in the sidebar."""
id: UUID
tree_id: UUID
tree_name: str
tree_type: str
category_emoji: Optional[str] = None
category_name: Optional[str] = None
pinned_at: datetime
display_order: int
class Config:
from_attributes = True
class PinnedFlowsListResponse(BaseModel):
"""List of pinned flows."""
items: list[PinnedFlowResponse]
count: int
class PinnedFlowReorderItem(BaseModel):
"""Single item in a reorder request."""
tree_id: UUID
display_order: int
class PinnedFlowReorderRequest(BaseModel):
"""Request to reorder pinned flows."""
order: list[PinnedFlowReorderItem]

View File

@@ -1,39 +0,0 @@
import uuid
from datetime import datetime
from typing import Optional
from pydantic import BaseModel, Field
class WorkspaceCreate(BaseModel):
name: str = Field(..., min_length=1, max_length=100)
slug: str = Field(..., min_length=1, max_length=100, pattern=r'^[a-z0-9-]+$')
description: Optional[str] = None
icon: Optional[str] = Field(None, max_length=10)
accent_color: Optional[str] = Field(None, pattern=r'^#[0-9a-fA-F]{6}$')
sort_order: int = 0
class WorkspaceUpdate(BaseModel):
name: Optional[str] = Field(None, min_length=1, max_length=100)
slug: Optional[str] = Field(None, min_length=1, max_length=100, pattern=r'^[a-z0-9-]+$')
description: Optional[str] = None
icon: Optional[str] = Field(None, max_length=10)
accent_color: Optional[str] = Field(None, pattern=r'^#[0-9a-fA-F]{6}$')
sort_order: Optional[int] = None
class WorkspaceResponse(BaseModel):
id: uuid.UUID
name: str
slug: str
description: Optional[str] = None
icon: Optional[str] = None
accent_color: Optional[str] = None
account_id: uuid.UUID
is_default: bool
sort_order: int
tree_count: int = 0
created_at: datetime
updated_at: datetime
model_config = {"from_attributes": True}