feat(agents): add category and display fields to AgentType model

Add 6 new fields to AgentType for better organization and UI display:
- category: enum for grouping (development, design, quality, etc.)
- icon: Lucide icon identifier for UI
- color: hex color code for visual distinction
- sort_order: display ordering within categories
- typical_tasks: list of tasks the agent excels at
- collaboration_hints: agent slugs that work well together

Backend changes:
- Add AgentTypeCategory enum to enums.py
- Update AgentType model with 6 new columns and indexes
- Update schemas with validators for new fields
- Add category filter and /grouped endpoint to routes
- Update CRUD with get_grouped_by_category method
- Update seed data with categories for all 27 agents
- Add migration 0007

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-06 16:11:22 +01:00
parent 79cb6bfd7b
commit 9339ea30a1
8 changed files with 484 additions and 28 deletions

View File

@@ -0,0 +1,90 @@
"""Add category and display fields to agent_types table
Revision ID: 0007
Revises: 0006
Create Date: 2026-01-06
This migration adds:
- category: String(50) for grouping agents by role type
- icon: String(50) for Lucide icon identifier
- color: String(7) for hex color code
- sort_order: Integer for display ordering within categories
- typical_tasks: JSONB list of tasks this agent excels at
- collaboration_hints: JSONB list of agent slugs that work well together
"""
from collections.abc import Sequence
import sqlalchemy as sa
from alembic import op
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision: str = "0007"
down_revision: str | None = "0006"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None
def upgrade() -> None:
"""Add category and display fields to agent_types table."""
# Add new columns
op.add_column(
"agent_types",
sa.Column("category", sa.String(length=50), nullable=True),
)
op.add_column(
"agent_types",
sa.Column("icon", sa.String(length=50), nullable=True, server_default="bot"),
)
op.add_column(
"agent_types",
sa.Column(
"color", sa.String(length=7), nullable=True, server_default="#3B82F6"
),
)
op.add_column(
"agent_types",
sa.Column("sort_order", sa.Integer(), nullable=False, server_default="0"),
)
op.add_column(
"agent_types",
sa.Column(
"typical_tasks",
postgresql.JSONB(astext_type=sa.Text()),
nullable=False,
server_default="[]",
),
)
op.add_column(
"agent_types",
sa.Column(
"collaboration_hints",
postgresql.JSONB(astext_type=sa.Text()),
nullable=False,
server_default="[]",
),
)
# Add indexes for category and sort_order
op.create_index("ix_agent_types_category", "agent_types", ["category"])
op.create_index("ix_agent_types_sort_order", "agent_types", ["sort_order"])
op.create_index(
"ix_agent_types_category_sort", "agent_types", ["category", "sort_order"]
)
def downgrade() -> None:
"""Remove category and display fields from agent_types table."""
# Drop indexes
op.drop_index("ix_agent_types_category_sort", table_name="agent_types")
op.drop_index("ix_agent_types_sort_order", table_name="agent_types")
op.drop_index("ix_agent_types_category", table_name="agent_types")
# Drop columns
op.drop_column("agent_types", "collaboration_hints")
op.drop_column("agent_types", "typical_tasks")
op.drop_column("agent_types", "sort_order")
op.drop_column("agent_types", "color")
op.drop_column("agent_types", "icon")
op.drop_column("agent_types", "category")

View File

