from datetime import datetime from typing import Optional from uuid import UUID from pydantic import BaseModel, Field import re def slugify(name: str) -> str: """Convert a name to a URL-safe slug.""" # Remove non-alphanumeric chars except spaces, convert to lowercase slug = re.sub(r'[^a-zA-Z0-9 ]', '', name.lower()) # Replace spaces with hyphens slug = re.sub(r' +', '-', slug.strip()) return slug class StepCategoryBase(BaseModel): name: str = Field(..., min_length=1, max_length=100) description: Optional[str] = None class StepCategoryCreate(StepCategoryBase): account_id: Optional[UUID] = Field(None, description="Account ID for account-specific category. NULL for global.") class StepCategoryUpdate(BaseModel): name: Optional[str] = Field(None, min_length=1, max_length=100) description: Optional[str] = None display_order: Optional[int] = None is_active: Optional[bool] = None class StepCategoryResponse(StepCategoryBase): id: UUID slug: str account_id: Optional[UUID] = None display_order: int is_active: bool created_at: datetime updated_at: datetime step_count: int = 0 # Computed field - count of steps in this category class Config: from_attributes = True class StepCategoryListResponse(BaseModel): id: UUID name: str slug: str description: Optional[str] = None account_id: Optional[UUID] = None display_order: int is_active: bool step_count: int = 0 class Config: from_attributes = True