feat: add boards and tasks management endpoints

This commit is contained in:
Abhimanyu Saharan
2026-02-04 02:28:51 +05:30
parent 23faa0865b
commit 1abc8f68f3
170 changed files with 6860 additions and 10706 deletions

View File

@@ -1,15 +1,13 @@
from app.models.activity import Activity
from app.models.org import Department, Employee, Team
from app.models.projects import Project, ProjectMember
from app.models.work import Task, TaskComment
from app.models.activity_events import ActivityEvent
from app.models.agents import Agent
from app.models.boards import Board
from app.models.tasks import Task
from app.models.users import User
__all__ = [
"Department",
"Employee",
"Team",
"Project",
"ProjectMember",
"ActivityEvent",
"Agent",
"Board",
"Task",
"TaskComment",
"Activity",
"User",
]

View File

@@ -1,19 +0,0 @@
from __future__ import annotations
from datetime import datetime
from sqlmodel import Field, SQLModel
class Activity(SQLModel, table=True):
__tablename__ = "activities"
id: int | None = Field(default=None, primary_key=True)
actor_employee_id: int | None = Field(default=None, foreign_key="employees.id")
entity_type: str
entity_id: int | None = None
verb: str
payload_json: str | None = None
created_at: datetime = Field(default_factory=datetime.utcnow)

View File

@@ -0,0 +1,17 @@
from __future__ import annotations
from datetime import datetime
from uuid import UUID, uuid4
from sqlmodel import Field, SQLModel
class ActivityEvent(SQLModel, table=True):
__tablename__ = "activity_events"
id: UUID = Field(default_factory=uuid4, primary_key=True)
event_type: str = Field(index=True)
message: str | None = None
agent_id: UUID | None = Field(default=None, foreign_key="agents.id", index=True)
task_id: UUID | None = Field(default=None, foreign_key="tasks.id", index=True)
created_at: datetime = Field(default_factory=datetime.utcnow)

View File

@@ -0,0 +1,18 @@
from __future__ import annotations
from datetime import datetime
from uuid import UUID, uuid4
from sqlmodel import Field, SQLModel
class Agent(SQLModel, table=True):
__tablename__ = "agents"
id: UUID = Field(default_factory=uuid4, primary_key=True)
name: str = Field(index=True)
status: str = Field(default="online", index=True)
openclaw_session_id: str | None = Field(default=None, index=True)
last_seen_at: datetime = Field(default_factory=datetime.utcnow)
created_at: datetime = Field(default_factory=datetime.utcnow)
updated_at: datetime = Field(default_factory=datetime.utcnow)

View File

@@ -0,0 +1,18 @@
from __future__ import annotations
from datetime import datetime
from uuid import UUID, uuid4
from sqlmodel import Field
from app.models.tenancy import TenantScoped
class Board(TenantScoped, table=True):
__tablename__ = "boards"
id: UUID = Field(default_factory=uuid4, primary_key=True)
name: str
slug: str = Field(index=True)
created_at: datetime = Field(default_factory=datetime.utcnow)
updated_at: datetime = Field(default_factory=datetime.utcnow)

View File

@@ -1,40 +0,0 @@
from __future__ import annotations
from sqlmodel import Field, SQLModel
class Department(SQLModel, table=True):
__tablename__ = "departments"
id: int | None = Field(default=None, primary_key=True)
name: str = Field(index=True, unique=True)
head_employee_id: int | None = Field(default=None, foreign_key="employees.id")
class Team(SQLModel, table=True):
__tablename__ = "teams"
id: int | None = Field(default=None, primary_key=True)
name: str = Field(index=True)
department_id: int = Field(foreign_key="departments.id")
lead_employee_id: int | None = Field(default=None, foreign_key="employees.id")
class Employee(SQLModel, table=True):
__tablename__ = "employees"
id: int | None = Field(default=None, primary_key=True)
name: str
employee_type: str # human | agent
department_id: int | None = Field(default=None, foreign_key="departments.id")
team_id: int | None = Field(default=None, foreign_key="teams.id")
manager_id: int | None = Field(default=None, foreign_key="employees.id")
title: str | None = None
status: str = Field(default="active")
# OpenClaw integration
openclaw_session_key: str | None = None
notify_enabled: bool = Field(default=True)

View File

@@ -1,23 +0,0 @@
from __future__ import annotations
from sqlmodel import Field, SQLModel
class Project(SQLModel, table=True):
__tablename__ = "projects"
id: int | None = Field(default=None, primary_key=True)
name: str = Field(index=True, unique=True)
status: str = Field(default="active")
# Project ownership: projects are assigned to teams (not departments)
team_id: int | None = Field(default=None, foreign_key="teams.id")
class ProjectMember(SQLModel, table=True):
__tablename__ = "project_members"
id: int | None = Field(default=None, primary_key=True)
project_id: int = Field(foreign_key="projects.id")
employee_id: int = Field(foreign_key="employees.id")
role: str | None = None

View File

@@ -0,0 +1,26 @@
from __future__ import annotations
from datetime import datetime
from uuid import UUID, uuid4
from sqlmodel import Field
from app.models.tenancy import TenantScoped
class Task(TenantScoped, table=True):
__tablename__ = "tasks"
id: UUID = Field(default_factory=uuid4, primary_key=True)
board_id: UUID | None = Field(default=None, foreign_key="boards.id", index=True)
title: str
description: str | None = None
status: str = Field(default="inbox", index=True)
priority: str = Field(default="medium", index=True)
due_at: datetime | None = None
created_by_user_id: UUID | None = Field(default=None, foreign_key="users.id", index=True)
created_at: datetime = Field(default_factory=datetime.utcnow)
updated_at: datetime = Field(default_factory=datetime.utcnow)

View File

@@ -0,0 +1,7 @@
from __future__ import annotations
from sqlmodel import SQLModel
class TenantScoped(SQLModel, table=False):
pass

View File

@@ -0,0 +1,15 @@
from __future__ import annotations
from uuid import UUID, uuid4
from sqlmodel import Field, SQLModel
class User(SQLModel, table=True):
__tablename__ = "users"
id: UUID = Field(default_factory=uuid4, primary_key=True)
clerk_user_id: str = Field(index=True, unique=True)
email: str | None = Field(default=None, index=True)
name: str | None = None
is_super_admin: bool = Field(default=False)

View File

@@ -1,38 +0,0 @@
from __future__ import annotations
from datetime import datetime
from sqlmodel import Field, SQLModel
class Task(SQLModel, table=True):
__tablename__ = "tasks"
id: int | None = Field(default=None, primary_key=True)
project_id: int = Field(foreign_key="projects.id", index=True)
title: str
description: str | None = None
status: str = Field(default="backlog", index=True)
assignee_employee_id: int | None = Field(default=None, foreign_key="employees.id")
reviewer_employee_id: int | None = Field(default=None, foreign_key="employees.id")
created_by_employee_id: int | None = Field(default=None, foreign_key="employees.id")
created_at: datetime = Field(default_factory=datetime.utcnow)
updated_at: datetime = Field(default_factory=datetime.utcnow)
class TaskComment(SQLModel, table=True):
__tablename__ = "task_comments"
id: int | None = Field(default=None, primary_key=True)
task_id: int = Field(foreign_key="tasks.id", index=True)
author_employee_id: int | None = Field(default=None, foreign_key="employees.id")
# Optional reply threading
reply_to_comment_id: int | None = Field(default=None, foreign_key="task_comments.id")
body: str
created_at: datetime = Field(default_factory=datetime.utcnow)