@@ -81,6 +81,13 @@ def _build_agent_type_response(
mcp_servers=agent_type.mcp_servers,
tool_permissions=agent_type.tool_permissions,
is_active=agent_type.is_active,
# Category and display fields
category=agent_type.category,
icon=agent_type.icon,
color=agent_type.color,
sort_order=agent_type.sort_order,
typical_tasks=agent_type.typical_tasks or [],
collaboration_hints=agent_type.collaboration_hints or [],
created_at=agent_type.created_at,
updated_at=agent_type.updated_at,
instance_count=instance_count,
@@ -300,6 +307,7 @@ async def list_agent_types(
request: Request,
pagination: PaginationParams = Depends(),
is_active: bool = Query(True, description="Filter by active status"),
category: str | None = Query(None, description="Filter by category"),
search: str | None = Query(None, description="Search by name, slug, description"),
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
@@ -314,6 +322,7 @@ async def list_agent_types(
request: FastAPI request object
pagination: Pagination parameters (page, limit)
is_active: Filter by active status (default: True)
category: Filter by category (e.g., "development", "design")
search: Optional search term for name, slug, description
current_user: Authenticated user
db: Database session
@@ -328,6 +337,7 @@ async def list_agent_types(
skip=pagination.offset,
limit=pagination.limit,
is_active=is_active,
category=category,
search=search,
)
@@ -354,6 +364,51 @@ async def list_agent_types(
raise
@router.get(
"/grouped",
response_model=dict[str, list[AgentTypeResponse]],
summary="List Agent Types Grouped by Category",
description="Get all agent types organized by category",
operation_id="list_agent_types_grouped",
)
@limiter.limit(f"{60 * RATE_MULTIPLIER}/minute")
async def list_agent_types_grouped(
request: Request,
is_active: bool = Query(True, description="Filter by active status"),
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
) -> Any:
"""
Get agent types grouped by category.
Returns a dictionary where keys are category names and values
are lists of agent types, sorted by sort_order within each category.
Args:
request: FastAPI request object
is_active: Filter by active status (default: True)
current_user: Authenticated user
db: Database session
Returns:
Dictionary mapping category to list of agent types
"""
try:
grouped = await agent_type_crud.get_grouped_by_category(db, is_active=is_active)
# Transform to response objects
result: dict[str, list[AgentTypeResponse]] = {}
for category, types in grouped.items():
result[category] = [
_build_agent_type_response(t, instance_count=0) for t in types
]
return result
except Exception as e:
logger.error(f"Error getting grouped agent types: {e!s}", exc_info=True)
raise
@router.get(
"/{agent_type_id}",
response_model=AgentTypeResponse,

View File

@@ -43,6 +43,13 @@ class CRUDAgentType(CRUDBase[AgentType, AgentTypeCreate, AgentTypeUpdate]):
mcp_servers=obj_in.mcp_servers,
tool_permissions=obj_in.tool_permissions,
is_active=obj_in.is_active,
# Category and display fields
category=obj_in.category.value if obj_in.category else None,
icon=obj_in.icon,
color=obj_in.color,
sort_order=obj_in.sort_order,
typical_tasks=obj_in.typical_tasks,
collaboration_hints=obj_in.collaboration_hints,
)
db.add(db_obj)
await db.commit()
@@ -68,6 +75,7 @@ class CRUDAgentType(CRUDBase[AgentType, AgentTypeCreate, AgentTypeUpdate]):
skip: int = 0,
limit: int = 100,
is_active: bool | None = None,
category: str | None = None,
search: str | None = None,
sort_by: str = "created_at",
sort_order: str = "desc",
@@ -85,6 +93,9 @@ class CRUDAgentType(CRUDBase[AgentType, AgentTypeCreate, AgentTypeUpdate]):
if is_active is not None:
query = query.where(AgentType.is_active == is_active)
if category:
query = query.where(AgentType.category == category)
if search:
search_filter = or_(
AgentType.name.ilike(f"%{search}%"),
@@ -162,6 +173,7 @@ class CRUDAgentType(CRUDBase[AgentType, AgentTypeCreate, AgentTypeUpdate]):
skip: int = 0,
limit: int = 100,
is_active: bool | None = None,
category: str | None = None,
search: str | None = None,
) -> tuple[list[dict[str, Any]], int]:
"""
@@ -177,6 +189,7 @@ class CRUDAgentType(CRUDBase[AgentType, AgentTypeCreate, AgentTypeUpdate]):
skip=skip,
limit=limit,
is_active=is_active,
category=category,
search=search,
)
@@ -260,6 +273,44 @@ class CRUDAgentType(CRUDBase[AgentType, AgentTypeCreate, AgentTypeUpdate]):
)
raise
async def get_grouped_by_category(
self,
db: AsyncSession,
*,
is_active: bool = True,
) -> dict[str, list[AgentType]]:
"""
Get agent types grouped by category, sorted by sort_order within each group.
Args:
db: Database session
is_active: Filter by active status (default: True)
Returns:
Dictionary mapping category to list of agent types
"""
try:
query = (
select(AgentType)
.where(AgentType.is_active == is_active)
.order_by(AgentType.category, AgentType.sort_order, AgentType.name)
)
result = await db.execute(query)
agent_types = list(result.scalars().all())
# Group by category
grouped: dict[str, list[AgentType]] = {}
for at in agent_types:
cat: str = str(at.category) if at.category else "uncategorized"
if cat not in grouped:
grouped[cat] = []
grouped[cat].append(at)
return grouped
except Exception as e:
logger.error(f"Error getting grouped agent types: {e!s}", exc_info=True)
raise
# Create a singleton instance for use across the application
agent_type = CRUDAgentType(AgentType)

View File

@@ -149,6 +149,13 @@ async def load_default_agent_types(session: AsyncSession) -> None:
mcp_servers=agent_type_data.get("mcp_servers", []),
tool_permissions=agent_type_data.get("tool_permissions", {}),
is_active=agent_type_data.get("is_active", True),
# Category and display fields
category=agent_type_data.get("category"),
icon=agent_type_data.get("icon", "bot"),
color=agent_type_data.get("color", "#3B82F6"),
sort_order=agent_type_data.get("sort_order", 0),
typical_tasks=agent_type_data.get("typical_tasks", []),
collaboration_hints=agent_type_data.get("collaboration_hints", []),
)
await agent_type_crud.create(session, obj_in=agent_type_in)

View File

@@ -6,7 +6,7 @@ An AgentType is a template that defines the capabilities, personality,
and model configuration for agent instances.
"""
from sqlalchemy import Boolean, Column, Index, String, Text
from sqlalchemy import Boolean, Column, Index, Integer, String, Text
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.orm import relationship
@@ -56,6 +56,24 @@ class AgentType(Base, UUIDMixin, TimestampMixin):
# Whether this agent type is available for new instances
is_active = Column(Boolean, default=True, nullable=False, index=True)
# Category for grouping agents (development, design, quality, etc.)
category = Column(String(50), nullable=True, index=True)
# Lucide icon identifier for UI display (e.g., "code", "palette", "shield")
icon = Column(String(50), nullable=True, default="bot")
# Hex color code for visual distinction (e.g., "#3B82F6")
color = Column(String(7), nullable=True, default="#3B82F6")
# Display ordering within category (lower = first)
sort_order = Column(Integer, nullable=False, default=0, index=True)
# List of typical tasks this agent excels at
typical_tasks = Column(JSONB, default=list, nullable=False)
# List of agent slugs that collaborate well with this type
collaboration_hints = Column(JSONB, default=list, nullable=False)
# Relationships
instances = relationship(
"AgentInstance",
@@ -66,6 +84,7 @@ class AgentType(Base, UUIDMixin, TimestampMixin):
__table_args__ = (
Index("ix_agent_types_slug_active", "slug", "is_active"),
Index("ix_agent_types_name_active", "name", "is_active"),
Index("ix_agent_types_category_sort", "category", "sort_order"),
)
def __repr__(self) -> str:

View File

@@ -167,3 +167,29 @@ class SprintStatus(str, PyEnum):
IN_REVIEW = "in_review"
COMPLETED = "completed"
CANCELLED = "cancelled"
class AgentTypeCategory(str, PyEnum):
"""
Category classification for agent types.
Used for grouping and filtering agents in the UI.
DEVELOPMENT: Product, project, and engineering roles
DESIGN: UI/UX and design research roles
QUALITY: QA and security engineering
OPERATIONS: DevOps and MLOps
AI_ML: Machine learning and AI specialists
DATA: Data science and engineering
LEADERSHIP: Technical leadership roles
DOMAIN_EXPERT: Industry and domain specialists
"""
DEVELOPMENT = "development"
DESIGN = "design"
QUALITY = "quality"
OPERATIONS = "operations"
AI_ML = "ai_ml"
DATA = "data"
LEADERSHIP = "leadership"
DOMAIN_EXPERT = "domain_expert"

View File

@@ -10,6 +10,8 @@ from uuid import UUID
from pydantic import BaseModel, ConfigDict, Field, field_validator
from app.models.syndarix.enums import AgentTypeCategory
class AgentTypeBase(BaseModel):
"""Base agent type schema with common fields."""
@@ -26,6 +28,14 @@ class AgentTypeBase(BaseModel):
tool_permissions: dict[str, Any] = Field(default_factory=dict)
is_active: bool = True
# Category and display fields
category: AgentTypeCategory | None = None
icon: str | None = Field(None, max_length=50)
color: str | None = Field(None, pattern=r"^#[0-9A-Fa-f]{6}$")
sort_order: int = Field(default=0, ge=0, le=1000)
typical_tasks: list[str] = Field(default_factory=list)
collaboration_hints: list[str] = Field(default_factory=list)
@field_validator("slug")
@classmethod
def validate_slug(cls, v: str | None) -> str | None:
@@ -62,6 +72,18 @@ class AgentTypeBase(BaseModel):
"""Validate MCP server list."""
return [s.strip() for s in v if s.strip()]
@field_validator("typical_tasks")
@classmethod
def validate_typical_tasks(cls, v: list[str]) -> list[str]:
"""Validate and normalize typical tasks list."""
return [t.strip() for t in v if t.strip()]
@field_validator("collaboration_hints")
@classmethod
def validate_collaboration_hints(cls, v: list[str]) -> list[str]:
"""Validate and normalize collaboration hints (agent slugs)."""
return [h.strip().lower() for h in v if h.strip()]
class AgentTypeCreate(AgentTypeBase):
"""Schema for creating a new agent type."""
@@ -87,6 +109,14 @@ class AgentTypeUpdate(BaseModel):
tool_permissions: dict[str, Any] | None = None
is_active: bool | None = None
# Category and display fields (all optional for updates)
category: AgentTypeCategory | None = None
icon: str | None = Field(None, max_length=50)
color: str | None = Field(None, pattern=r"^#[0-9A-Fa-f]{6}$")
sort_order: int | None = Field(None, ge=0, le=1000)
typical_tasks: list[str] | None = None
collaboration_hints: list[str] | None = None
@field_validator("slug")
@classmethod
def validate_slug(cls, v: str | None) -> str | None:
@@ -119,6 +149,22 @@ class AgentTypeUpdate(BaseModel):
return v
return [e.strip().lower() for e in v if e.strip()]
@field_validator("typical_tasks")
@classmethod
def validate_typical_tasks(cls, v: list[str] | None) -> list[str] | None:
"""Validate and normalize typical tasks list."""
if v is None:
return v
return [t.strip() for t in v if t.strip()]
@field_validator("collaboration_hints")
@classmethod
def validate_collaboration_hints(cls, v: list[str] | None) -> list[str] | None:
"""Validate and normalize collaboration hints (agent slugs)."""
if v is None:
return v
return [h.strip().lower() for h in v if h.strip()]
class AgentTypeInDB(AgentTypeBase):
"""Schema for agent type in database."""

View File

@@ -29,7 +29,13 @@
"denied": [],
"require_approval": ["gitea:delete_*"]
},
"is_active": true
"is_active": true,
"category": "development",
"icon": "clipboard-check",
"color": "#3B82F6",
"sort_order": 10,
"typical_tasks": ["Requirements discovery", "User story creation", "Backlog prioritization", "Stakeholder alignment"],
"collaboration_hints": ["business-analyst", "solutions-architect", "scrum-master"]
},
{
"name": "Project Manager",
@@ -61,7 +67,13 @@
"denied": [],
"require_approval": []
},
"is_active": true
"is_active": true,
"category": "development",
"icon": "briefcase",
"color": "#3B82F6",
"sort_order": 20,
"typical_tasks": ["Sprint planning", "Risk management", "Status reporting", "Team coordination"],
"collaboration_hints": ["product-owner", "scrum-master", "technical-lead"]
},
{
"name": "Business Analyst",
@@ -93,7 +105,13 @@
"denied": [],
"require_approval": []
},
"is_active": true
"is_active": true,
"category": "development",
"icon": "file-text",
"color": "#3B82F6",
"sort_order": 30,
"typical_tasks": ["Requirements analysis", "Process modeling", "Gap analysis", "Functional specifications"],
"collaboration_hints": ["product-owner", "solutions-architect", "qa-engineer"]
},
{
"name": "Solutions Architect",
@@ -129,7 +147,13 @@
"denied": [],
"require_approval": ["gitea:create_pull_request"]
},
"is_active": true
"is_active": true,
"category": "development",
"icon": "git-branch",
"color": "#3B82F6",
"sort_order": 40,
"typical_tasks": ["System design", "ADR creation", "Technology selection", "Integration patterns"],
"collaboration_hints": ["backend-engineer", "frontend-engineer", "security-engineer"]
},
{
"name": "Full Stack Engineer",
@@ -166,7 +190,13 @@
"denied": [],
"require_approval": ["gitea:create_pull_request", "gitea:delete_*"]
},
"is_active": true
"is_active": true,
"category": "development",
"icon": "code",
"color": "#3B82F6",
"sort_order": 50,
"typical_tasks": ["End-to-end feature development", "API design", "UI implementation", "Database operations"],
"collaboration_hints": ["solutions-architect", "qa-engineer", "devops-engineer"]
},
{
"name": "Backend Engineer",
@@ -208,7 +238,13 @@
"denied": [],
"require_approval": ["gitea:create_pull_request", "gitea:delete_*"]
},
"is_active": true
"is_active": true,
"category": "development",
"icon": "server",
"color": "#3B82F6",
"sort_order": 60,
"typical_tasks": ["API development", "Database optimization", "System integration", "Performance tuning"],
"collaboration_hints": ["solutions-architect", "frontend-engineer", "data-engineer"]
},
{
"name": "Frontend Engineer",
@@ -249,7 +285,13 @@
"denied": [],
"require_approval": ["gitea:create_pull_request", "gitea:delete_*"]
},
"is_active": true
"is_active": true,
"category": "development",
"icon": "layout",
"color": "#3B82F6",
"sort_order": 70,
"typical_tasks": ["UI component development", "State management", "API integration", "Responsive design"],
"collaboration_hints": ["ui-ux-designer", "backend-engineer", "qa-engineer"]
},
{
"name": "Mobile Engineer",
@@ -286,7 +328,13 @@
"denied": [],
"require_approval": ["gitea:create_pull_request", "gitea:delete_*"]
},
"is_active": true
"is_active": true,
"category": "development",
"icon": "smartphone",
"color": "#3B82F6",
"sort_order": 80,
"typical_tasks": ["Native app development", "Cross-platform solutions", "Mobile optimization", "App store deployment"],
"collaboration_hints": ["backend-engineer", "ui-ux-designer", "qa-engineer"]
},
{
"name": "UI/UX Designer",
@@ -321,7 +369,13 @@
"denied": [],
"require_approval": []
},
"is_active": true
"is_active": true,
"category": "design",
"icon": "palette",
"color": "#EC4899",
"sort_order": 10,
"typical_tasks": ["Interface design", "User flow creation", "Design system maintenance", "Prototyping"],
"collaboration_hints": ["frontend-engineer", "ux-researcher", "product-owner"]
},
{
"name": "UX Researcher",
@@ -355,7 +409,13 @@
"denied": [],
"require_approval": []
},
"is_active": true
"is_active": true,
"category": "design",
"icon": "search",
"color": "#EC4899",
"sort_order": 20,
"typical_tasks": ["User research", "Usability testing", "Journey mapping", "Research synthesis"],
"collaboration_hints": ["ui-ux-designer", "product-owner", "business-analyst"]
},
{
"name": "QA Engineer",
@@ -391,7 +451,13 @@
"denied": [],
"require_approval": []
},
"is_active": true
"is_active": true,
"category": "quality",
"icon": "shield",
"color": "#10B981",
"sort_order": 10,
"typical_tasks": ["Test strategy development", "Test automation", "Bug verification", "Quality metrics"],
"collaboration_hints": ["backend-engineer", "frontend-engineer", "devops-engineer"]
},
{
"name": "DevOps Engineer",
@@ -431,7 +497,13 @@
"denied": [],
"require_approval": ["gitea:create_release", "gitea:delete_*"]
},
"is_active": true
"is_active": true,
"category": "operations",
"icon": "settings",
"color": "#F59E0B",
"sort_order": 10,
"typical_tasks": ["CI/CD pipeline design", "Infrastructure automation", "Monitoring setup", "Deployment optimization"],
"collaboration_hints": ["backend-engineer", "security-engineer", "mlops-engineer"]
},
{
"name": "Security Engineer",
@@ -467,7 +539,13 @@
"denied": [],
"require_approval": []
},
"is_active": true
"is_active": true,
"category": "quality",
"icon": "shield-check",
"color": "#10B981",
"sort_order": 20,
"typical_tasks": ["Security architecture", "Vulnerability assessment", "Compliance validation", "Threat modeling"],
"collaboration_hints": ["solutions-architect", "devops-engineer", "backend-engineer"]
},
{
"name": "AI/ML Engineer",
@@ -503,7 +581,13 @@
"denied": [],
"require_approval": ["gitea:create_pull_request"]
},
"is_active": true
"is_active": true,
"category": "ai_ml",
"icon": "brain",
"color": "#8B5CF6",
"sort_order": 10,
"typical_tasks": ["Model development", "Algorithm selection", "Feature engineering", "Model optimization"],
"collaboration_hints": ["data-scientist", "mlops-engineer", "backend-engineer"]
},
{
"name": "AI Researcher",
@@ -537,7 +621,13 @@
"denied": [],
"require_approval": []
},
"is_active": true
"is_active": true,
"category": "ai_ml",
"icon": "microscope",
"color": "#8B5CF6",
"sort_order": 20,
"typical_tasks": ["Research paper analysis", "Novel algorithm design", "Experiment design", "Benchmark evaluation"],
"collaboration_hints": ["ai-ml-engineer", "data-scientist", "scientific-computing-expert"]
},
{
"name": "Computer Vision Engineer",
@@ -573,7 +663,13 @@
"denied": [],
"require_approval": ["gitea:create_pull_request"]
},
"is_active": true
"is_active": true,
"category": "ai_ml",
"icon": "eye",
"color": "#8B5CF6",
"sort_order": 30,
"typical_tasks": ["Image processing pipelines", "Object detection models", "Video analysis", "Computer vision deployment"],
"collaboration_hints": ["ai-ml-engineer", "mlops-engineer", "backend-engineer"]
},
{
"name": "NLP Engineer",
@@ -609,7 +705,13 @@
"denied": [],
"require_approval": ["gitea:create_pull_request"]
},
"is_active": true
"is_active": true,
"category": "ai_ml",
"icon": "message-square",
"color": "#8B5CF6",
"sort_order": 40,
"typical_tasks": ["Text processing pipelines", "Language model fine-tuning", "Named entity recognition", "Sentiment analysis"],
"collaboration_hints": ["ai-ml-engineer", "data-scientist", "backend-engineer"]
},
{
"name": "MLOps Engineer",
@@ -645,7 +747,13 @@
"denied": [],
"require_approval": ["gitea:create_release"]
},
"is_active": true
"is_active": true,
"category": "operations",
"icon": "settings-2",
"color": "#F59E0B",
"sort_order": 20,
"typical_tasks": ["ML pipeline development", "Model deployment", "Feature store management", "Model monitoring"],
"collaboration_hints": ["ai-ml-engineer", "devops-engineer", "data-engineer"]
},
{
"name": "Data Scientist",
@@ -681,7 +789,13 @@
"denied": [],
"require_approval": []
},
"is_active": true
"is_active": true,
"category": "data",
"icon": "chart-bar",
"color": "#06B6D4",
"sort_order": 10,
"typical_tasks": ["Statistical analysis", "Predictive modeling", "Data visualization", "Insight generation"],
"collaboration_hints": ["data-engineer", "ai-ml-engineer", "business-analyst"]
},
{
"name": "Data Engineer",
@@ -717,7 +831,13 @@
"denied": [],
"require_approval": ["gitea:create_pull_request"]
},
"is_active": true
"is_active": true,
"category": "data",
"icon": "database",
"color": "#06B6D4",
"sort_order": 20,
"typical_tasks": ["Data pipeline development", "ETL optimization", "Data warehouse design", "Data quality management"],
"collaboration_hints": ["data-scientist", "backend-engineer", "mlops-engineer"]
},
{
"name": "Technical Lead",
@@ -749,7 +869,13 @@
"denied": [],
"require_approval": []
},
"is_active": true
"is_active": true,
"category": "leadership",
"icon": "users",
"color": "#F97316",
"sort_order": 10,
"typical_tasks": ["Technical direction", "Code review leadership", "Team mentoring", "Architecture decisions"],
"collaboration_hints": ["solutions-architect", "backend-engineer", "frontend-engineer"]
},
{
"name": "Scrum Master",
@@ -781,7 +907,13 @@
"denied": [],
"require_approval": []
},
"is_active": true
"is_active": true,
"category": "leadership",
"icon": "target",
"color": "#F97316",
"sort_order": 20,
"typical_tasks": ["Sprint facilitation", "Impediment removal", "Process improvement", "Team coaching"],
"collaboration_hints": ["project-manager", "product-owner", "technical-lead"]
},
{
"name": "Financial Systems Expert",
@@ -816,7 +948,13 @@
"denied": [],
"require_approval": []
},
"is_active": true
"is_active": true,
"category": "domain_expert",
"icon": "calculator",
"color": "#84CC16",
"sort_order": 10,
"typical_tasks": ["Financial system design", "Regulatory compliance", "Transaction processing", "Audit trail implementation"],
"collaboration_hints": ["solutions-architect", "security-engineer", "backend-engineer"]
},
{
"name": "Healthcare Systems Expert",
@@ -850,7 +988,13 @@
"denied": [],
"require_approval": []
},
"is_active": true
"is_active": true,
"category": "domain_expert",
"icon": "heart-pulse",
"color": "#84CC16",
"sort_order": 20,
"typical_tasks": ["Healthcare system design", "HIPAA compliance", "HL7/FHIR integration", "Clinical workflow optimization"],
"collaboration_hints": ["solutions-architect", "security-engineer", "data-engineer"]
},
{
"name": "Scientific Computing Expert",
@@ -886,7 +1030,13 @@
"denied": [],
"require_approval": []
},
"is_active": true
"is_active": true,
"category": "domain_expert",
"icon": "flask",
"color": "#84CC16",
"sort_order": 30,
"typical_tasks": ["HPC architecture", "Scientific algorithm implementation", "Data pipeline optimization", "Numerical computing"],
"collaboration_hints": ["ai-researcher", "data-scientist", "backend-engineer"]
},
{
"name": "Behavioral Psychology Expert",
@@ -919,7 +1069,13 @@
"denied": [],
"require_approval": []
},
"is_active": true
"is_active": true,
"category": "domain_expert",
"icon": "lightbulb",
"color": "#84CC16",
"sort_order": 40,
"typical_tasks": ["Behavioral design", "Engagement optimization", "User motivation analysis", "Ethical AI guidelines"],
"collaboration_hints": ["ux-researcher", "ui-ux-designer", "product-owner"]
},
{
"name": "Technical Writer",
@@ -951,6 +1107,12 @@
"denied": [],
"require_approval": []
},
"is_active": true
"is_active": true,
"category": "domain_expert",
"icon": "book-open",
"color": "#84CC16",
"sort_order": 50,
"typical_tasks": ["API documentation", "User guides", "Technical specifications", "Knowledge base creation"],
"collaboration_hints": ["solutions-architect", "product-owner", "qa-engineer"]
}
]