feat: add board goal schemas and validation
This commit is contained in:
@@ -1,5 +1,13 @@
|
|||||||
from app.schemas.activity_events import ActivityEventRead
|
from app.schemas.activity_events import ActivityEventRead
|
||||||
from app.schemas.agents import AgentCreate, AgentRead, AgentUpdate
|
from app.schemas.agents import AgentCreate, AgentRead, AgentUpdate
|
||||||
|
from app.schemas.approvals import ApprovalCreate, ApprovalRead, ApprovalUpdate
|
||||||
|
from app.schemas.board_memory import BoardMemoryCreate, BoardMemoryRead
|
||||||
|
from app.schemas.board_onboarding import (
|
||||||
|
BoardOnboardingAnswer,
|
||||||
|
BoardOnboardingConfirm,
|
||||||
|
BoardOnboardingRead,
|
||||||
|
BoardOnboardingStart,
|
||||||
|
)
|
||||||
from app.schemas.boards import BoardCreate, BoardRead, BoardUpdate
|
from app.schemas.boards import BoardCreate, BoardRead, BoardUpdate
|
||||||
from app.schemas.gateways import GatewayCreate, GatewayRead, GatewayUpdate
|
from app.schemas.gateways import GatewayCreate, GatewayRead, GatewayUpdate
|
||||||
from app.schemas.metrics import DashboardMetrics
|
from app.schemas.metrics import DashboardMetrics
|
||||||
@@ -11,6 +19,15 @@ __all__ = [
|
|||||||
"AgentCreate",
|
"AgentCreate",
|
||||||
"AgentRead",
|
"AgentRead",
|
||||||
"AgentUpdate",
|
"AgentUpdate",
|
||||||
|
"ApprovalCreate",
|
||||||
|
"ApprovalRead",
|
||||||
|
"ApprovalUpdate",
|
||||||
|
"BoardMemoryCreate",
|
||||||
|
"BoardMemoryRead",
|
||||||
|
"BoardOnboardingAnswer",
|
||||||
|
"BoardOnboardingConfirm",
|
||||||
|
"BoardOnboardingRead",
|
||||||
|
"BoardOnboardingStart",
|
||||||
"BoardCreate",
|
"BoardCreate",
|
||||||
"BoardRead",
|
"BoardRead",
|
||||||
"BoardUpdate",
|
"BoardUpdate",
|
||||||
|
|||||||
30
backend/app/schemas/approvals.py
Normal file
30
backend/app/schemas/approvals.py
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
|
from sqlmodel import SQLModel
|
||||||
|
|
||||||
|
|
||||||
|
class ApprovalBase(SQLModel):
|
||||||
|
action_type: str
|
||||||
|
payload: dict[str, object] | None = None
|
||||||
|
confidence: int
|
||||||
|
rubric_scores: dict[str, int] | None = None
|
||||||
|
status: str = "pending"
|
||||||
|
|
||||||
|
|
||||||
|
class ApprovalCreate(ApprovalBase):
|
||||||
|
agent_id: UUID | None = None
|
||||||
|
|
||||||
|
|
||||||
|
class ApprovalUpdate(SQLModel):
|
||||||
|
status: str | None = None
|
||||||
|
|
||||||
|
|
||||||
|
class ApprovalRead(ApprovalBase):
|
||||||
|
id: UUID
|
||||||
|
board_id: UUID
|
||||||
|
agent_id: UUID | None = None
|
||||||
|
created_at: datetime
|
||||||
|
resolved_at: datetime | None = None
|
||||||
18
backend/app/schemas/board_memory.py
Normal file
18
backend/app/schemas/board_memory.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
|
from sqlmodel import SQLModel
|
||||||
|
|
||||||
|
|
||||||
|
class BoardMemoryCreate(SQLModel):
|
||||||
|
content: str
|
||||||
|
tags: list[str] | None = None
|
||||||
|
source: str | None = None
|
||||||
|
|
||||||
|
|
||||||
|
class BoardMemoryRead(BoardMemoryCreate):
|
||||||
|
id: UUID
|
||||||
|
board_id: UUID
|
||||||
|
created_at: datetime
|
||||||
33
backend/app/schemas/board_onboarding.py
Normal file
33
backend/app/schemas/board_onboarding.py
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
|
from sqlmodel import SQLModel
|
||||||
|
|
||||||
|
|
||||||
|
class BoardOnboardingStart(SQLModel):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class BoardOnboardingAnswer(SQLModel):
|
||||||
|
answer: str
|
||||||
|
other_text: str | None = None
|
||||||
|
|
||||||
|
|
||||||
|
class BoardOnboardingConfirm(SQLModel):
|
||||||
|
board_type: str
|
||||||
|
objective: str | None = None
|
||||||
|
success_metrics: dict[str, object] | None = None
|
||||||
|
target_date: datetime | None = None
|
||||||
|
|
||||||
|
|
||||||
|
class BoardOnboardingRead(SQLModel):
|
||||||
|
id: UUID
|
||||||
|
board_id: UUID
|
||||||
|
session_key: str
|
||||||
|
status: str
|
||||||
|
messages: list[dict[str, object]] | None = None
|
||||||
|
draft_goal: dict[str, object] | None = None
|
||||||
|
created_at: datetime
|
||||||
|
updated_at: datetime
|
||||||
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
|
from pydantic import model_validator
|
||||||
from sqlmodel import SQLModel
|
from sqlmodel import SQLModel
|
||||||
|
|
||||||
|
|
||||||
@@ -10,16 +11,33 @@ class BoardBase(SQLModel):
|
|||||||
name: str
|
name: str
|
||||||
slug: str
|
slug: str
|
||||||
gateway_id: UUID | None = None
|
gateway_id: UUID | None = None
|
||||||
|
board_type: str = "goal"
|
||||||
|
objective: str | None = None
|
||||||
|
success_metrics: dict[str, object] | None = None
|
||||||
|
target_date: datetime | None = None
|
||||||
|
goal_confirmed: bool = False
|
||||||
|
goal_source: str | None = None
|
||||||
|
|
||||||
|
|
||||||
class BoardCreate(BoardBase):
|
class BoardCreate(BoardBase):
|
||||||
pass
|
@model_validator(mode="after")
|
||||||
|
def validate_goal_fields(self):
|
||||||
|
if self.board_type == "goal":
|
||||||
|
if not self.objective or not self.success_metrics:
|
||||||
|
raise ValueError("Goal boards require objective and success_metrics")
|
||||||
|
return self
|
||||||
|
|
||||||
|
|
||||||
class BoardUpdate(SQLModel):
|
class BoardUpdate(SQLModel):
|
||||||
name: str | None = None
|
name: str | None = None
|
||||||
slug: str | None = None
|
slug: str | None = None
|
||||||
gateway_id: UUID | None = None
|
gateway_id: UUID | None = None
|
||||||
|
board_type: str | None = None
|
||||||
|
objective: str | None = None
|
||||||
|
success_metrics: dict[str, object] | None = None
|
||||||
|
target_date: datetime | None = None
|
||||||
|
goal_confirmed: bool | None = None
|
||||||
|
goal_source: str | None = None
|
||||||
|
|
||||||
|
|
||||||
class BoardRead(BoardBase):
|
class BoardRead(BoardBase):
|
||||||
|
|||||||
20
backend/tests/test_board_schema.py
Normal file
20
backend/tests/test_board_schema.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from app.schemas.boards import BoardCreate
|
||||||
|
|
||||||
|
|
||||||
|
def test_goal_board_requires_objective_and_metrics():
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
BoardCreate(name="Goal Board", slug="goal", board_type="goal")
|
||||||
|
|
||||||
|
BoardCreate(
|
||||||
|
name="Goal Board",
|
||||||
|
slug="goal",
|
||||||
|
board_type="goal",
|
||||||
|
objective="Launch onboarding",
|
||||||
|
success_metrics={"emails": 3},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_general_board_allows_missing_objective():
|
||||||
|
BoardCreate(name="General", slug="general", board_type="general")
|
||||||
Reference in New Issue
Block a user