chore: update generated files to orval v8.3.0 and adjust related interfaces

This commit is contained in:
Abhimanyu Saharan
2026-02-12 18:04:35 +05:30
parent c73103d5c9
commit 2ebdead95b
232 changed files with 9434 additions and 6021 deletions

View File

@@ -6,6 +6,7 @@ from typing import TYPE_CHECKING, Any
from uuid import UUID from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException, Query, status from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy import func
from sqlmodel import SQLModel, col, select from sqlmodel import SQLModel, col, select
from app.api import agents as agents_api from app.api import agents as agents_api
@@ -20,6 +21,7 @@ from app.db.session import get_session
from app.models.agents import Agent from app.models.agents import Agent
from app.models.boards import Board from app.models.boards import Board
from app.models.task_dependencies import TaskDependency from app.models.task_dependencies import TaskDependency
from app.models.task_tags import TaskTag
from app.models.tasks import Task from app.models.tasks import Task
from app.schemas.agents import ( from app.schemas.agents import (
AgentCreate, AgentCreate,
@@ -42,6 +44,7 @@ from app.schemas.gateway_coordination import (
GatewayMainAskUserResponse, GatewayMainAskUserResponse,
) )
from app.schemas.pagination import DefaultLimitOffsetPage from app.schemas.pagination import DefaultLimitOffsetPage
from app.schemas.task_tags import TaskTagRef
from app.schemas.tasks import TaskCommentCreate, TaskCommentRead, TaskCreate, TaskRead, TaskUpdate from app.schemas.tasks import TaskCommentCreate, TaskCommentRead, TaskCreate, TaskRead, TaskUpdate
from app.services.activity_log import record_activity from app.services.activity_log import record_activity
from app.services.openclaw.coordination_service import GatewayCoordinationService from app.services.openclaw.coordination_service import GatewayCoordinationService
@@ -52,6 +55,7 @@ from app.services.task_dependencies import (
dependency_status_by_id, dependency_status_by_id,
validate_dependency_update, validate_dependency_update,
) )
from app.services.task_tags import replace_task_tags, validate_task_tag_ids
if TYPE_CHECKING: if TYPE_CHECKING:
from collections.abc import Sequence from collections.abc import Sequence
@@ -210,6 +214,32 @@ async def list_tasks(
) )
@router.get("/boards/{board_id}/tags", response_model=list[TaskTagRef])
async def list_task_tags(
board: Board = BOARD_DEP,
session: AsyncSession = SESSION_DEP,
agent_ctx: AgentAuthContext = AGENT_CTX_DEP,
) -> list[TaskTagRef]:
"""List task tags available to the board's organization."""
_guard_board_access(agent_ctx, board)
tags = (
await session.exec(
select(TaskTag)
.where(col(TaskTag.organization_id) == board.organization_id)
.order_by(func.lower(col(TaskTag.name)).asc(), col(TaskTag.created_at).asc()),
)
).all()
return [
TaskTagRef(
id=tag.id,
name=tag.name,
slug=tag.slug,
color=tag.color,
)
for tag in tags
]
@router.post("/boards/{board_id}/tasks", response_model=TaskRead) @router.post("/boards/{board_id}/tasks", response_model=TaskRead)
async def create_task( async def create_task(
payload: TaskCreate, payload: TaskCreate,
@@ -220,8 +250,9 @@ async def create_task(
"""Create a task on the board as the lead agent.""" """Create a task on the board as the lead agent."""
_guard_board_access(agent_ctx, board) _guard_board_access(agent_ctx, board)
_require_board_lead(agent_ctx) _require_board_lead(agent_ctx)
data = payload.model_dump(exclude={"depends_on_task_ids"}) data = payload.model_dump(exclude={"depends_on_task_ids", "tag_ids"})
depends_on_task_ids = list(payload.depends_on_task_ids) depends_on_task_ids = list(payload.depends_on_task_ids)
tag_ids = list(payload.tag_ids)
task = Task.model_validate(data) task = Task.model_validate(data)
task.board_id = board.id task.board_id = board.id
@@ -234,6 +265,11 @@ async def create_task(
task_id=task.id, task_id=task.id,
depends_on_task_ids=depends_on_task_ids, depends_on_task_ids=depends_on_task_ids,
) )
normalized_tag_ids = await validate_task_tag_ids(
session,
organization_id=board.organization_id,
tag_ids=tag_ids,
)
dep_status = await dependency_status_by_id( dep_status = await dependency_status_by_id(
session, session,
board_id=board.id, board_id=board.id,
@@ -274,6 +310,11 @@ async def create_task(
depends_on_task_id=dep_id, depends_on_task_id=dep_id,
), ),
) )
await replace_task_tags(
session,
task_id=task.id,
tag_ids=normalized_tag_ids,
)
await session.commit() await session.commit()
await session.refresh(task) await session.refresh(task)
record_activity( record_activity(
@@ -295,12 +336,10 @@ async def create_task(
task=task, task=task,
agent=assigned_agent, agent=assigned_agent,
) )
return TaskRead.model_validate(task, from_attributes=True).model_copy( return await tasks_api._task_read_response(
update={ session,
"depends_on_task_ids": normalized_deps, task=task,
"blocked_by_task_ids": blocked_by, board_id=board.id,
"is_blocked": bool(blocked_by),
},
) )

View File

@@ -0,0 +1,220 @@
"""Task-tag CRUD endpoints for organization-scoped task categorization."""
from __future__ import annotations
from typing import TYPE_CHECKING
from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy import func
from sqlmodel import col, select
from app.api.deps import require_org_admin, require_org_member
from app.core.time import utcnow
from app.db import crud
from app.db.pagination import paginate
from app.db.session import get_session
from app.models.task_tag_assignments import TaskTagAssignment
from app.models.task_tags import TaskTag
from app.schemas.common import OkResponse
from app.schemas.pagination import DefaultLimitOffsetPage
from app.schemas.task_tags import TaskTagCreate, TaskTagRead, TaskTagUpdate
from app.services.organizations import OrganizationContext
from app.services.task_tags import slugify_task_tag, task_counts_for_tags
if TYPE_CHECKING:
from collections.abc import Sequence
from fastapi_pagination.limit_offset import LimitOffsetPage
from sqlmodel.ext.asyncio.session import AsyncSession
router = APIRouter(prefix="/tags", tags=["tags"])
SESSION_DEP = Depends(get_session)
ORG_MEMBER_DEP = Depends(require_org_member)
ORG_ADMIN_DEP = Depends(require_org_admin)
def _normalize_slug(slug: str | None, *, fallback_name: str) -> str:
source = (slug or "").strip() or fallback_name
return slugify_task_tag(source)
async def _require_org_task_tag(
session: AsyncSession,
*,
tag_id: UUID,
ctx: OrganizationContext,
) -> TaskTag:
tag = await TaskTag.objects.by_id(tag_id).first(session)
if tag is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
if tag.organization_id != ctx.organization.id:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
return tag
async def _ensure_slug_available(
session: AsyncSession,
*,
organization_id: UUID,
slug: str,
exclude_tag_id: UUID | None = None,
) -> None:
existing = await TaskTag.objects.filter_by(organization_id=organization_id, slug=slug).first(
session
)
if existing is None:
return
if exclude_tag_id is not None and existing.id == exclude_tag_id:
return
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail="Task tag slug already exists in this organization.",
)
async def _tag_read_page(
*,
session: AsyncSession,
items: Sequence[TaskTag],
) -> list[TaskTagRead]:
if not items:
return []
counts = await task_counts_for_tags(
session,
tag_ids=[item.id for item in items],
)
return [
TaskTagRead.model_validate(item, from_attributes=True).model_copy(
update={"task_count": counts.get(item.id, 0)},
)
for item in items
]
@router.get("", response_model=DefaultLimitOffsetPage[TaskTagRead])
async def list_task_tags(
session: AsyncSession = SESSION_DEP,
ctx: OrganizationContext = ORG_MEMBER_DEP,
) -> LimitOffsetPage[TaskTagRead]:
"""List task tags for the active organization."""
statement = (
select(TaskTag)
.where(col(TaskTag.organization_id) == ctx.organization.id)
.order_by(func.lower(col(TaskTag.name)).asc(), col(TaskTag.created_at).asc())
)
async def _transform(items: Sequence[object]) -> Sequence[object]:
tags: list[TaskTag] = []
for item in items:
if not isinstance(item, TaskTag):
msg = "Expected TaskTag items from paginated query"
raise TypeError(msg)
tags.append(item)
return await _tag_read_page(session=session, items=tags)
return await paginate(session, statement, transformer=_transform)
@router.post("", response_model=TaskTagRead)
async def create_task_tag(
payload: TaskTagCreate,
session: AsyncSession = SESSION_DEP,
ctx: OrganizationContext = ORG_ADMIN_DEP,
) -> TaskTagRead:
"""Create a task tag within the active organization."""
slug = _normalize_slug(payload.slug, fallback_name=payload.name)
await _ensure_slug_available(
session,
organization_id=ctx.organization.id,
slug=slug,
)
tag = await crud.create(
session,
TaskTag,
organization_id=ctx.organization.id,
name=payload.name,
slug=slug,
color=payload.color,
description=payload.description,
)
return TaskTagRead.model_validate(tag, from_attributes=True)
@router.get("/{tag_id}", response_model=TaskTagRead)
async def get_task_tag(
tag_id: UUID,
session: AsyncSession = SESSION_DEP,
ctx: OrganizationContext = ORG_MEMBER_DEP,
) -> TaskTagRead:
"""Get a single task tag in the active organization."""
tag = await _require_org_task_tag(
session,
tag_id=tag_id,
ctx=ctx,
)
count = (
await session.exec(
select(func.count(col(TaskTagAssignment.task_id))).where(
col(TaskTagAssignment.tag_id) == tag.id,
),
)
).one()
return TaskTagRead.model_validate(tag, from_attributes=True).model_copy(
update={"task_count": int(count or 0)},
)
@router.patch("/{tag_id}", response_model=TaskTagRead)
async def update_task_tag(
tag_id: UUID,
payload: TaskTagUpdate,
session: AsyncSession = SESSION_DEP,
ctx: OrganizationContext = ORG_ADMIN_DEP,
) -> TaskTagRead:
"""Update a task tag in the active organization."""
tag = await _require_org_task_tag(
session,
tag_id=tag_id,
ctx=ctx,
)
updates = payload.model_dump(exclude_unset=True)
if "slug" in payload.model_fields_set:
updates["slug"] = _normalize_slug(
updates.get("slug"),
fallback_name=str(updates.get("name") or tag.name),
)
if "slug" in updates and isinstance(updates["slug"], str):
await _ensure_slug_available(
session,
organization_id=ctx.organization.id,
slug=updates["slug"],
exclude_tag_id=tag.id,
)
updates["updated_at"] = utcnow()
updated = await crud.patch(session, tag, updates)
return TaskTagRead.model_validate(updated, from_attributes=True)
@router.delete("/{tag_id}", response_model=OkResponse)
async def delete_task_tag(
tag_id: UUID,
session: AsyncSession = SESSION_DEP,
ctx: OrganizationContext = ORG_ADMIN_DEP,
) -> OkResponse:
"""Delete a task tag and remove all associated task-tag links."""
tag = await _require_org_task_tag(
session,
tag_id=tag_id,
ctx=ctx,
)
await crud.delete_where(
session,
TaskTagAssignment,
col(TaskTagAssignment.tag_id) == tag.id,
commit=False,
)
await session.delete(tag)
await session.commit()
return OkResponse()

View File

@@ -34,6 +34,7 @@ from app.models.approvals import Approval
from app.models.boards import Board from app.models.boards import Board
from app.models.task_dependencies import TaskDependency from app.models.task_dependencies import TaskDependency
from app.models.task_fingerprints import TaskFingerprint from app.models.task_fingerprints import TaskFingerprint
from app.models.task_tag_assignments import TaskTagAssignment
from app.models.tasks import Task from app.models.tasks import Task
from app.schemas.activity_events import ActivityEventRead from app.schemas.activity_events import ActivityEventRead
from app.schemas.common import OkResponse from app.schemas.common import OkResponse
@@ -55,6 +56,12 @@ from app.services.task_dependencies import (
replace_task_dependencies, replace_task_dependencies,
validate_dependency_update, validate_dependency_update,
) )
from app.services.task_tags import (
TaskTagState,
load_task_tag_state,
replace_task_tags,
validate_task_tag_ids,
)
if TYPE_CHECKING: if TYPE_CHECKING:
from collections.abc import AsyncIterator, Sequence from collections.abc import AsyncIterator, Sequence
@@ -576,6 +583,10 @@ async def _task_read_page(
return [] return []
task_ids = [task.id for task in tasks] task_ids = [task.id for task in tasks]
tag_state_by_task_id = await load_task_tag_state(
session,
task_ids=task_ids,
)
deps_map = await dependency_ids_by_task_id( deps_map = await dependency_ids_by_task_id(
session, session,
board_id=board_id, board_id=board_id,
@@ -592,6 +603,7 @@ async def _task_read_page(
output: list[TaskRead] = [] output: list[TaskRead] = []
for task in tasks: for task in tasks:
tag_state = tag_state_by_task_id.get(task.id, TaskTagState())
dep_list = deps_map.get(task.id, []) dep_list = deps_map.get(task.id, [])
blocked_by = blocked_by_dependency_ids( blocked_by = blocked_by_dependency_ids(
dependency_ids=dep_list, dependency_ids=dep_list,
@@ -603,6 +615,8 @@ async def _task_read_page(
TaskRead.model_validate(task, from_attributes=True).model_copy( TaskRead.model_validate(task, from_attributes=True).model_copy(
update={ update={
"depends_on_task_ids": dep_list, "depends_on_task_ids": dep_list,
"tag_ids": tag_state.tag_ids,
"tags": tag_state.tags,
"blocked_by_task_ids": blocked_by, "blocked_by_task_ids": blocked_by,
"is_blocked": bool(blocked_by), "is_blocked": bool(blocked_by),
}, },
@@ -611,18 +625,22 @@ async def _task_read_page(
return output return output
async def _stream_dependency_state( async def _stream_task_state(
session: AsyncSession, session: AsyncSession,
*, *,
board_id: UUID, board_id: UUID,
rows: list[tuple[ActivityEvent, Task | None]], rows: list[tuple[ActivityEvent, Task | None]],
) -> tuple[dict[UUID, list[UUID]], dict[UUID, str]]: ) -> tuple[dict[UUID, list[UUID]], dict[UUID, str], dict[UUID, TaskTagState]]:
task_ids = [ task_ids = [
task.id for event, task in rows if task is not None and event.event_type != "task.comment" task.id for event, task in rows if task is not None and event.event_type != "task.comment"
] ]
if not task_ids: if not task_ids:
return {}, {} return {}, {}, {}
tag_state_by_task_id = await load_task_tag_state(
session,
task_ids=list({*task_ids}),
)
deps_map = await dependency_ids_by_task_id( deps_map = await dependency_ids_by_task_id(
session, session,
board_id=board_id, board_id=board_id,
@@ -632,14 +650,14 @@ async def _stream_dependency_state(
for value in deps_map.values(): for value in deps_map.values():
dep_ids.extend(value) dep_ids.extend(value)
if not dep_ids: if not dep_ids:
return deps_map, {} return deps_map, {}, tag_state_by_task_id
dep_status = await dependency_status_by_id( dep_status = await dependency_status_by_id(
session, session,
board_id=board_id, board_id=board_id,
dependency_ids=list({*dep_ids}), dependency_ids=list({*dep_ids}),
) )
return deps_map, dep_status return deps_map, dep_status, tag_state_by_task_id
def _task_event_payload( def _task_event_payload(
@@ -648,6 +666,7 @@ def _task_event_payload(
*, *,
deps_map: dict[UUID, list[UUID]], deps_map: dict[UUID, list[UUID]],
dep_status: dict[UUID, str], dep_status: dict[UUID, str],
tag_state_by_task_id: dict[UUID, TaskTagState],
) -> dict[str, object]: ) -> dict[str, object]:
payload: dict[str, object] = { payload: dict[str, object] = {
"type": event.event_type, "type": event.event_type,
@@ -660,6 +679,7 @@ def _task_event_payload(
payload["task"] = None payload["task"] = None
return payload return payload
tag_state = tag_state_by_task_id.get(task.id, TaskTagState())
dep_list = deps_map.get(task.id, []) dep_list = deps_map.get(task.id, [])
blocked_by = blocked_by_dependency_ids( blocked_by = blocked_by_dependency_ids(
dependency_ids=dep_list, dependency_ids=dep_list,
@@ -672,6 +692,8 @@ def _task_event_payload(
.model_copy( .model_copy(
update={ update={
"depends_on_task_ids": dep_list, "depends_on_task_ids": dep_list,
"tag_ids": tag_state.tag_ids,
"tags": tag_state.tags,
"blocked_by_task_ids": blocked_by, "blocked_by_task_ids": blocked_by,
"is_blocked": bool(blocked_by), "is_blocked": bool(blocked_by),
}, },
@@ -697,7 +719,7 @@ async def _task_event_generator(
async with async_session_maker() as session: async with async_session_maker() as session:
rows = await _fetch_task_events(session, board_id, last_seen) rows = await _fetch_task_events(session, board_id, last_seen)
deps_map, dep_status = await _stream_dependency_state( deps_map, dep_status, tag_state_by_task_id = await _stream_task_state(
session, session,
board_id=board_id, board_id=board_id,
rows=rows, rows=rows,
@@ -718,6 +740,7 @@ async def _task_event_generator(
task, task,
deps_map=deps_map, deps_map=deps_map,
dep_status=dep_status, dep_status=dep_status,
tag_state_by_task_id=tag_state_by_task_id,
) )
yield {"event": "task", "data": json.dumps(payload)} yield {"event": "task", "data": json.dumps(payload)}
await asyncio.sleep(2) await asyncio.sleep(2)
@@ -778,8 +801,9 @@ async def create_task(
auth: AuthContext = ADMIN_AUTH_DEP, auth: AuthContext = ADMIN_AUTH_DEP,
) -> TaskRead: ) -> TaskRead:
"""Create a task and initialize dependency rows.""" """Create a task and initialize dependency rows."""
data = payload.model_dump(exclude={"depends_on_task_ids"}) data = payload.model_dump(exclude={"depends_on_task_ids", "tag_ids"})
depends_on_task_ids = list(payload.depends_on_task_ids) depends_on_task_ids = list(payload.depends_on_task_ids)
tag_ids = list(payload.tag_ids)
task = Task.model_validate(data) task = Task.model_validate(data)
task.board_id = board.id task.board_id = board.id
@@ -792,6 +816,11 @@ async def create_task(
task_id=task.id, task_id=task.id,
depends_on_task_ids=depends_on_task_ids, depends_on_task_ids=depends_on_task_ids,
) )
normalized_tag_ids = await validate_task_tag_ids(
session,
organization_id=board.organization_id,
tag_ids=tag_ids,
)
dep_status = await dependency_status_by_id( dep_status = await dependency_status_by_id(
session, session,
board_id=board.id, board_id=board.id,
@@ -814,6 +843,11 @@ async def create_task(
depends_on_task_id=dep_id, depends_on_task_id=dep_id,
), ),
) )
await replace_task_tags(
session,
task_id=task.id,
tag_ids=normalized_tag_ids,
)
await session.commit() await session.commit()
await session.refresh(task) await session.refresh(task)
@@ -836,12 +870,10 @@ async def create_task(
task=task, task=task,
agent=assigned_agent, agent=assigned_agent,
) )
return TaskRead.model_validate(task, from_attributes=True).model_copy( return await _task_read_response(
update={ session,
"depends_on_task_ids": normalized_deps, task=task,
"blocked_by_task_ids": blocked_by, board_id=board.id,
"is_blocked": bool(blocked_by),
},
) )
@@ -876,8 +908,10 @@ async def update_task(
depends_on_task_ids = ( depends_on_task_ids = (
payload.depends_on_task_ids if "depends_on_task_ids" in payload.model_fields_set else None payload.depends_on_task_ids if "depends_on_task_ids" in payload.model_fields_set else None
) )
tag_ids = payload.tag_ids if "tag_ids" in payload.model_fields_set else None
updates.pop("comment", None) updates.pop("comment", None)
updates.pop("depends_on_task_ids", None) updates.pop("depends_on_task_ids", None)
updates.pop("tag_ids", None)
update = _TaskUpdateInput( update = _TaskUpdateInput(
task=task, task=task,
actor=actor, actor=actor,
@@ -887,6 +921,7 @@ async def update_task(
updates=updates, updates=updates,
comment=comment, comment=comment,
depends_on_task_ids=depends_on_task_ids, depends_on_task_ids=depends_on_task_ids,
tag_ids=tag_ids,
) )
if actor.actor_type == "agent" and actor.agent and actor.agent.is_board_lead: if actor.actor_type == "agent" and actor.agent and actor.agent.is_board_lead:
return await _apply_lead_task_update(session, update=update) return await _apply_lead_task_update(session, update=update)
@@ -957,6 +992,12 @@ async def delete_task(
), ),
commit=False, commit=False,
) )
await crud.delete_where(
session,
TaskTagAssignment,
col(TaskTagAssignment.task_id) == task.id,
commit=False,
)
await session.delete(task) await session.delete(task)
await session.commit() await session.commit()
return OkResponse() return OkResponse()
@@ -1119,6 +1160,8 @@ class _TaskUpdateInput:
updates: dict[str, object] updates: dict[str, object]
comment: str | None comment: str | None
depends_on_task_ids: list[UUID] | None depends_on_task_ids: list[UUID] | None
tag_ids: list[UUID] | None
normalized_tag_ids: list[UUID] | None = None
def _required_status_value(value: object) -> str: def _required_status_value(value: object) -> str:
@@ -1133,6 +1176,21 @@ def _optional_assigned_agent_id(value: object) -> UUID | None:
raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY) raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY)
async def _board_organization_id(
session: AsyncSession,
*,
board_id: UUID,
) -> UUID:
organization_id = (
await session.exec(
select(Board.organization_id).where(col(Board.id) == board_id),
)
).first()
if organization_id is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
return organization_id
async def _task_dep_ids( async def _task_dep_ids(
session: AsyncSession, session: AsyncSession,
*, *,
@@ -1173,6 +1231,10 @@ async def _task_read_response(
board_id: UUID, board_id: UUID,
) -> TaskRead: ) -> TaskRead:
dep_ids = await _task_dep_ids(session, board_id=board_id, task_id=task.id) dep_ids = await _task_dep_ids(session, board_id=board_id, task_id=task.id)
tag_state = (await load_task_tag_state(session, task_ids=[task.id])).get(
task.id,
TaskTagState(),
)
blocked_ids = await _task_blocked_ids( blocked_ids = await _task_blocked_ids(
session, session,
board_id=board_id, board_id=board_id,
@@ -1183,6 +1245,8 @@ async def _task_read_response(
return TaskRead.model_validate(task, from_attributes=True).model_copy( return TaskRead.model_validate(task, from_attributes=True).model_copy(
update={ update={
"depends_on_task_ids": dep_ids, "depends_on_task_ids": dep_ids,
"tag_ids": tag_state.tag_ids,
"tags": tag_state.tags,
"blocked_by_task_ids": blocked_ids, "blocked_by_task_ids": blocked_ids,
"is_blocked": bool(blocked_ids), "is_blocked": bool(blocked_ids),
}, },
@@ -1209,11 +1273,13 @@ def _lead_requested_fields(update: _TaskUpdateInput) -> set[str]:
requested_fields.add("comment") requested_fields.add("comment")
if update.depends_on_task_ids is not None: if update.depends_on_task_ids is not None:
requested_fields.add("depends_on_task_ids") requested_fields.add("depends_on_task_ids")
if update.tag_ids is not None:
requested_fields.add("tag_ids")
return requested_fields return requested_fields
def _validate_lead_update_request(update: _TaskUpdateInput) -> None: def _validate_lead_update_request(update: _TaskUpdateInput) -> None:
allowed_fields = {"assigned_agent_id", "status", "depends_on_task_ids"} allowed_fields = {"assigned_agent_id", "status", "depends_on_task_ids", "tag_ids"}
requested_fields = _lead_requested_fields(update) requested_fields = _lead_requested_fields(update)
if update.comment is not None or not requested_fields.issubset(allowed_fields): if update.comment is not None or not requested_fields.issubset(allowed_fields):
raise HTTPException( raise HTTPException(
@@ -1260,6 +1326,24 @@ async def _lead_effective_dependencies(
return effective_deps, blocked_by return effective_deps, blocked_by
async def _normalized_update_tag_ids(
session: AsyncSession,
*,
update: _TaskUpdateInput,
) -> list[UUID] | None:
if update.tag_ids is None:
return None
organization_id = await _board_organization_id(
session,
board_id=update.board_id,
)
return await validate_task_tag_ids(
session,
organization_id=organization_id,
tag_ids=update.tag_ids,
)
async def _lead_apply_assignment( async def _lead_apply_assignment(
session: AsyncSession, session: AsyncSession,
*, *,
@@ -1351,6 +1435,10 @@ async def _apply_lead_task_update(
session, session,
update=update, update=update,
) )
normalized_tag_ids = await _normalized_update_tag_ids(
session,
update=update,
)
if blocked_by and update.task.status != "done": if blocked_by and update.task.status != "done":
update.task.status = "inbox" update.task.status = "inbox"
@@ -1360,6 +1448,13 @@ async def _apply_lead_task_update(
await _lead_apply_assignment(session, update=update) await _lead_apply_assignment(session, update=update)
_lead_apply_status(update) _lead_apply_status(update)
if normalized_tag_ids is not None:
await replace_task_tags(
session,
task_id=update.task.id,
tag_ids=normalized_tag_ids,
)
update.task.updated_at = utcnow() update.task.updated_at = utcnow()
session.add(update.task) session.add(update.task)
event_type, message = _task_event_details(update.task, update.previous_status) event_type, message = _task_event_details(update.task, update.previous_status)
@@ -1402,8 +1497,12 @@ async def _apply_non_lead_agent_task_rules(
): ):
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN) raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
allowed_fields = {"status", "comment"} allowed_fields = {"status", "comment"}
if update.depends_on_task_ids is not None or not set(update.updates).issubset( if (
allowed_fields, update.depends_on_task_ids is not None
or update.tag_ids is not None
or not set(update.updates).issubset(
allowed_fields,
)
): ):
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN) raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
if "status" in update.updates: if "status" in update.updates:
@@ -1436,6 +1535,10 @@ async def _apply_admin_task_rules(
update: _TaskUpdateInput, update: _TaskUpdateInput,
) -> None: ) -> None:
admin_normalized_deps: list[UUID] | None = None admin_normalized_deps: list[UUID] | None = None
update.normalized_tag_ids = await _normalized_update_tag_ids(
session,
update=update,
)
if update.depends_on_task_ids is not None: if update.depends_on_task_ids is not None:
if update.task.status == "done": if update.task.status == "done":
raise HTTPException( raise HTTPException(
@@ -1611,6 +1714,21 @@ async def _finalize_updated_task(
): ):
raise _comment_validation_error() raise _comment_validation_error()
if update.tag_ids is not None:
normalized = (
update.normalized_tag_ids
if update.normalized_tag_ids is not None
else await _normalized_update_tag_ids(
session,
update=update,
)
)
await replace_task_tags(
session,
task_id=update.task.id,
tag_ids=normalized or [],
)
session.add(update.task) session.add(update.task)
await session.commit() await session.commit()
await session.refresh(update.task) await session.refresh(update.task)

View File

@@ -24,6 +24,7 @@ from app.api.gateways import router as gateways_router
from app.api.metrics import router as metrics_router from app.api.metrics import router as metrics_router
from app.api.organizations import router as organizations_router from app.api.organizations import router as organizations_router
from app.api.souls_directory import router as souls_directory_router from app.api.souls_directory import router as souls_directory_router
from app.api.task_tags import router as task_tags_router
from app.api.tasks import router as tasks_router from app.api.tasks import router as tasks_router
from app.api.users import router as users_router from app.api.users import router as users_router
from app.core.config import settings from app.core.config import settings
@@ -107,6 +108,7 @@ api_v1.include_router(board_memory_router)
api_v1.include_router(board_onboarding_router) api_v1.include_router(board_onboarding_router)
api_v1.include_router(approvals_router) api_v1.include_router(approvals_router)
api_v1.include_router(tasks_router) api_v1.include_router(tasks_router)
api_v1.include_router(task_tags_router)
api_v1.include_router(users_router) api_v1.include_router(users_router)
app.include_router(api_v1) app.include_router(api_v1)

View File

@@ -17,6 +17,8 @@ from app.models.organization_members import OrganizationMember
from app.models.organizations import Organization from app.models.organizations import Organization
from app.models.task_dependencies import TaskDependency from app.models.task_dependencies import TaskDependency
from app.models.task_fingerprints import TaskFingerprint from app.models.task_fingerprints import TaskFingerprint
from app.models.task_tag_assignments import TaskTagAssignment
from app.models.task_tags import TaskTag
from app.models.tasks import Task from app.models.tasks import Task
from app.models.users import User from app.models.users import User
@@ -39,5 +41,7 @@ __all__ = [
"TaskDependency", "TaskDependency",
"Task", "Task",
"TaskFingerprint", "TaskFingerprint",
"TaskTag",
"TaskTagAssignment",
"User", "User",
] ]

View File

@@ -0,0 +1,32 @@
"""Task/tag many-to-many link rows."""
from __future__ import annotations
from datetime import datetime
from uuid import UUID, uuid4
from sqlalchemy import UniqueConstraint
from sqlmodel import Field
from app.core.time import utcnow
from app.models.base import QueryModel
RUNTIME_ANNOTATION_TYPES = (datetime,)
class TaskTagAssignment(QueryModel, table=True):
"""Association row mapping one task to one tag."""
__tablename__ = "task_tag_assignments" # pyright: ignore[reportAssignmentType]
__table_args__ = (
UniqueConstraint(
"task_id",
"tag_id",
name="uq_task_tag_assignments_task_id_tag_id",
),
)
id: UUID = Field(default_factory=uuid4, primary_key=True)
task_id: UUID = Field(foreign_key="tasks.id", index=True)
tag_id: UUID = Field(foreign_key="task_tags.id", index=True)
created_at: datetime = Field(default_factory=utcnow)

View File

@@ -0,0 +1,36 @@
"""Task tag model for organization-scoped task categorization."""
from __future__ import annotations
from datetime import datetime
from uuid import UUID, uuid4
from sqlalchemy import UniqueConstraint
from sqlmodel import Field
from app.core.time import utcnow
from app.models.tenancy import TenantScoped
RUNTIME_ANNOTATION_TYPES = (datetime,)
class TaskTag(TenantScoped, table=True):
"""Organization-scoped task tag used to classify and group tasks."""
__tablename__ = "task_tags" # pyright: ignore[reportAssignmentType]
__table_args__ = (
UniqueConstraint(
"organization_id",
"slug",
name="uq_task_tags_organization_id_slug",
),
)
id: UUID = Field(default_factory=uuid4, primary_key=True)
organization_id: UUID = Field(foreign_key="organizations.id", index=True)
name: str
slug: str = Field(index=True)
color: str = Field(default="9e9e9e")
description: str | None = None
created_at: datetime = Field(default_factory=utcnow)
updated_at: datetime = Field(default_factory=utcnow)

View File

@@ -31,6 +31,7 @@ from app.schemas.souls_directory import (
SoulsDirectorySearchResponse, SoulsDirectorySearchResponse,
SoulsDirectorySoulRef, SoulsDirectorySoulRef,
) )
from app.schemas.task_tags import TaskTagCreate, TaskTagRead, TaskTagRef, TaskTagUpdate
from app.schemas.tasks import TaskCreate, TaskRead, TaskUpdate from app.schemas.tasks import TaskCreate, TaskRead, TaskUpdate
from app.schemas.users import UserCreate, UserRead, UserUpdate from app.schemas.users import UserCreate, UserRead, UserUpdate
@@ -70,6 +71,10 @@ __all__ = [
"SoulsDirectoryMarkdownResponse", "SoulsDirectoryMarkdownResponse",
"SoulsDirectorySearchResponse", "SoulsDirectorySearchResponse",
"SoulsDirectorySoulRef", "SoulsDirectorySoulRef",
"TaskTagCreate",
"TaskTagRead",
"TaskTagRef",
"TaskTagUpdate",
"TaskCreate", "TaskCreate",
"TaskRead", "TaskRead",
"TaskUpdate", "TaskUpdate",

View File

@@ -0,0 +1,126 @@
"""Schemas for task-tag CRUD payloads."""
from __future__ import annotations
import re
from datetime import datetime
from typing import Self
from uuid import UUID
from pydantic import field_validator, model_validator
from sqlmodel import SQLModel
from app.schemas.common import NonEmptyStr
HEX_COLOR_RE = re.compile(r"^[0-9a-f]{6}$")
RUNTIME_ANNOTATION_TYPES = (datetime, UUID, NonEmptyStr)
def _normalize_color(value: str | None) -> str | None:
if value is None:
return None
cleaned = value.strip().lower().lstrip("#")
if not cleaned:
return None
if not HEX_COLOR_RE.fullmatch(cleaned):
raise ValueError("color must be a 6-digit hex value")
return cleaned
class TaskTagBase(SQLModel):
"""Shared task-tag fields for create/read payloads."""
name: str
slug: str
color: str = "9e9e9e"
description: str | None = None
class TaskTagRef(SQLModel):
"""Compact task-tag representation embedded in task payloads."""
id: UUID
name: str
slug: str
color: str
class TaskTagCreate(SQLModel):
"""Payload for creating a task tag."""
name: NonEmptyStr
slug: str | None = None
color: str = "9e9e9e"
description: str | None = None
@field_validator("slug", mode="before")
@classmethod
def normalize_slug(cls, value: object) -> object | None:
"""Treat empty slug strings as unset so API can auto-generate."""
if value is None:
return None
if isinstance(value, str):
cleaned = value.strip()
return cleaned or None
return value
@field_validator("color", mode="before")
@classmethod
def normalize_color(cls, value: object) -> object:
"""Normalize color to lowercase hex without a leading hash."""
if isinstance(value, str):
normalized = _normalize_color(value)
if normalized is None:
raise ValueError("color is required")
return normalized
return value
class TaskTagUpdate(SQLModel):
"""Payload for partial task-tag updates."""
name: NonEmptyStr | None = None
slug: str | None = None
color: str | None = None
description: str | None = None
@field_validator("slug", mode="before")
@classmethod
def normalize_slug(cls, value: object) -> object | None:
"""Treat empty slug strings as unset so API can auto-generate."""
if value is None:
return None
if isinstance(value, str):
cleaned = value.strip()
return cleaned or None
return value
@field_validator("color", mode="before")
@classmethod
def normalize_color(cls, value: object) -> object | None:
"""Normalize color to lowercase hex without a leading hash."""
if value is None:
return None
if isinstance(value, str):
normalized = _normalize_color(value)
if normalized is None:
raise ValueError("color must be a 6-digit hex value")
return normalized
return value
@model_validator(mode="after")
def require_some_update(self) -> Self:
"""Reject empty update payloads to avoid no-op patch calls."""
if not self.model_fields_set:
raise ValueError("At least one field is required")
return self
class TaskTagRead(TaskTagBase):
"""Task-tag payload returned from API endpoints."""
id: UUID
organization_id: UUID
task_count: int = 0
created_at: datetime
updated_at: datetime

View File

@@ -10,12 +10,13 @@ from pydantic import field_validator, model_validator
from sqlmodel import Field, SQLModel from sqlmodel import Field, SQLModel
from app.schemas.common import NonEmptyStr from app.schemas.common import NonEmptyStr
from app.schemas.task_tags import TaskTagRef
TaskStatus = Literal["inbox", "in_progress", "review", "done"] TaskStatus = Literal["inbox", "in_progress", "review", "done"]
STATUS_REQUIRED_ERROR = "status is required" STATUS_REQUIRED_ERROR = "status is required"
# Keep these symbols as runtime globals so Pydantic can resolve # Keep these symbols as runtime globals so Pydantic can resolve
# deferred annotations reliably. # deferred annotations reliably.
RUNTIME_ANNOTATION_TYPES = (datetime, UUID, NonEmptyStr) RUNTIME_ANNOTATION_TYPES = (datetime, UUID, NonEmptyStr, TaskTagRef)
class TaskBase(SQLModel): class TaskBase(SQLModel):
@@ -28,6 +29,7 @@ class TaskBase(SQLModel):
due_at: datetime | None = None due_at: datetime | None = None
assigned_agent_id: UUID | None = None assigned_agent_id: UUID | None = None
depends_on_task_ids: list[UUID] = Field(default_factory=list) depends_on_task_ids: list[UUID] = Field(default_factory=list)
tag_ids: list[UUID] = Field(default_factory=list)
class TaskCreate(TaskBase): class TaskCreate(TaskBase):
@@ -46,6 +48,7 @@ class TaskUpdate(SQLModel):
due_at: datetime | None = None due_at: datetime | None = None
assigned_agent_id: UUID | None = None assigned_agent_id: UUID | None = None
depends_on_task_ids: list[UUID] | None = None depends_on_task_ids: list[UUID] | None = None
tag_ids: list[UUID] | None = None
comment: NonEmptyStr | None = None comment: NonEmptyStr | None = None
@field_validator("comment", mode="before") @field_validator("comment", mode="before")
@@ -77,6 +80,7 @@ class TaskRead(TaskBase):
updated_at: datetime updated_at: datetime
blocked_by_task_ids: list[UUID] = Field(default_factory=list) blocked_by_task_ids: list[UUID] = Field(default_factory=list)
is_blocked: bool = False is_blocked: bool = False
tags: list[TaskTagRef] = Field(default_factory=list)
class TaskCommentCreate(SQLModel): class TaskCommentCreate(SQLModel):

View File

@@ -12,6 +12,7 @@ from app.schemas.approvals import ApprovalRead
from app.schemas.board_groups import BoardGroupRead from app.schemas.board_groups import BoardGroupRead
from app.schemas.board_memory import BoardMemoryRead from app.schemas.board_memory import BoardMemoryRead
from app.schemas.boards import BoardRead from app.schemas.boards import BoardRead
from app.schemas.task_tags import TaskTagRef
from app.schemas.tasks import TaskRead from app.schemas.tasks import TaskRead
RUNTIME_ANNOTATION_TYPES = ( RUNTIME_ANNOTATION_TYPES = (
@@ -22,6 +23,7 @@ RUNTIME_ANNOTATION_TYPES = (
BoardGroupRead, BoardGroupRead,
BoardMemoryRead, BoardMemoryRead,
BoardRead, BoardRead,
TaskTagRef,
) )
@@ -57,6 +59,7 @@ class BoardGroupTaskSummary(SQLModel):
assignee: str | None = None assignee: str | None = None
due_at: datetime | None = None due_at: datetime | None = None
in_progress_at: datetime | None = None in_progress_at: datetime | None = None
tags: list[TaskTagRef] = Field(default_factory=list)
created_at: datetime created_at: datetime
updated_at: datetime updated_at: datetime

View File

@@ -21,6 +21,7 @@ from app.schemas.view_models import (
BoardGroupSnapshot, BoardGroupSnapshot,
BoardGroupTaskSummary, BoardGroupTaskSummary,
) )
from app.services.task_tags import TaskTagState, load_task_tag_state
if TYPE_CHECKING: if TYPE_CHECKING:
from sqlalchemy.sql.elements import ColumnElement from sqlalchemy.sql.elements import ColumnElement
@@ -122,6 +123,7 @@ def _task_summaries_by_board(
boards_by_id: dict[UUID, Board], boards_by_id: dict[UUID, Board],
tasks: list[Task], tasks: list[Task],
agent_name_by_id: dict[UUID, str], agent_name_by_id: dict[UUID, str],
tag_state_by_task_id: dict[UUID, TaskTagState],
per_board_task_limit: int, per_board_task_limit: int,
) -> dict[UUID, list[BoardGroupTaskSummary]]: ) -> dict[UUID, list[BoardGroupTaskSummary]]:
"""Build limited per-board task summary lists.""" """Build limited per-board task summary lists."""
@@ -138,6 +140,7 @@ def _task_summaries_by_board(
if board is None: if board is None:
continue continue
current.append( current.append(
# Include tags so cross-board snapshots can be grouped quickly in the UI.
BoardGroupTaskSummary( BoardGroupTaskSummary(
id=task.id, id=task.id,
board_id=task.board_id, board_id=task.board_id,
@@ -153,6 +156,7 @@ def _task_summaries_by_board(
), ),
due_at=task.due_at, due_at=task.due_at,
in_progress_at=task.in_progress_at, in_progress_at=task.in_progress_at,
tags=tag_state_by_task_id.get(task.id, TaskTagState()).tags,
created_at=task.created_at, created_at=task.created_at,
updated_at=task.updated_at, updated_at=task.updated_at,
), ),
@@ -187,10 +191,15 @@ async def build_group_snapshot(
include_done=include_done, include_done=include_done,
) )
agent_name_by_id = await _agent_names(session, tasks) agent_name_by_id = await _agent_names(session, tasks)
tag_state_by_task_id = await load_task_tag_state(
session,
task_ids=[task.id for task in tasks],
)
tasks_by_board = _task_summaries_by_board( tasks_by_board = _task_summaries_by_board(
boards_by_id=boards_by_id, boards_by_id=boards_by_id,
tasks=tasks, tasks=tasks,
agent_name_by_id=agent_name_by_id, agent_name_by_id=agent_name_by_id,
tag_state_by_task_id=tag_state_by_task_id,
per_board_task_limit=per_board_task_limit, per_board_task_limit=per_board_task_limit,
) )
snapshots = [ snapshots = [

View File

@@ -22,6 +22,7 @@ from app.services.task_dependencies import (
dependency_ids_by_task_id, dependency_ids_by_task_id,
dependency_status_by_id, dependency_status_by_id,
) )
from app.services.task_tags import TaskTagState, load_task_tag_state
if TYPE_CHECKING: if TYPE_CHECKING:
from uuid import UUID from uuid import UUID
@@ -48,11 +49,13 @@ def _task_to_card(
counts_by_task_id: dict[UUID, tuple[int, int]], counts_by_task_id: dict[UUID, tuple[int, int]],
deps_by_task_id: dict[UUID, list[UUID]], deps_by_task_id: dict[UUID, list[UUID]],
dependency_status_by_id_map: dict[UUID, str], dependency_status_by_id_map: dict[UUID, str],
tag_state_by_task_id: dict[UUID, TaskTagState],
) -> TaskCardRead: ) -> TaskCardRead:
card = TaskCardRead.model_validate(task, from_attributes=True) card = TaskCardRead.model_validate(task, from_attributes=True)
approvals_count, approvals_pending_count = counts_by_task_id.get(task.id, (0, 0)) approvals_count, approvals_pending_count = counts_by_task_id.get(task.id, (0, 0))
assignee = agent_name_by_id.get(task.assigned_agent_id) if task.assigned_agent_id else None assignee = agent_name_by_id.get(task.assigned_agent_id) if task.assigned_agent_id else None
depends_on_task_ids = deps_by_task_id.get(task.id, []) depends_on_task_ids = deps_by_task_id.get(task.id, [])
tag_state = tag_state_by_task_id.get(task.id, TaskTagState())
blocked_by_task_ids = blocked_by_dependency_ids( blocked_by_task_ids = blocked_by_dependency_ids(
dependency_ids=depends_on_task_ids, dependency_ids=depends_on_task_ids,
status_by_id=dependency_status_by_id_map, status_by_id=dependency_status_by_id_map,
@@ -65,6 +68,8 @@ def _task_to_card(
"approvals_count": approvals_count, "approvals_count": approvals_count,
"approvals_pending_count": approvals_pending_count, "approvals_pending_count": approvals_pending_count,
"depends_on_task_ids": depends_on_task_ids, "depends_on_task_ids": depends_on_task_ids,
"tag_ids": tag_state.tag_ids,
"tags": tag_state.tags,
"blocked_by_task_ids": blocked_by_task_ids, "blocked_by_task_ids": blocked_by_task_ids,
"is_blocked": bool(blocked_by_task_ids), "is_blocked": bool(blocked_by_task_ids),
}, },
@@ -81,6 +86,10 @@ async def build_board_snapshot(session: AsyncSession, board: Board) -> BoardSnap
.all(session), .all(session),
) )
task_ids = [task.id for task in tasks] task_ids = [task.id for task in tasks]
tag_state_by_task_id = await load_task_tag_state(
session,
task_ids=task_ids,
)
deps_by_task_id = await dependency_ids_by_task_id( deps_by_task_id = await dependency_ids_by_task_id(
session, session,
@@ -148,6 +157,7 @@ async def build_board_snapshot(session: AsyncSession, board: Board) -> BoardSnap
counts_by_task_id=counts_by_task_id, counts_by_task_id=counts_by_task_id,
deps_by_task_id=deps_by_task_id, deps_by_task_id=deps_by_task_id,
dependency_status_by_id_map=dependency_status_by_id_map, dependency_status_by_id_map=dependency_status_by_id_map,
tag_state_by_task_id=tag_state_by_task_id,
) )
for task in tasks for task in tasks
] ]

View File

@@ -0,0 +1,158 @@
"""Helpers for validating and loading task tags and task-tag mappings."""
from __future__ import annotations
import re
from collections import defaultdict
from collections.abc import Sequence
from dataclasses import dataclass, field
from typing import TYPE_CHECKING
from uuid import UUID
from fastapi import HTTPException, status
from sqlalchemy import delete, func
from sqlmodel import col, select
from app.models.task_tag_assignments import TaskTagAssignment
from app.models.task_tags import TaskTag
from app.schemas.task_tags import TaskTagRef
if TYPE_CHECKING:
from sqlmodel.ext.asyncio.session import AsyncSession
SLUG_RE = re.compile(r"[^a-z0-9]+")
def slugify_task_tag(value: str) -> str:
"""Build a slug from arbitrary text using lowercase alphanumeric groups."""
slug = SLUG_RE.sub("-", value.lower()).strip("-")
return slug or "tag"
def _dedupe_uuid_list(values: Sequence[UUID]) -> list[UUID]:
deduped: list[UUID] = []
seen: set[UUID] = set()
for value in values:
if value in seen:
continue
seen.add(value)
deduped.append(value)
return deduped
async def validate_task_tag_ids(
session: AsyncSession,
*,
organization_id: UUID,
tag_ids: Sequence[UUID],
) -> list[UUID]:
"""Validate task-tag IDs within an organization and return deduped IDs."""
normalized = _dedupe_uuid_list(tag_ids)
if not normalized:
return []
existing_ids = set(
await session.exec(
select(TaskTag.id)
.where(col(TaskTag.organization_id) == organization_id)
.where(col(TaskTag.id).in_(normalized)),
),
)
missing = [tag_id for tag_id in normalized if tag_id not in existing_ids]
if missing:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail={
"message": "One or more task tags do not exist in this organization.",
"missing_tag_ids": [str(tag_id) for tag_id in missing],
},
)
return normalized
@dataclass(slots=True)
class TaskTagState:
"""Ordered task-tag state for a task payload."""
tag_ids: list[UUID] = field(default_factory=list)
tags: list[TaskTagRef] = field(default_factory=list)
async def load_task_tag_state(
session: AsyncSession,
*,
task_ids: Sequence[UUID],
) -> dict[UUID, TaskTagState]:
"""Return ordered tag IDs and refs for each task id."""
normalized_task_ids = _dedupe_uuid_list(task_ids)
if not normalized_task_ids:
return {}
rows = list(
await session.exec(
select(
col(TaskTagAssignment.task_id),
TaskTag,
)
.join(TaskTag, col(TaskTag.id) == col(TaskTagAssignment.tag_id))
.where(col(TaskTagAssignment.task_id).in_(normalized_task_ids))
.order_by(
col(TaskTagAssignment.task_id).asc(),
col(TaskTagAssignment.created_at).asc(),
),
),
)
state_by_task_id: dict[UUID, TaskTagState] = defaultdict(TaskTagState)
for task_id, tag in rows:
if task_id is None:
continue
state = state_by_task_id[task_id]
state.tag_ids.append(tag.id)
state.tags.append(
TaskTagRef(
id=tag.id,
name=tag.name,
slug=tag.slug,
color=tag.color,
),
)
return dict(state_by_task_id)
async def replace_task_tags(
session: AsyncSession,
*,
task_id: UUID,
tag_ids: Sequence[UUID],
) -> None:
"""Replace all tag-assignment rows for a task."""
normalized = _dedupe_uuid_list(tag_ids)
await session.exec(
delete(TaskTagAssignment).where(
col(TaskTagAssignment.task_id) == task_id,
),
)
for tag_id in normalized:
session.add(TaskTagAssignment(task_id=task_id, tag_id=tag_id))
async def task_counts_for_tags(
session: AsyncSession,
*,
tag_ids: Sequence[UUID],
) -> dict[UUID, int]:
"""Return count of tagged tasks per tag id."""
normalized = _dedupe_uuid_list(tag_ids)
if not normalized:
return {}
rows = list(
await session.exec(
select(
col(TaskTagAssignment.tag_id),
func.count(col(TaskTagAssignment.task_id)),
)
.where(col(TaskTagAssignment.tag_id).in_(normalized))
.group_by(col(TaskTagAssignment.tag_id)),
),
)
return {tag_id: int(count or 0) for tag_id, count in rows}

View File

@@ -0,0 +1,101 @@
"""add task tags and task-tag assignments
Revision ID: d8c1e5a4f7b2
Revises: 99cd6df95f85, b4338be78eec
Create Date: 2026-02-12 16:05:00.000000
"""
from __future__ import annotations
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision = "d8c1e5a4f7b2"
down_revision = ("99cd6df95f85", "b4338be78eec")
branch_labels = None
depends_on = None
def upgrade() -> None:
bind = op.get_bind()
inspector = sa.inspect(bind)
if not inspector.has_table("tags"):
op.create_table(
"tags",
sa.Column("id", sa.Uuid(), nullable=False),
sa.Column("organization_id", sa.Uuid(), nullable=False),
sa.Column("name", sa.String(), nullable=False),
sa.Column("slug", sa.String(), nullable=False),
sa.Column("color", sa.String(), nullable=False),
sa.Column("description", sa.String(), nullable=True),
sa.Column("created_at", sa.DateTime(), nullable=False),
sa.Column("updated_at", sa.DateTime(), nullable=False),
sa.ForeignKeyConstraint(["organization_id"], ["organizations.id"]),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint(
"organization_id",
"slug",
name="uq_task_tags_organization_id_slug",
),
)
task_tag_indexes = {item.get("name") for item in inspector.get_indexes("tags")}
if op.f("ix_task_tags_organization_id") not in task_tag_indexes:
op.create_index(
op.f("ix_task_tags_organization_id"),
"tags",
["organization_id"],
unique=False,
)
if op.f("ix_task_tags_slug") not in task_tag_indexes:
op.create_index(
op.f("ix_task_tags_slug"),
"tags",
["slug"],
unique=False,
)
if not inspector.has_table("task_tag_assignments"):
op.create_table(
"task_tag_assignments",
sa.Column("id", sa.Uuid(), nullable=False),
sa.Column("task_id", sa.Uuid(), nullable=False),
sa.Column("tag_id", sa.Uuid(), nullable=False),
sa.Column("created_at", sa.DateTime(), nullable=False),
sa.ForeignKeyConstraint(["tag_id"], ["tags.id"]),
sa.ForeignKeyConstraint(["task_id"], ["tasks.id"]),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint(
"task_id",
"tag_id",
name="uq_task_tag_assignments_task_id_tag_id",
),
)
assignment_indexes = {
item.get("name") for item in inspector.get_indexes("task_tag_assignments")
}
if op.f("ix_task_tag_assignments_task_id") not in assignment_indexes:
op.create_index(
op.f("ix_task_tag_assignments_task_id"),
"task_tag_assignments",
["task_id"],
unique=False,
)
if op.f("ix_task_tag_assignments_tag_id") not in assignment_indexes:
op.create_index(
op.f("ix_task_tag_assignments_tag_id"),
"task_tag_assignments",
["tag_id"],
unique=False,
)
def downgrade() -> None:
op.drop_index(op.f("ix_task_tag_assignments_tag_id"), table_name="task_tag_assignments")
op.drop_index(op.f("ix_task_tag_assignments_task_id"), table_name="task_tag_assignments")
op.drop_table("task_tag_assignments")
op.drop_index(op.f("ix_task_tags_slug"), table_name="tags")
op.drop_index(op.f("ix_task_tags_organization_id"), table_name="tags")
op.drop_table("tags")

View File

@@ -146,6 +146,7 @@ run a short intake with the human in **board chat**.
2) Review recent tasks/comments and board memory: 2) Review recent tasks/comments and board memory:
- GET $BASE_URL/api/v1/agent/boards/$BOARD_ID/tasks?limit=50 - GET $BASE_URL/api/v1/agent/boards/$BOARD_ID/tasks?limit=50
- GET $BASE_URL/api/v1/agent/boards/$BOARD_ID/tags
- GET $BASE_URL/api/v1/agent/boards/$BOARD_ID/memory?limit=50 - GET $BASE_URL/api/v1/agent/boards/$BOARD_ID/memory?limit=50
- GET $BASE_URL/api/v1/agent/agents?board_id=$BOARD_ID - GET $BASE_URL/api/v1/agent/agents?board_id=$BOARD_ID
- For any task in **review**, fetch its comments: - For any task in **review**, fetch its comments:
@@ -274,9 +275,13 @@ Body: {"depends_on_task_ids":["DEP_TASK_ID_1","DEP_TASK_ID_2"]}
7) Creating new tasks: 7) Creating new tasks:
- Before creating any task or approval, run the de-duplication pass (step 2a). If a similar task already exists, merge/split scope there instead of creating a duplicate. - Before creating any task or approval, run the de-duplication pass (step 2a). If a similar task already exists, merge/split scope there instead of creating a duplicate.
- Leads **can** create tasks directly when confidence >= 70 and the action is not risky/external. - Leads **can** create tasks directly when confidence >= 70 and the action is not risky/external.
- If task tags are configured (`GET /api/v1/agent/boards/$BOARD_ID/tags` returns items), choose the most relevant tags and include their ids in `tag_ids`.
- Build and keep a local map: `slug/name -> tag_id`.
- Prefer 1-3 tags per task; avoid over-tagging.
- If no existing tag fits, set `tag_ids: []` and leave a short note in your plan/comment so admins can add a missing tag later.
POST $BASE_URL/api/v1/agent/boards/$BOARD_ID/tasks POST $BASE_URL/api/v1/agent/boards/$BOARD_ID/tasks
Body example: Body example:
{"title":"...","description":"...","priority":"high","status":"inbox","assigned_agent_id":null,"depends_on_task_ids":["DEP_TASK_ID"]} {"title":"...","description":"...","priority":"high","status":"inbox","assigned_agent_id":null,"depends_on_task_ids":["DEP_TASK_ID"],"tag_ids":["TAG_ID_1","TAG_ID_2"]}
- Task descriptions must be written in clear markdown (short sections, bullets/checklists when helpful). - Task descriptions must be written in clear markdown (short sections, bullets/checklists when helpful).
- If the task depends on other tasks, always set `depends_on_task_ids`. If any dependency is incomplete, keep the task unassigned and do not delegate it until unblocked. - If the task depends on other tasks, always set `depends_on_task_ids`. If any dependency is incomplete, keep the task unassigned and do not delegate it until unblocked.
- If confidence < 70 or the action is risky/external, request approval instead: - If confidence < 70 or the action is risky/external, request approval instead:

View File

@@ -0,0 +1,99 @@
from __future__ import annotations
from dataclasses import dataclass
from uuid import UUID, uuid4
import pytest
from fastapi import HTTPException
from app.api import agent as agent_api
from app.core.agent_auth import AgentAuthContext
from app.models.agents import Agent
from app.models.boards import Board
from app.models.task_tags import TaskTag
@dataclass
class _FakeExecResult:
tags: list[TaskTag]
def all(self) -> list[TaskTag]:
return self.tags
@dataclass
class _FakeSession:
tags: list[TaskTag]
async def exec(self, _query: object) -> _FakeExecResult:
return _FakeExecResult(self.tags)
def _board() -> Board:
return Board(
id=uuid4(),
organization_id=uuid4(),
name="Delivery",
slug="delivery",
)
def _agent_ctx(*, board_id: UUID | None) -> AgentAuthContext:
return AgentAuthContext(
actor_type="agent",
agent=Agent(
id=uuid4(),
board_id=board_id,
gateway_id=uuid4(),
name="Lead",
is_board_lead=True,
),
)
@pytest.mark.asyncio
async def test_list_task_tags_returns_task_tag_refs() -> None:
board = _board()
session = _FakeSession(
tags=[
TaskTag(
id=uuid4(),
organization_id=board.organization_id,
name="Backend",
slug="backend",
color="0f172a",
),
TaskTag(
id=uuid4(),
organization_id=board.organization_id,
name="Urgent",
slug="urgent",
color="dc2626",
),
],
)
response = await agent_api.list_task_tags(
board=board,
session=session, # type: ignore[arg-type]
agent_ctx=_agent_ctx(board_id=board.id),
)
assert [tag.slug for tag in response] == ["backend", "urgent"]
assert response[0].name == "Backend"
assert response[1].color == "dc2626"
@pytest.mark.asyncio
async def test_list_task_tags_rejects_cross_board_agent() -> None:
board = _board()
session = _FakeSession(tags=[])
with pytest.raises(HTTPException) as exc:
await agent_api.list_task_tags(
board=board,
session=session, # type: ignore[arg-type]
agent_ctx=_agent_ctx(board_id=uuid4()),
)
assert exc.value.status_code == 403

View File

@@ -0,0 +1,128 @@
# ruff: noqa
from __future__ import annotations
from dataclasses import dataclass, field
from uuid import uuid4
import pytest
from app.models.task_tags import TaskTag
from app.services import task_tags
@dataclass
class _FakeSession:
exec_results: list[object]
executed: list[object] = field(default_factory=list)
added: list[object] = field(default_factory=list)
async def exec(self, query):
self.executed.append(query)
if not self.exec_results:
raise AssertionError("No more exec_results left for session.exec")
return self.exec_results.pop(0)
def add(self, value):
self.added.append(value)
def test_slugify_task_tag_normalizes_text():
assert task_tags.slugify_task_tag("Release / QA") == "release-qa"
assert task_tags.slugify_task_tag(" ### ") == "tag"
@pytest.mark.asyncio
async def test_validate_task_tag_ids_dedupes_and_preserves_order():
org_id = uuid4()
tag_a = uuid4()
tag_b = uuid4()
session = _FakeSession(exec_results=[{tag_a, tag_b}])
result = await task_tags.validate_task_tag_ids(
session,
organization_id=org_id,
tag_ids=[tag_a, tag_b, tag_a],
)
assert result == [tag_a, tag_b]
@pytest.mark.asyncio
async def test_validate_task_tag_ids_rejects_missing_tags():
org_id = uuid4()
tag_a = uuid4()
missing = uuid4()
session = _FakeSession(exec_results=[{tag_a}])
with pytest.raises(task_tags.HTTPException) as exc:
await task_tags.validate_task_tag_ids(
session,
organization_id=org_id,
tag_ids=[tag_a, missing],
)
assert exc.value.status_code == 404
assert exc.value.detail["missing_tag_ids"] == [str(missing)]
@pytest.mark.asyncio
async def test_load_task_tag_state_groups_rows_by_task_id():
task_a = uuid4()
task_b = uuid4()
tag_a = uuid4()
tag_b = uuid4()
session = _FakeSession(
exec_results=[
[
(
task_a,
TaskTag(
id=tag_a,
organization_id=uuid4(),
name="Backend",
slug="backend",
color="0f172a",
),
),
(
task_a,
TaskTag(
id=tag_b,
organization_id=uuid4(),
name="Urgent",
slug="urgent",
color="dc2626",
),
),
(
task_b,
TaskTag(
id=tag_b,
organization_id=uuid4(),
name="Urgent",
slug="urgent",
color="dc2626",
),
),
],
],
)
state = await task_tags.load_task_tag_state(
session,
task_ids=[task_a, task_b],
)
assert state[task_a].tag_ids == [tag_a, tag_b]
assert [tag.name for tag in state[task_a].tags] == ["Backend", "Urgent"]
assert state[task_b].tag_ids == [tag_b]
@pytest.mark.asyncio
async def test_replace_task_tags_replaces_existing_links():
task_id = uuid4()
tag_a = uuid4()
tag_b = uuid4()
session = _FakeSession(exec_results=[None])
await task_tags.replace_task_tags(
session,
task_id=task_id,
tag_ids=[tag_a, tag_b, tag_a],
)
assert len(session.executed) == 1
assert len(session.added) == 2

View File

@@ -67,6 +67,7 @@ def test_task_event_payload_includes_activity_for_comment_event() -> None:
task, task,
deps_map={}, deps_map={},
dep_status={}, dep_status={},
tag_state_by_task_id={},
) )
assert payload["type"] == "task.comment" assert payload["type"] == "task.comment"
@@ -98,6 +99,7 @@ def test_task_event_payload_includes_activity_for_non_comment_event() -> None:
task, task,
deps_map={}, deps_map={},
dep_status={}, dep_status={},
tag_state_by_task_id={},
) )
assert payload["type"] == "task.updated" assert payload["type"] == "task.updated"

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -364,6 +364,134 @@ export const useCreateAgentApiV1AgentsPost = <
queryClient, queryClient,
); );
}; };
/**
* Heartbeat an existing agent or create/provision one if needed.
* @summary Heartbeat Or Create Agent
*/
export type heartbeatOrCreateAgentApiV1AgentsHeartbeatPostResponse200 = {
data: AgentRead;
status: 200;
};
export type heartbeatOrCreateAgentApiV1AgentsHeartbeatPostResponse422 = {
data: HTTPValidationError;
status: 422;
};
export type heartbeatOrCreateAgentApiV1AgentsHeartbeatPostResponseSuccess =
heartbeatOrCreateAgentApiV1AgentsHeartbeatPostResponse200 & {
headers: Headers;
};
export type heartbeatOrCreateAgentApiV1AgentsHeartbeatPostResponseError =
heartbeatOrCreateAgentApiV1AgentsHeartbeatPostResponse422 & {
headers: Headers;
};
export type heartbeatOrCreateAgentApiV1AgentsHeartbeatPostResponse =
| heartbeatOrCreateAgentApiV1AgentsHeartbeatPostResponseSuccess
| heartbeatOrCreateAgentApiV1AgentsHeartbeatPostResponseError;
export const getHeartbeatOrCreateAgentApiV1AgentsHeartbeatPostUrl = () => {
return `/api/v1/agents/heartbeat`;
};
export const heartbeatOrCreateAgentApiV1AgentsHeartbeatPost = async (
agentHeartbeatCreate: AgentHeartbeatCreate,
options?: RequestInit,
): Promise<heartbeatOrCreateAgentApiV1AgentsHeartbeatPostResponse> => {
return customFetch<heartbeatOrCreateAgentApiV1AgentsHeartbeatPostResponse>(
getHeartbeatOrCreateAgentApiV1AgentsHeartbeatPostUrl(),
{
...options,
method: "POST",
headers: { "Content-Type": "application/json", ...options?.headers },
body: JSON.stringify(agentHeartbeatCreate),
},
);
};
export const getHeartbeatOrCreateAgentApiV1AgentsHeartbeatPostMutationOptions =
<TError = HTTPValidationError, TContext = unknown>(options?: {
mutation?: UseMutationOptions<
Awaited<
ReturnType<typeof heartbeatOrCreateAgentApiV1AgentsHeartbeatPost>
>,
TError,
{ data: AgentHeartbeatCreate },
TContext
>;
request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
Awaited<ReturnType<typeof heartbeatOrCreateAgentApiV1AgentsHeartbeatPost>>,
TError,
{ data: AgentHeartbeatCreate },
TContext
> => {
const mutationKey = ["heartbeatOrCreateAgentApiV1AgentsHeartbeatPost"];
const { mutation: mutationOptions, request: requestOptions } = options
? options.mutation &&
"mutationKey" in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey }, request: undefined };
const mutationFn: MutationFunction<
Awaited<
ReturnType<typeof heartbeatOrCreateAgentApiV1AgentsHeartbeatPost>
>,
{ data: AgentHeartbeatCreate }
> = (props) => {
const { data } = props ?? {};
return heartbeatOrCreateAgentApiV1AgentsHeartbeatPost(
data,
requestOptions,
);
};
return { mutationFn, ...mutationOptions };
};
export type HeartbeatOrCreateAgentApiV1AgentsHeartbeatPostMutationResult =
NonNullable<
Awaited<ReturnType<typeof heartbeatOrCreateAgentApiV1AgentsHeartbeatPost>>
>;
export type HeartbeatOrCreateAgentApiV1AgentsHeartbeatPostMutationBody =
AgentHeartbeatCreate;
export type HeartbeatOrCreateAgentApiV1AgentsHeartbeatPostMutationError =
HTTPValidationError;
/**
* @summary Heartbeat Or Create Agent
*/
export const useHeartbeatOrCreateAgentApiV1AgentsHeartbeatPost = <
TError = HTTPValidationError,
TContext = unknown,
>(
options?: {
mutation?: UseMutationOptions<
Awaited<
ReturnType<typeof heartbeatOrCreateAgentApiV1AgentsHeartbeatPost>
>,
TError,
{ data: AgentHeartbeatCreate },
TContext
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseMutationResult<
Awaited<ReturnType<typeof heartbeatOrCreateAgentApiV1AgentsHeartbeatPost>>,
TError,
{ data: AgentHeartbeatCreate },
TContext
> => {
return useMutation(
getHeartbeatOrCreateAgentApiV1AgentsHeartbeatPostMutationOptions(options),
queryClient,
);
};
/** /**
* Stream agent updates as SSE events. * Stream agent updates as SSE events.
* @summary Stream Agents * @summary Stream Agents
@@ -576,6 +704,123 @@ export function useStreamAgentsApiV1AgentsStreamGet<
return { ...query, queryKey: queryOptions.queryKey }; return { ...query, queryKey: queryOptions.queryKey };
} }
/**
* Delete an agent and clean related task state.
* @summary Delete Agent
*/
export type deleteAgentApiV1AgentsAgentIdDeleteResponse200 = {
data: OkResponse;
status: 200;
};
export type deleteAgentApiV1AgentsAgentIdDeleteResponse422 = {
data: HTTPValidationError;
status: 422;
};
export type deleteAgentApiV1AgentsAgentIdDeleteResponseSuccess =
deleteAgentApiV1AgentsAgentIdDeleteResponse200 & {
headers: Headers;
};
export type deleteAgentApiV1AgentsAgentIdDeleteResponseError =
deleteAgentApiV1AgentsAgentIdDeleteResponse422 & {
headers: Headers;
};
export type deleteAgentApiV1AgentsAgentIdDeleteResponse =
| deleteAgentApiV1AgentsAgentIdDeleteResponseSuccess
| deleteAgentApiV1AgentsAgentIdDeleteResponseError;
export const getDeleteAgentApiV1AgentsAgentIdDeleteUrl = (agentId: string) => {
return `/api/v1/agents/${agentId}`;
};
export const deleteAgentApiV1AgentsAgentIdDelete = async (
agentId: string,
options?: RequestInit,
): Promise<deleteAgentApiV1AgentsAgentIdDeleteResponse> => {
return customFetch<deleteAgentApiV1AgentsAgentIdDeleteResponse>(
getDeleteAgentApiV1AgentsAgentIdDeleteUrl(agentId),
{
...options,
method: "DELETE",
},
);
};
export const getDeleteAgentApiV1AgentsAgentIdDeleteMutationOptions = <
TError = HTTPValidationError,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deleteAgentApiV1AgentsAgentIdDelete>>,
TError,
{ agentId: string },
TContext
>;
request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
Awaited<ReturnType<typeof deleteAgentApiV1AgentsAgentIdDelete>>,
TError,
{ agentId: string },
TContext
> => {
const mutationKey = ["deleteAgentApiV1AgentsAgentIdDelete"];
const { mutation: mutationOptions, request: requestOptions } = options
? options.mutation &&
"mutationKey" in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey }, request: undefined };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof deleteAgentApiV1AgentsAgentIdDelete>>,
{ agentId: string }
> = (props) => {
const { agentId } = props ?? {};
return deleteAgentApiV1AgentsAgentIdDelete(agentId, requestOptions);
};
return { mutationFn, ...mutationOptions };
};
export type DeleteAgentApiV1AgentsAgentIdDeleteMutationResult = NonNullable<
Awaited<ReturnType<typeof deleteAgentApiV1AgentsAgentIdDelete>>
>;
export type DeleteAgentApiV1AgentsAgentIdDeleteMutationError =
HTTPValidationError;
/**
* @summary Delete Agent
*/
export const useDeleteAgentApiV1AgentsAgentIdDelete = <
TError = HTTPValidationError,
TContext = unknown,
>(
options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deleteAgentApiV1AgentsAgentIdDelete>>,
TError,
{ agentId: string },
TContext
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseMutationResult<
Awaited<ReturnType<typeof deleteAgentApiV1AgentsAgentIdDelete>>,
TError,
{ agentId: string },
TContext
> => {
return useMutation(
getDeleteAgentApiV1AgentsAgentIdDeleteMutationOptions(options),
queryClient,
);
};
/** /**
* Get a single agent by id. * Get a single agent by id.
* @summary Get Agent * @summary Get Agent
@@ -937,123 +1182,6 @@ export const useUpdateAgentApiV1AgentsAgentIdPatch = <
queryClient, queryClient,
); );
}; };
/**
* Delete an agent and clean related task state.
* @summary Delete Agent
*/
export type deleteAgentApiV1AgentsAgentIdDeleteResponse200 = {
data: OkResponse;
status: 200;
};
export type deleteAgentApiV1AgentsAgentIdDeleteResponse422 = {
data: HTTPValidationError;
status: 422;
};
export type deleteAgentApiV1AgentsAgentIdDeleteResponseSuccess =
deleteAgentApiV1AgentsAgentIdDeleteResponse200 & {
headers: Headers;
};
export type deleteAgentApiV1AgentsAgentIdDeleteResponseError =
deleteAgentApiV1AgentsAgentIdDeleteResponse422 & {
headers: Headers;
};
export type deleteAgentApiV1AgentsAgentIdDeleteResponse =
| deleteAgentApiV1AgentsAgentIdDeleteResponseSuccess
| deleteAgentApiV1AgentsAgentIdDeleteResponseError;
export const getDeleteAgentApiV1AgentsAgentIdDeleteUrl = (agentId: string) => {
return `/api/v1/agents/${agentId}`;
};
export const deleteAgentApiV1AgentsAgentIdDelete = async (
agentId: string,
options?: RequestInit,
): Promise<deleteAgentApiV1AgentsAgentIdDeleteResponse> => {
return customFetch<deleteAgentApiV1AgentsAgentIdDeleteResponse>(
getDeleteAgentApiV1AgentsAgentIdDeleteUrl(agentId),
{
...options,
method: "DELETE",
},
);
};
export const getDeleteAgentApiV1AgentsAgentIdDeleteMutationOptions = <
TError = HTTPValidationError,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deleteAgentApiV1AgentsAgentIdDelete>>,
TError,
{ agentId: string },
TContext
>;
request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
Awaited<ReturnType<typeof deleteAgentApiV1AgentsAgentIdDelete>>,
TError,
{ agentId: string },
TContext
> => {
const mutationKey = ["deleteAgentApiV1AgentsAgentIdDelete"];
const { mutation: mutationOptions, request: requestOptions } = options
? options.mutation &&
"mutationKey" in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey }, request: undefined };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof deleteAgentApiV1AgentsAgentIdDelete>>,
{ agentId: string }
> = (props) => {
const { agentId } = props ?? {};
return deleteAgentApiV1AgentsAgentIdDelete(agentId, requestOptions);
};
return { mutationFn, ...mutationOptions };
};
export type DeleteAgentApiV1AgentsAgentIdDeleteMutationResult = NonNullable<
Awaited<ReturnType<typeof deleteAgentApiV1AgentsAgentIdDelete>>
>;
export type DeleteAgentApiV1AgentsAgentIdDeleteMutationError =
HTTPValidationError;
/**
* @summary Delete Agent
*/
export const useDeleteAgentApiV1AgentsAgentIdDelete = <
TError = HTTPValidationError,
TContext = unknown,
>(
options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deleteAgentApiV1AgentsAgentIdDelete>>,
TError,
{ agentId: string },
TContext
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseMutationResult<
Awaited<ReturnType<typeof deleteAgentApiV1AgentsAgentIdDelete>>,
TError,
{ agentId: string },
TContext
> => {
return useMutation(
getDeleteAgentApiV1AgentsAgentIdDeleteMutationOptions(options),
queryClient,
);
};
/** /**
* Record a heartbeat for a specific agent. * Record a heartbeat for a specific agent.
* @summary Heartbeat Agent * @summary Heartbeat Agent
@@ -1182,131 +1310,3 @@ export const useHeartbeatAgentApiV1AgentsAgentIdHeartbeatPost = <
queryClient, queryClient,
); );
}; };
/**
* Heartbeat an existing agent or create/provision one if needed.
* @summary Heartbeat Or Create Agent
*/
export type heartbeatOrCreateAgentApiV1AgentsHeartbeatPostResponse200 = {
data: AgentRead;
status: 200;
};
export type heartbeatOrCreateAgentApiV1AgentsHeartbeatPostResponse422 = {
data: HTTPValidationError;
status: 422;
};
export type heartbeatOrCreateAgentApiV1AgentsHeartbeatPostResponseSuccess =
heartbeatOrCreateAgentApiV1AgentsHeartbeatPostResponse200 & {
headers: Headers;
};
export type heartbeatOrCreateAgentApiV1AgentsHeartbeatPostResponseError =
heartbeatOrCreateAgentApiV1AgentsHeartbeatPostResponse422 & {
headers: Headers;
};
export type heartbeatOrCreateAgentApiV1AgentsHeartbeatPostResponse =
| heartbeatOrCreateAgentApiV1AgentsHeartbeatPostResponseSuccess
| heartbeatOrCreateAgentApiV1AgentsHeartbeatPostResponseError;
export const getHeartbeatOrCreateAgentApiV1AgentsHeartbeatPostUrl = () => {
return `/api/v1/agents/heartbeat`;
};
export const heartbeatOrCreateAgentApiV1AgentsHeartbeatPost = async (
agentHeartbeatCreate: AgentHeartbeatCreate,
options?: RequestInit,
): Promise<heartbeatOrCreateAgentApiV1AgentsHeartbeatPostResponse> => {
return customFetch<heartbeatOrCreateAgentApiV1AgentsHeartbeatPostResponse>(
getHeartbeatOrCreateAgentApiV1AgentsHeartbeatPostUrl(),
{
...options,
method: "POST",
headers: { "Content-Type": "application/json", ...options?.headers },
body: JSON.stringify(agentHeartbeatCreate),
},
);
};
export const getHeartbeatOrCreateAgentApiV1AgentsHeartbeatPostMutationOptions =
<TError = HTTPValidationError, TContext = unknown>(options?: {
mutation?: UseMutationOptions<
Awaited<
ReturnType<typeof heartbeatOrCreateAgentApiV1AgentsHeartbeatPost>
>,
TError,
{ data: AgentHeartbeatCreate },
TContext
>;
request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
Awaited<ReturnType<typeof heartbeatOrCreateAgentApiV1AgentsHeartbeatPost>>,
TError,
{ data: AgentHeartbeatCreate },
TContext
> => {
const mutationKey = ["heartbeatOrCreateAgentApiV1AgentsHeartbeatPost"];
const { mutation: mutationOptions, request: requestOptions } = options
? options.mutation &&
"mutationKey" in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey }, request: undefined };
const mutationFn: MutationFunction<
Awaited<
ReturnType<typeof heartbeatOrCreateAgentApiV1AgentsHeartbeatPost>
>,
{ data: AgentHeartbeatCreate }
> = (props) => {
const { data } = props ?? {};
return heartbeatOrCreateAgentApiV1AgentsHeartbeatPost(
data,
requestOptions,
);
};
return { mutationFn, ...mutationOptions };
};
export type HeartbeatOrCreateAgentApiV1AgentsHeartbeatPostMutationResult =
NonNullable<
Awaited<ReturnType<typeof heartbeatOrCreateAgentApiV1AgentsHeartbeatPost>>
>;
export type HeartbeatOrCreateAgentApiV1AgentsHeartbeatPostMutationBody =
AgentHeartbeatCreate;
export type HeartbeatOrCreateAgentApiV1AgentsHeartbeatPostMutationError =
HTTPValidationError;
/**
* @summary Heartbeat Or Create Agent
*/
export const useHeartbeatOrCreateAgentApiV1AgentsHeartbeatPost = <
TError = HTTPValidationError,
TContext = unknown,
>(
options?: {
mutation?: UseMutationOptions<
Awaited<
ReturnType<typeof heartbeatOrCreateAgentApiV1AgentsHeartbeatPost>
>,
TError,
{ data: AgentHeartbeatCreate },
TContext
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseMutationResult<
Awaited<ReturnType<typeof heartbeatOrCreateAgentApiV1AgentsHeartbeatPost>>,
TError,
{ data: AgentHeartbeatCreate },
TContext
> => {
return useMutation(
getHeartbeatOrCreateAgentApiV1AgentsHeartbeatPostMutationOptions(options),
queryClient,
);
};

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -369,6 +369,129 @@ export const useCreateBoardGroupApiV1BoardGroupsPost = <
queryClient, queryClient,
); );
}; };
/**
* Delete a board group.
* @summary Delete Board Group
*/
export type deleteBoardGroupApiV1BoardGroupsGroupIdDeleteResponse200 = {
data: OkResponse;
status: 200;
};
export type deleteBoardGroupApiV1BoardGroupsGroupIdDeleteResponse422 = {
data: HTTPValidationError;
status: 422;
};
export type deleteBoardGroupApiV1BoardGroupsGroupIdDeleteResponseSuccess =
deleteBoardGroupApiV1BoardGroupsGroupIdDeleteResponse200 & {
headers: Headers;
};
export type deleteBoardGroupApiV1BoardGroupsGroupIdDeleteResponseError =
deleteBoardGroupApiV1BoardGroupsGroupIdDeleteResponse422 & {
headers: Headers;
};
export type deleteBoardGroupApiV1BoardGroupsGroupIdDeleteResponse =
| deleteBoardGroupApiV1BoardGroupsGroupIdDeleteResponseSuccess
| deleteBoardGroupApiV1BoardGroupsGroupIdDeleteResponseError;
export const getDeleteBoardGroupApiV1BoardGroupsGroupIdDeleteUrl = (
groupId: string,
) => {
return `/api/v1/board-groups/${groupId}`;
};
export const deleteBoardGroupApiV1BoardGroupsGroupIdDelete = async (
groupId: string,
options?: RequestInit,
): Promise<deleteBoardGroupApiV1BoardGroupsGroupIdDeleteResponse> => {
return customFetch<deleteBoardGroupApiV1BoardGroupsGroupIdDeleteResponse>(
getDeleteBoardGroupApiV1BoardGroupsGroupIdDeleteUrl(groupId),
{
...options,
method: "DELETE",
},
);
};
export const getDeleteBoardGroupApiV1BoardGroupsGroupIdDeleteMutationOptions = <
TError = HTTPValidationError,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deleteBoardGroupApiV1BoardGroupsGroupIdDelete>>,
TError,
{ groupId: string },
TContext
>;
request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
Awaited<ReturnType<typeof deleteBoardGroupApiV1BoardGroupsGroupIdDelete>>,
TError,
{ groupId: string },
TContext
> => {
const mutationKey = ["deleteBoardGroupApiV1BoardGroupsGroupIdDelete"];
const { mutation: mutationOptions, request: requestOptions } = options
? options.mutation &&
"mutationKey" in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey }, request: undefined };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof deleteBoardGroupApiV1BoardGroupsGroupIdDelete>>,
{ groupId: string }
> = (props) => {
const { groupId } = props ?? {};
return deleteBoardGroupApiV1BoardGroupsGroupIdDelete(
groupId,
requestOptions,
);
};
return { mutationFn, ...mutationOptions };
};
export type DeleteBoardGroupApiV1BoardGroupsGroupIdDeleteMutationResult =
NonNullable<
Awaited<ReturnType<typeof deleteBoardGroupApiV1BoardGroupsGroupIdDelete>>
>;
export type DeleteBoardGroupApiV1BoardGroupsGroupIdDeleteMutationError =
HTTPValidationError;
/**
* @summary Delete Board Group
*/
export const useDeleteBoardGroupApiV1BoardGroupsGroupIdDelete = <
TError = HTTPValidationError,
TContext = unknown,
>(
options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deleteBoardGroupApiV1BoardGroupsGroupIdDelete>>,
TError,
{ groupId: string },
TContext
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseMutationResult<
Awaited<ReturnType<typeof deleteBoardGroupApiV1BoardGroupsGroupIdDelete>>,
TError,
{ groupId: string },
TContext
> => {
return useMutation(
getDeleteBoardGroupApiV1BoardGroupsGroupIdDeleteMutationOptions(options),
queryClient,
);
};
/** /**
* Get a board group by id. * Get a board group by id.
* @summary Get Board Group * @summary Get Board Group
@@ -707,125 +830,161 @@ export const useUpdateBoardGroupApiV1BoardGroupsGroupIdPatch = <
); );
}; };
/** /**
* Delete a board group. * Apply heartbeat settings to agents in a board group.
* @summary Delete Board Group * @summary Apply Board Group Heartbeat
*/ */
export type deleteBoardGroupApiV1BoardGroupsGroupIdDeleteResponse200 = { export type applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostResponse200 =
data: OkResponse; {
status: 200; data: BoardGroupHeartbeatApplyResult;
}; status: 200;
};
export type deleteBoardGroupApiV1BoardGroupsGroupIdDeleteResponse422 = { export type applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostResponse422 =
data: HTTPValidationError; {
status: 422; data: HTTPValidationError;
}; status: 422;
};
export type deleteBoardGroupApiV1BoardGroupsGroupIdDeleteResponseSuccess = export type applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostResponseSuccess =
deleteBoardGroupApiV1BoardGroupsGroupIdDeleteResponse200 & { applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostResponse200 & {
headers: Headers; headers: Headers;
}; };
export type deleteBoardGroupApiV1BoardGroupsGroupIdDeleteResponseError = export type applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostResponseError =
deleteBoardGroupApiV1BoardGroupsGroupIdDeleteResponse422 & { applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostResponse422 & {
headers: Headers; headers: Headers;
}; };
export type deleteBoardGroupApiV1BoardGroupsGroupIdDeleteResponse = export type applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostResponse =
| deleteBoardGroupApiV1BoardGroupsGroupIdDeleteResponseSuccess
| deleteBoardGroupApiV1BoardGroupsGroupIdDeleteResponseError;
export const getDeleteBoardGroupApiV1BoardGroupsGroupIdDeleteUrl = ( | applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostResponseSuccess
groupId: string, | applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostResponseError;
) => {
return `/api/v1/board-groups/${groupId}`;
};
export const deleteBoardGroupApiV1BoardGroupsGroupIdDelete = async ( export const getApplyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostUrl =
groupId: string, (groupId: string) => {
options?: RequestInit, return `/api/v1/board-groups/${groupId}/heartbeat`;
): Promise<deleteBoardGroupApiV1BoardGroupsGroupIdDeleteResponse> => { };
return customFetch<deleteBoardGroupApiV1BoardGroupsGroupIdDeleteResponse>(
getDeleteBoardGroupApiV1BoardGroupsGroupIdDeleteUrl(groupId),
{
...options,
method: "DELETE",
},
);
};
export const getDeleteBoardGroupApiV1BoardGroupsGroupIdDeleteMutationOptions = < export const applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPost =
TError = HTTPValidationError, async (
TContext = unknown, groupId: string,
>(options?: { boardGroupHeartbeatApply: BoardGroupHeartbeatApply,
mutation?: UseMutationOptions< options?: RequestInit,
Awaited<ReturnType<typeof deleteBoardGroupApiV1BoardGroupsGroupIdDelete>>, ): Promise<applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostResponse> => {
TError, return customFetch<applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostResponse>(
{ groupId: string }, getApplyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostUrl(
TContext groupId,
>; ),
request?: SecondParameter<typeof customFetch>; {
}): UseMutationOptions< ...options,
Awaited<ReturnType<typeof deleteBoardGroupApiV1BoardGroupsGroupIdDelete>>, method: "POST",
TError, headers: { "Content-Type": "application/json", ...options?.headers },
{ groupId: string }, body: JSON.stringify(boardGroupHeartbeatApply),
TContext },
> => {
const mutationKey = ["deleteBoardGroupApiV1BoardGroupsGroupIdDelete"];
const { mutation: mutationOptions, request: requestOptions } = options
? options.mutation &&
"mutationKey" in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey }, request: undefined };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof deleteBoardGroupApiV1BoardGroupsGroupIdDelete>>,
{ groupId: string }
> = (props) => {
const { groupId } = props ?? {};
return deleteBoardGroupApiV1BoardGroupsGroupIdDelete(
groupId,
requestOptions,
); );
}; };
return { mutationFn, ...mutationOptions }; export const getApplyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostMutationOptions =
}; <TError = HTTPValidationError, TContext = unknown>(options?: {
mutation?: UseMutationOptions<
Awaited<
ReturnType<
typeof applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPost
>
>,
TError,
{ groupId: string; data: BoardGroupHeartbeatApply },
TContext
>;
request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
Awaited<
ReturnType<
typeof applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPost
>
>,
TError,
{ groupId: string; data: BoardGroupHeartbeatApply },
TContext
> => {
const mutationKey = [
"applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPost",
];
const { mutation: mutationOptions, request: requestOptions } = options
? options.mutation &&
"mutationKey" in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey }, request: undefined };
export type DeleteBoardGroupApiV1BoardGroupsGroupIdDeleteMutationResult = const mutationFn: MutationFunction<
Awaited<
ReturnType<
typeof applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPost
>
>,
{ groupId: string; data: BoardGroupHeartbeatApply }
> = (props) => {
const { groupId, data } = props ?? {};
return applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPost(
groupId,
data,
requestOptions,
);
};
return { mutationFn, ...mutationOptions };
};
export type ApplyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostMutationResult =
NonNullable< NonNullable<
Awaited<ReturnType<typeof deleteBoardGroupApiV1BoardGroupsGroupIdDelete>> Awaited<
ReturnType<
typeof applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPost
>
>
>; >;
export type ApplyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostMutationBody =
export type DeleteBoardGroupApiV1BoardGroupsGroupIdDeleteMutationError = BoardGroupHeartbeatApply;
export type ApplyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostMutationError =
HTTPValidationError; HTTPValidationError;
/** /**
* @summary Delete Board Group * @summary Apply Board Group Heartbeat
*/ */
export const useDeleteBoardGroupApiV1BoardGroupsGroupIdDelete = < export const useApplyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPost = <
TError = HTTPValidationError, TError = HTTPValidationError,
TContext = unknown, TContext = unknown,
>( >(
options?: { options?: {
mutation?: UseMutationOptions< mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deleteBoardGroupApiV1BoardGroupsGroupIdDelete>>, Awaited<
ReturnType<
typeof applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPost
>
>,
TError, TError,
{ groupId: string }, { groupId: string; data: BoardGroupHeartbeatApply },
TContext TContext
>; >;
request?: SecondParameter<typeof customFetch>; request?: SecondParameter<typeof customFetch>;
}, },
queryClient?: QueryClient, queryClient?: QueryClient,
): UseMutationResult< ): UseMutationResult<
Awaited<ReturnType<typeof deleteBoardGroupApiV1BoardGroupsGroupIdDelete>>, Awaited<
ReturnType<
typeof applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPost
>
>,
TError, TError,
{ groupId: string }, { groupId: string; data: BoardGroupHeartbeatApply },
TContext TContext
> => { > => {
return useMutation( return useMutation(
getDeleteBoardGroupApiV1BoardGroupsGroupIdDeleteMutationOptions(options), getApplyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostMutationOptions(
options,
),
queryClient, queryClient,
); );
}; };
@@ -1131,163 +1290,3 @@ export function useGetBoardGroupSnapshotApiV1BoardGroupsGroupIdSnapshotGet<
return { ...query, queryKey: queryOptions.queryKey }; return { ...query, queryKey: queryOptions.queryKey };
} }
/**
* Apply heartbeat settings to agents in a board group.
* @summary Apply Board Group Heartbeat
*/
export type applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostResponse200 =
{
data: BoardGroupHeartbeatApplyResult;
status: 200;
};
export type applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostResponse422 =
{
data: HTTPValidationError;
status: 422;
};
export type applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostResponseSuccess =
applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostResponse200 & {
headers: Headers;
};
export type applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostResponseError =
applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostResponse422 & {
headers: Headers;
};
export type applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostResponse =
| applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostResponseSuccess
| applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostResponseError;
export const getApplyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostUrl =
(groupId: string) => {
return `/api/v1/board-groups/${groupId}/heartbeat`;
};
export const applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPost =
async (
groupId: string,
boardGroupHeartbeatApply: BoardGroupHeartbeatApply,
options?: RequestInit,
): Promise<applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostResponse> => {
return customFetch<applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostResponse>(
getApplyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostUrl(
groupId,
),
{
...options,
method: "POST",
headers: { "Content-Type": "application/json", ...options?.headers },
body: JSON.stringify(boardGroupHeartbeatApply),
},
);
};
export const getApplyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostMutationOptions =
<TError = HTTPValidationError, TContext = unknown>(options?: {
mutation?: UseMutationOptions<
Awaited<
ReturnType<
typeof applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPost
>
>,
TError,
{ groupId: string; data: BoardGroupHeartbeatApply },
TContext
>;
request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
Awaited<
ReturnType<
typeof applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPost
>
>,
TError,
{ groupId: string; data: BoardGroupHeartbeatApply },
TContext
> => {
const mutationKey = [
"applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPost",
];
const { mutation: mutationOptions, request: requestOptions } = options
? options.mutation &&
"mutationKey" in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey }, request: undefined };
const mutationFn: MutationFunction<
Awaited<
ReturnType<
typeof applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPost
>
>,
{ groupId: string; data: BoardGroupHeartbeatApply }
> = (props) => {
const { groupId, data } = props ?? {};
return applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPost(
groupId,
data,
requestOptions,
);
};
return { mutationFn, ...mutationOptions };
};
export type ApplyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostMutationResult =
NonNullable<
Awaited<
ReturnType<
typeof applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPost
>
>
>;
export type ApplyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostMutationBody =
BoardGroupHeartbeatApply;
export type ApplyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostMutationError =
HTTPValidationError;
/**
* @summary Apply Board Group Heartbeat
*/
export const useApplyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPost = <
TError = HTTPValidationError,
TContext = unknown,
>(
options?: {
mutation?: UseMutationOptions<
Awaited<
ReturnType<
typeof applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPost
>
>,
TError,
{ groupId: string; data: BoardGroupHeartbeatApply },
TContext
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseMutationResult<
Awaited<
ReturnType<
typeof applyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPost
>
>,
TError,
{ groupId: string; data: BoardGroupHeartbeatApply },
TContext
> => {
return useMutation(
getApplyBoardGroupHeartbeatApiV1BoardGroupsGroupIdHeartbeatPostMutationOptions(
options,
),
queryClient,
);
};

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -274,298 +274,6 @@ export function useGetOnboardingApiV1BoardsBoardIdOnboardingGet<
return { ...query, queryKey: queryOptions.queryKey }; return { ...query, queryKey: queryOptions.queryKey };
} }
/**
* Start onboarding and send instructions to the gateway agent.
* @summary Start Onboarding
*/
export type startOnboardingApiV1BoardsBoardIdOnboardingStartPostResponse200 = {
data: BoardOnboardingRead;
status: 200;
};
export type startOnboardingApiV1BoardsBoardIdOnboardingStartPostResponse422 = {
data: HTTPValidationError;
status: 422;
};
export type startOnboardingApiV1BoardsBoardIdOnboardingStartPostResponseSuccess =
startOnboardingApiV1BoardsBoardIdOnboardingStartPostResponse200 & {
headers: Headers;
};
export type startOnboardingApiV1BoardsBoardIdOnboardingStartPostResponseError =
startOnboardingApiV1BoardsBoardIdOnboardingStartPostResponse422 & {
headers: Headers;
};
export type startOnboardingApiV1BoardsBoardIdOnboardingStartPostResponse =
| startOnboardingApiV1BoardsBoardIdOnboardingStartPostResponseSuccess
| startOnboardingApiV1BoardsBoardIdOnboardingStartPostResponseError;
export const getStartOnboardingApiV1BoardsBoardIdOnboardingStartPostUrl = (
boardId: string,
) => {
return `/api/v1/boards/${boardId}/onboarding/start`;
};
export const startOnboardingApiV1BoardsBoardIdOnboardingStartPost = async (
boardId: string,
boardOnboardingStart: BoardOnboardingStart,
options?: RequestInit,
): Promise<startOnboardingApiV1BoardsBoardIdOnboardingStartPostResponse> => {
return customFetch<startOnboardingApiV1BoardsBoardIdOnboardingStartPostResponse>(
getStartOnboardingApiV1BoardsBoardIdOnboardingStartPostUrl(boardId),
{
...options,
method: "POST",
headers: { "Content-Type": "application/json", ...options?.headers },
body: JSON.stringify(boardOnboardingStart),
},
);
};
export const getStartOnboardingApiV1BoardsBoardIdOnboardingStartPostMutationOptions =
<TError = HTTPValidationError, TContext = unknown>(options?: {
mutation?: UseMutationOptions<
Awaited<
ReturnType<typeof startOnboardingApiV1BoardsBoardIdOnboardingStartPost>
>,
TError,
{ boardId: string; data: BoardOnboardingStart },
TContext
>;
request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
Awaited<
ReturnType<typeof startOnboardingApiV1BoardsBoardIdOnboardingStartPost>
>,
TError,
{ boardId: string; data: BoardOnboardingStart },
TContext
> => {
const mutationKey = [
"startOnboardingApiV1BoardsBoardIdOnboardingStartPost",
];
const { mutation: mutationOptions, request: requestOptions } = options
? options.mutation &&
"mutationKey" in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey }, request: undefined };
const mutationFn: MutationFunction<
Awaited<
ReturnType<typeof startOnboardingApiV1BoardsBoardIdOnboardingStartPost>
>,
{ boardId: string; data: BoardOnboardingStart }
> = (props) => {
const { boardId, data } = props ?? {};
return startOnboardingApiV1BoardsBoardIdOnboardingStartPost(
boardId,
data,
requestOptions,
);
};
return { mutationFn, ...mutationOptions };
};
export type StartOnboardingApiV1BoardsBoardIdOnboardingStartPostMutationResult =
NonNullable<
Awaited<
ReturnType<typeof startOnboardingApiV1BoardsBoardIdOnboardingStartPost>
>
>;
export type StartOnboardingApiV1BoardsBoardIdOnboardingStartPostMutationBody =
BoardOnboardingStart;
export type StartOnboardingApiV1BoardsBoardIdOnboardingStartPostMutationError =
HTTPValidationError;
/**
* @summary Start Onboarding
*/
export const useStartOnboardingApiV1BoardsBoardIdOnboardingStartPost = <
TError = HTTPValidationError,
TContext = unknown,
>(
options?: {
mutation?: UseMutationOptions<
Awaited<
ReturnType<typeof startOnboardingApiV1BoardsBoardIdOnboardingStartPost>
>,
TError,
{ boardId: string; data: BoardOnboardingStart },
TContext
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseMutationResult<
Awaited<
ReturnType<typeof startOnboardingApiV1BoardsBoardIdOnboardingStartPost>
>,
TError,
{ boardId: string; data: BoardOnboardingStart },
TContext
> => {
return useMutation(
getStartOnboardingApiV1BoardsBoardIdOnboardingStartPostMutationOptions(
options,
),
queryClient,
);
};
/**
* Send a user onboarding answer to the gateway agent.
* @summary Answer Onboarding
*/
export type answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostResponse200 =
{
data: BoardOnboardingRead;
status: 200;
};
export type answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostResponse422 =
{
data: HTTPValidationError;
status: 422;
};
export type answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostResponseSuccess =
answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostResponse200 & {
headers: Headers;
};
export type answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostResponseError =
answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostResponse422 & {
headers: Headers;
};
export type answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostResponse =
| answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostResponseSuccess
| answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostResponseError;
export const getAnswerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostUrl = (
boardId: string,
) => {
return `/api/v1/boards/${boardId}/onboarding/answer`;
};
export const answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPost = async (
boardId: string,
boardOnboardingAnswer: BoardOnboardingAnswer,
options?: RequestInit,
): Promise<answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostResponse> => {
return customFetch<answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostResponse>(
getAnswerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostUrl(boardId),
{
...options,
method: "POST",
headers: { "Content-Type": "application/json", ...options?.headers },
body: JSON.stringify(boardOnboardingAnswer),
},
);
};
export const getAnswerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostMutationOptions =
<TError = HTTPValidationError, TContext = unknown>(options?: {
mutation?: UseMutationOptions<
Awaited<
ReturnType<
typeof answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPost
>
>,
TError,
{ boardId: string; data: BoardOnboardingAnswer },
TContext
>;
request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
Awaited<
ReturnType<typeof answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPost>
>,
TError,
{ boardId: string; data: BoardOnboardingAnswer },
TContext
> => {
const mutationKey = [
"answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPost",
];
const { mutation: mutationOptions, request: requestOptions } = options
? options.mutation &&
"mutationKey" in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey }, request: undefined };
const mutationFn: MutationFunction<
Awaited<
ReturnType<
typeof answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPost
>
>,
{ boardId: string; data: BoardOnboardingAnswer }
> = (props) => {
const { boardId, data } = props ?? {};
return answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPost(
boardId,
data,
requestOptions,
);
};
return { mutationFn, ...mutationOptions };
};
export type AnswerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostMutationResult =
NonNullable<
Awaited<
ReturnType<typeof answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPost>
>
>;
export type AnswerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostMutationBody =
BoardOnboardingAnswer;
export type AnswerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostMutationError =
HTTPValidationError;
/**
* @summary Answer Onboarding
*/
export const useAnswerOnboardingApiV1BoardsBoardIdOnboardingAnswerPost = <
TError = HTTPValidationError,
TContext = unknown,
>(
options?: {
mutation?: UseMutationOptions<
Awaited<
ReturnType<
typeof answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPost
>
>,
TError,
{ boardId: string; data: BoardOnboardingAnswer },
TContext
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseMutationResult<
Awaited<
ReturnType<typeof answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPost>
>,
TError,
{ boardId: string; data: BoardOnboardingAnswer },
TContext
> => {
return useMutation(
getAnswerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostMutationOptions(
options,
),
queryClient,
);
};
/** /**
* Store onboarding updates submitted by the gateway agent. * Store onboarding updates submitted by the gateway agent.
* @summary Agent Onboarding Update * @summary Agent Onboarding Update
@@ -741,6 +449,156 @@ export const useAgentOnboardingUpdateApiV1BoardsBoardIdOnboardingAgentPost = <
queryClient, queryClient,
); );
}; };
/**
* Send a user onboarding answer to the gateway agent.
* @summary Answer Onboarding
*/
export type answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostResponse200 =
{
data: BoardOnboardingRead;
status: 200;
};
export type answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostResponse422 =
{
data: HTTPValidationError;
status: 422;
};
export type answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostResponseSuccess =
answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostResponse200 & {
headers: Headers;
};
export type answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostResponseError =
answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostResponse422 & {
headers: Headers;
};
export type answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostResponse =
| answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostResponseSuccess
| answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostResponseError;
export const getAnswerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostUrl = (
boardId: string,
) => {
return `/api/v1/boards/${boardId}/onboarding/answer`;
};
export const answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPost = async (
boardId: string,
boardOnboardingAnswer: BoardOnboardingAnswer,
options?: RequestInit,
): Promise<answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostResponse> => {
return customFetch<answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostResponse>(
getAnswerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostUrl(boardId),
{
...options,
method: "POST",
headers: { "Content-Type": "application/json", ...options?.headers },
body: JSON.stringify(boardOnboardingAnswer),
},
);
};
export const getAnswerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostMutationOptions =
<TError = HTTPValidationError, TContext = unknown>(options?: {
mutation?: UseMutationOptions<
Awaited<
ReturnType<
typeof answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPost
>
>,
TError,
{ boardId: string; data: BoardOnboardingAnswer },
TContext
>;
request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
Awaited<
ReturnType<typeof answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPost>
>,
TError,
{ boardId: string; data: BoardOnboardingAnswer },
TContext
> => {
const mutationKey = [
"answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPost",
];
const { mutation: mutationOptions, request: requestOptions } = options
? options.mutation &&
"mutationKey" in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey }, request: undefined };
const mutationFn: MutationFunction<
Awaited<
ReturnType<
typeof answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPost
>
>,
{ boardId: string; data: BoardOnboardingAnswer }
> = (props) => {
const { boardId, data } = props ?? {};
return answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPost(
boardId,
data,
requestOptions,
);
};
return { mutationFn, ...mutationOptions };
};
export type AnswerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostMutationResult =
NonNullable<
Awaited<
ReturnType<typeof answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPost>
>
>;
export type AnswerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostMutationBody =
BoardOnboardingAnswer;
export type AnswerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostMutationError =
HTTPValidationError;
/**
* @summary Answer Onboarding
*/
export const useAnswerOnboardingApiV1BoardsBoardIdOnboardingAnswerPost = <
TError = HTTPValidationError,
TContext = unknown,
>(
options?: {
mutation?: UseMutationOptions<
Awaited<
ReturnType<
typeof answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPost
>
>,
TError,
{ boardId: string; data: BoardOnboardingAnswer },
TContext
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseMutationResult<
Awaited<
ReturnType<typeof answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPost>
>,
TError,
{ boardId: string; data: BoardOnboardingAnswer },
TContext
> => {
return useMutation(
getAnswerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostMutationOptions(
options,
),
queryClient,
);
};
/** /**
* Confirm onboarding results and provision the board lead agent. * Confirm onboarding results and provision the board lead agent.
* @summary Confirm Onboarding * @summary Confirm Onboarding
@@ -895,3 +753,145 @@ export const useConfirmOnboardingApiV1BoardsBoardIdOnboardingConfirmPost = <
queryClient, queryClient,
); );
}; };
/**
* Start onboarding and send instructions to the gateway agent.
* @summary Start Onboarding
*/
export type startOnboardingApiV1BoardsBoardIdOnboardingStartPostResponse200 = {
data: BoardOnboardingRead;
status: 200;
};
export type startOnboardingApiV1BoardsBoardIdOnboardingStartPostResponse422 = {
data: HTTPValidationError;
status: 422;
};
export type startOnboardingApiV1BoardsBoardIdOnboardingStartPostResponseSuccess =
startOnboardingApiV1BoardsBoardIdOnboardingStartPostResponse200 & {
headers: Headers;
};
export type startOnboardingApiV1BoardsBoardIdOnboardingStartPostResponseError =
startOnboardingApiV1BoardsBoardIdOnboardingStartPostResponse422 & {
headers: Headers;
};
export type startOnboardingApiV1BoardsBoardIdOnboardingStartPostResponse =
| startOnboardingApiV1BoardsBoardIdOnboardingStartPostResponseSuccess
| startOnboardingApiV1BoardsBoardIdOnboardingStartPostResponseError;
export const getStartOnboardingApiV1BoardsBoardIdOnboardingStartPostUrl = (
boardId: string,
) => {
return `/api/v1/boards/${boardId}/onboarding/start`;
};
export const startOnboardingApiV1BoardsBoardIdOnboardingStartPost = async (
boardId: string,
boardOnboardingStart: BoardOnboardingStart,
options?: RequestInit,
): Promise<startOnboardingApiV1BoardsBoardIdOnboardingStartPostResponse> => {
return customFetch<startOnboardingApiV1BoardsBoardIdOnboardingStartPostResponse>(
getStartOnboardingApiV1BoardsBoardIdOnboardingStartPostUrl(boardId),
{
...options,
method: "POST",
headers: { "Content-Type": "application/json", ...options?.headers },
body: JSON.stringify(boardOnboardingStart),
},
);
};
export const getStartOnboardingApiV1BoardsBoardIdOnboardingStartPostMutationOptions =
<TError = HTTPValidationError, TContext = unknown>(options?: {
mutation?: UseMutationOptions<
Awaited<
ReturnType<typeof startOnboardingApiV1BoardsBoardIdOnboardingStartPost>
>,
TError,
{ boardId: string; data: BoardOnboardingStart },
TContext
>;
request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
Awaited<
ReturnType<typeof startOnboardingApiV1BoardsBoardIdOnboardingStartPost>
>,
TError,
{ boardId: string; data: BoardOnboardingStart },
TContext
> => {
const mutationKey = [
"startOnboardingApiV1BoardsBoardIdOnboardingStartPost",
];
const { mutation: mutationOptions, request: requestOptions } = options
? options.mutation &&
"mutationKey" in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey }, request: undefined };
const mutationFn: MutationFunction<
Awaited<
ReturnType<typeof startOnboardingApiV1BoardsBoardIdOnboardingStartPost>
>,
{ boardId: string; data: BoardOnboardingStart }
> = (props) => {
const { boardId, data } = props ?? {};
return startOnboardingApiV1BoardsBoardIdOnboardingStartPost(
boardId,
data,
requestOptions,
);
};
return { mutationFn, ...mutationOptions };
};
export type StartOnboardingApiV1BoardsBoardIdOnboardingStartPostMutationResult =
NonNullable<
Awaited<
ReturnType<typeof startOnboardingApiV1BoardsBoardIdOnboardingStartPost>
>
>;
export type StartOnboardingApiV1BoardsBoardIdOnboardingStartPostMutationBody =
BoardOnboardingStart;
export type StartOnboardingApiV1BoardsBoardIdOnboardingStartPostMutationError =
HTTPValidationError;
/**
* @summary Start Onboarding
*/
export const useStartOnboardingApiV1BoardsBoardIdOnboardingStartPost = <
TError = HTTPValidationError,
TContext = unknown,
>(
options?: {
mutation?: UseMutationOptions<
Awaited<
ReturnType<typeof startOnboardingApiV1BoardsBoardIdOnboardingStartPost>
>,
TError,
{ boardId: string; data: BoardOnboardingStart },
TContext
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseMutationResult<
Awaited<
ReturnType<typeof startOnboardingApiV1BoardsBoardIdOnboardingStartPost>
>,
TError,
{ boardId: string; data: BoardOnboardingStart },
TContext
> => {
return useMutation(
getStartOnboardingApiV1BoardsBoardIdOnboardingStartPostMutationOptions(
options,
),
queryClient,
);
};

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -363,6 +363,123 @@ export const useCreateBoardApiV1BoardsPost = <
queryClient, queryClient,
); );
}; };
/**
* Delete a board and all dependent records.
* @summary Delete Board
*/
export type deleteBoardApiV1BoardsBoardIdDeleteResponse200 = {
data: OkResponse;
status: 200;
};
export type deleteBoardApiV1BoardsBoardIdDeleteResponse422 = {
data: HTTPValidationError;
status: 422;
};
export type deleteBoardApiV1BoardsBoardIdDeleteResponseSuccess =
deleteBoardApiV1BoardsBoardIdDeleteResponse200 & {
headers: Headers;
};
export type deleteBoardApiV1BoardsBoardIdDeleteResponseError =
deleteBoardApiV1BoardsBoardIdDeleteResponse422 & {
headers: Headers;
};
export type deleteBoardApiV1BoardsBoardIdDeleteResponse =
| deleteBoardApiV1BoardsBoardIdDeleteResponseSuccess
| deleteBoardApiV1BoardsBoardIdDeleteResponseError;
export const getDeleteBoardApiV1BoardsBoardIdDeleteUrl = (boardId: string) => {
return `/api/v1/boards/${boardId}`;
};
export const deleteBoardApiV1BoardsBoardIdDelete = async (
boardId: string,
options?: RequestInit,
): Promise<deleteBoardApiV1BoardsBoardIdDeleteResponse> => {
return customFetch<deleteBoardApiV1BoardsBoardIdDeleteResponse>(
getDeleteBoardApiV1BoardsBoardIdDeleteUrl(boardId),
{
...options,
method: "DELETE",
},
);
};
export const getDeleteBoardApiV1BoardsBoardIdDeleteMutationOptions = <
TError = HTTPValidationError,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deleteBoardApiV1BoardsBoardIdDelete>>,
TError,
{ boardId: string },
TContext
>;
request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
Awaited<ReturnType<typeof deleteBoardApiV1BoardsBoardIdDelete>>,
TError,
{ boardId: string },
TContext
> => {
const mutationKey = ["deleteBoardApiV1BoardsBoardIdDelete"];
const { mutation: mutationOptions, request: requestOptions } = options
? options.mutation &&
"mutationKey" in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey }, request: undefined };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof deleteBoardApiV1BoardsBoardIdDelete>>,
{ boardId: string }
> = (props) => {
const { boardId } = props ?? {};
return deleteBoardApiV1BoardsBoardIdDelete(boardId, requestOptions);
};
return { mutationFn, ...mutationOptions };
};
export type DeleteBoardApiV1BoardsBoardIdDeleteMutationResult = NonNullable<
Awaited<ReturnType<typeof deleteBoardApiV1BoardsBoardIdDelete>>
>;
export type DeleteBoardApiV1BoardsBoardIdDeleteMutationError =
HTTPValidationError;
/**
* @summary Delete Board
*/
export const useDeleteBoardApiV1BoardsBoardIdDelete = <
TError = HTTPValidationError,
TContext = unknown,
>(
options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deleteBoardApiV1BoardsBoardIdDelete>>,
TError,
{ boardId: string },
TContext
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseMutationResult<
Awaited<ReturnType<typeof deleteBoardApiV1BoardsBoardIdDelete>>,
TError,
{ boardId: string },
TContext
> => {
return useMutation(
getDeleteBoardApiV1BoardsBoardIdDeleteMutationOptions(options),
queryClient,
);
};
/** /**
* Get a board by id. * Get a board by id.
* @summary Get Board * @summary Get Board
@@ -683,362 +800,6 @@ export const useUpdateBoardApiV1BoardsBoardIdPatch = <
queryClient, queryClient,
); );
}; };
/**
* Delete a board and all dependent records.
* @summary Delete Board
*/
export type deleteBoardApiV1BoardsBoardIdDeleteResponse200 = {
data: OkResponse;
status: 200;
};
export type deleteBoardApiV1BoardsBoardIdDeleteResponse422 = {
data: HTTPValidationError;
status: 422;
};
export type deleteBoardApiV1BoardsBoardIdDeleteResponseSuccess =
deleteBoardApiV1BoardsBoardIdDeleteResponse200 & {
headers: Headers;
};
export type deleteBoardApiV1BoardsBoardIdDeleteResponseError =
deleteBoardApiV1BoardsBoardIdDeleteResponse422 & {
headers: Headers;
};
export type deleteBoardApiV1BoardsBoardIdDeleteResponse =
| deleteBoardApiV1BoardsBoardIdDeleteResponseSuccess
| deleteBoardApiV1BoardsBoardIdDeleteResponseError;
export const getDeleteBoardApiV1BoardsBoardIdDeleteUrl = (boardId: string) => {
return `/api/v1/boards/${boardId}`;
};
export const deleteBoardApiV1BoardsBoardIdDelete = async (
boardId: string,
options?: RequestInit,
): Promise<deleteBoardApiV1BoardsBoardIdDeleteResponse> => {
return customFetch<deleteBoardApiV1BoardsBoardIdDeleteResponse>(
getDeleteBoardApiV1BoardsBoardIdDeleteUrl(boardId),
{
...options,
method: "DELETE",
},
);
};
export const getDeleteBoardApiV1BoardsBoardIdDeleteMutationOptions = <
TError = HTTPValidationError,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deleteBoardApiV1BoardsBoardIdDelete>>,
TError,
{ boardId: string },
TContext
>;
request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
Awaited<ReturnType<typeof deleteBoardApiV1BoardsBoardIdDelete>>,
TError,
{ boardId: string },
TContext
> => {
const mutationKey = ["deleteBoardApiV1BoardsBoardIdDelete"];
const { mutation: mutationOptions, request: requestOptions } = options
? options.mutation &&
"mutationKey" in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey }, request: undefined };
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof deleteBoardApiV1BoardsBoardIdDelete>>,
{ boardId: string }
> = (props) => {
const { boardId } = props ?? {};
return deleteBoardApiV1BoardsBoardIdDelete(boardId, requestOptions);
};
return { mutationFn, ...mutationOptions };
};
export type DeleteBoardApiV1BoardsBoardIdDeleteMutationResult = NonNullable<
Awaited<ReturnType<typeof deleteBoardApiV1BoardsBoardIdDelete>>
>;
export type DeleteBoardApiV1BoardsBoardIdDeleteMutationError =
HTTPValidationError;
/**
* @summary Delete Board
*/
export const useDeleteBoardApiV1BoardsBoardIdDelete = <
TError = HTTPValidationError,
TContext = unknown,
>(
options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof deleteBoardApiV1BoardsBoardIdDelete>>,
TError,
{ boardId: string },
TContext
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseMutationResult<
Awaited<ReturnType<typeof deleteBoardApiV1BoardsBoardIdDelete>>,
TError,
{ boardId: string },
TContext
> => {
return useMutation(
getDeleteBoardApiV1BoardsBoardIdDeleteMutationOptions(options),
queryClient,
);
};
/**
* Get a board snapshot view model.
* @summary Get Board Snapshot
*/
export type getBoardSnapshotApiV1BoardsBoardIdSnapshotGetResponse200 = {
data: BoardSnapshot;
status: 200;
};
export type getBoardSnapshotApiV1BoardsBoardIdSnapshotGetResponse422 = {
data: HTTPValidationError;
status: 422;
};
export type getBoardSnapshotApiV1BoardsBoardIdSnapshotGetResponseSuccess =
getBoardSnapshotApiV1BoardsBoardIdSnapshotGetResponse200 & {
headers: Headers;
};
export type getBoardSnapshotApiV1BoardsBoardIdSnapshotGetResponseError =
getBoardSnapshotApiV1BoardsBoardIdSnapshotGetResponse422 & {
headers: Headers;
};
export type getBoardSnapshotApiV1BoardsBoardIdSnapshotGetResponse =
| getBoardSnapshotApiV1BoardsBoardIdSnapshotGetResponseSuccess
| getBoardSnapshotApiV1BoardsBoardIdSnapshotGetResponseError;
export const getGetBoardSnapshotApiV1BoardsBoardIdSnapshotGetUrl = (
boardId: string,
) => {
return `/api/v1/boards/${boardId}/snapshot`;
};
export const getBoardSnapshotApiV1BoardsBoardIdSnapshotGet = async (
boardId: string,
options?: RequestInit,
): Promise<getBoardSnapshotApiV1BoardsBoardIdSnapshotGetResponse> => {
return customFetch<getBoardSnapshotApiV1BoardsBoardIdSnapshotGetResponse>(
getGetBoardSnapshotApiV1BoardsBoardIdSnapshotGetUrl(boardId),
{
...options,
method: "GET",
},
);
};
export const getGetBoardSnapshotApiV1BoardsBoardIdSnapshotGetQueryKey = (
boardId: string,
) => {
return [`/api/v1/boards/${boardId}/snapshot`] as const;
};
export const getGetBoardSnapshotApiV1BoardsBoardIdSnapshotGetQueryOptions = <
TData = Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>,
TError = HTTPValidationError,
>(
boardId: string,
options?: {
query?: Partial<
UseQueryOptions<
Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>,
TError,
TData
>
>;
request?: SecondParameter<typeof customFetch>;
},
) => {
const { query: queryOptions, request: requestOptions } = options ?? {};
const queryKey =
queryOptions?.queryKey ??
getGetBoardSnapshotApiV1BoardsBoardIdSnapshotGetQueryKey(boardId);
const queryFn: QueryFunction<
Awaited<ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>>
> = ({ signal }) =>
getBoardSnapshotApiV1BoardsBoardIdSnapshotGet(boardId, {
signal,
...requestOptions,
});
return {
queryKey,
queryFn,
enabled: !!boardId,
...queryOptions,
} as UseQueryOptions<
Awaited<ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>>,
TError,
TData
> & { queryKey: DataTag<QueryKey, TData, TError> };
};
export type GetBoardSnapshotApiV1BoardsBoardIdSnapshotGetQueryResult =
NonNullable<
Awaited<ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>>
>;
export type GetBoardSnapshotApiV1BoardsBoardIdSnapshotGetQueryError =
HTTPValidationError;
export function useGetBoardSnapshotApiV1BoardsBoardIdSnapshotGet<
TData = Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>,
TError = HTTPValidationError,
>(
boardId: string,
options: {
query: Partial<
UseQueryOptions<
Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>,
TError,
TData
>
> &
Pick<
DefinedInitialDataOptions<
Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>,
TError,
Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>
>,
"initialData"
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): DefinedUseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
export function useGetBoardSnapshotApiV1BoardsBoardIdSnapshotGet<
TData = Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>,
TError = HTTPValidationError,
>(
boardId: string,
options?: {
query?: Partial<
UseQueryOptions<
Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>,
TError,
TData
>
> &
Pick<
UndefinedInitialDataOptions<
Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>,
TError,
Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>
>,
"initialData"
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
export function useGetBoardSnapshotApiV1BoardsBoardIdSnapshotGet<
TData = Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>,
TError = HTTPValidationError,
>(
boardId: string,
options?: {
query?: Partial<
UseQueryOptions<
Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>,
TError,
TData
>
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
/**
* @summary Get Board Snapshot
*/
export function useGetBoardSnapshotApiV1BoardsBoardIdSnapshotGet<
TData = Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>,
TError = HTTPValidationError,
>(
boardId: string,
options?: {
query?: Partial<
UseQueryOptions<
Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>,
TError,
TData
>
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
} {
const queryOptions =
getGetBoardSnapshotApiV1BoardsBoardIdSnapshotGetQueryOptions(
boardId,
options,
);
const query = useQuery(queryOptions, queryClient) as UseQueryResult<
TData,
TError
> & { queryKey: DataTag<QueryKey, TData, TError> };
return { ...query, queryKey: queryOptions.queryKey };
}
/** /**
* Get a grouped snapshot across related boards. * Get a grouped snapshot across related boards.
* @summary Get Board Group Snapshot * @summary Get Board Group Snapshot
@@ -1341,3 +1102,242 @@ export function useGetBoardGroupSnapshotApiV1BoardsBoardIdGroupSnapshotGet<
return { ...query, queryKey: queryOptions.queryKey }; return { ...query, queryKey: queryOptions.queryKey };
} }
/**
* Get a board snapshot view model.
* @summary Get Board Snapshot
*/
export type getBoardSnapshotApiV1BoardsBoardIdSnapshotGetResponse200 = {
data: BoardSnapshot;
status: 200;
};
export type getBoardSnapshotApiV1BoardsBoardIdSnapshotGetResponse422 = {
data: HTTPValidationError;
status: 422;
};
export type getBoardSnapshotApiV1BoardsBoardIdSnapshotGetResponseSuccess =
getBoardSnapshotApiV1BoardsBoardIdSnapshotGetResponse200 & {
headers: Headers;
};
export type getBoardSnapshotApiV1BoardsBoardIdSnapshotGetResponseError =
getBoardSnapshotApiV1BoardsBoardIdSnapshotGetResponse422 & {
headers: Headers;
};
export type getBoardSnapshotApiV1BoardsBoardIdSnapshotGetResponse =
| getBoardSnapshotApiV1BoardsBoardIdSnapshotGetResponseSuccess
| getBoardSnapshotApiV1BoardsBoardIdSnapshotGetResponseError;
export const getGetBoardSnapshotApiV1BoardsBoardIdSnapshotGetUrl = (
boardId: string,
) => {
return `/api/v1/boards/${boardId}/snapshot`;
};
export const getBoardSnapshotApiV1BoardsBoardIdSnapshotGet = async (
boardId: string,
options?: RequestInit,
): Promise<getBoardSnapshotApiV1BoardsBoardIdSnapshotGetResponse> => {
return customFetch<getBoardSnapshotApiV1BoardsBoardIdSnapshotGetResponse>(
getGetBoardSnapshotApiV1BoardsBoardIdSnapshotGetUrl(boardId),
{
...options,
method: "GET",
},
);
};
export const getGetBoardSnapshotApiV1BoardsBoardIdSnapshotGetQueryKey = (
boardId: string,
) => {
return [`/api/v1/boards/${boardId}/snapshot`] as const;
};
export const getGetBoardSnapshotApiV1BoardsBoardIdSnapshotGetQueryOptions = <
TData = Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>,
TError = HTTPValidationError,
>(
boardId: string,
options?: {
query?: Partial<
UseQueryOptions<
Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>,
TError,
TData
>
>;
request?: SecondParameter<typeof customFetch>;
},
) => {
const { query: queryOptions, request: requestOptions } = options ?? {};
const queryKey =
queryOptions?.queryKey ??
getGetBoardSnapshotApiV1BoardsBoardIdSnapshotGetQueryKey(boardId);
const queryFn: QueryFunction<
Awaited<ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>>
> = ({ signal }) =>
getBoardSnapshotApiV1BoardsBoardIdSnapshotGet(boardId, {
signal,
...requestOptions,
});
return {
queryKey,
queryFn,
enabled: !!boardId,
...queryOptions,
} as UseQueryOptions<
Awaited<ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>>,
TError,
TData
> & { queryKey: DataTag<QueryKey, TData, TError> };
};
export type GetBoardSnapshotApiV1BoardsBoardIdSnapshotGetQueryResult =
NonNullable<
Awaited<ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>>
>;
export type GetBoardSnapshotApiV1BoardsBoardIdSnapshotGetQueryError =
HTTPValidationError;
export function useGetBoardSnapshotApiV1BoardsBoardIdSnapshotGet<
TData = Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>,
TError = HTTPValidationError,
>(
boardId: string,
options: {
query: Partial<
UseQueryOptions<
Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>,
TError,
TData
>
> &
Pick<
DefinedInitialDataOptions<
Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>,
TError,
Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>
>,
"initialData"
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): DefinedUseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
export function useGetBoardSnapshotApiV1BoardsBoardIdSnapshotGet<
TData = Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>,
TError = HTTPValidationError,
>(
boardId: string,
options?: {
query?: Partial<
UseQueryOptions<
Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>,
TError,
TData
>
> &
Pick<
UndefinedInitialDataOptions<
Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>,
TError,
Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>
>,
"initialData"
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
export function useGetBoardSnapshotApiV1BoardsBoardIdSnapshotGet<
TData = Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>,
TError = HTTPValidationError,
>(
boardId: string,
options?: {
query?: Partial<
UseQueryOptions<
Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>,
TError,
TData
>
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
/**
* @summary Get Board Snapshot
*/
export function useGetBoardSnapshotApiV1BoardsBoardIdSnapshotGet<
TData = Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>,
TError = HTTPValidationError,
>(
boardId: string,
options?: {
query?: Partial<
UseQueryOptions<
Awaited<
ReturnType<typeof getBoardSnapshotApiV1BoardsBoardIdSnapshotGet>
>,
TError,
TData
>
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
} {
const queryOptions =
getGetBoardSnapshotApiV1BoardsBoardIdSnapshotGetQueryOptions(
boardId,
options,
);
const query = useQuery(queryOptions, queryClient) as UseQueryResult<
TData,
TError
> & { queryKey: DataTag<QueryKey, TData, TError> };
return { ...query, queryKey: queryOptions.queryKey };
}

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -9,10 +9,10 @@
* Serialized activity event payload returned by activity endpoints. * Serialized activity event payload returned by activity endpoints.
*/ */
export interface ActivityEventRead { export interface ActivityEventRead {
id: string;
event_type: string;
message: string | null;
agent_id: string | null; agent_id: string | null;
task_id: string | null;
created_at: string; created_at: string;
event_type: string;
id: string;
message: string | null;
task_id: string | null;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -9,14 +9,14 @@
* Denormalized task-comment feed item enriched with task and board fields. * Denormalized task-comment feed item enriched with task and board fields.
*/ */
export interface ActivityTaskCommentFeedItemRead { export interface ActivityTaskCommentFeedItemRead {
id: string;
created_at: string;
message: string | null;
agent_id: string | null; agent_id: string | null;
agent_name?: string | null; agent_name?: string | null;
agent_role?: string | null; agent_role?: string | null;
task_id: string;
task_title: string;
board_id: string; board_id: string;
board_name: string; board_name: string;
created_at: string;
id: string;
message: string | null;
task_id: string;
task_title: string;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -12,11 +12,11 @@ import type { AgentCreateIdentityProfile } from "./agentCreateIdentityProfile";
*/ */
export interface AgentCreate { export interface AgentCreate {
board_id?: string | null; board_id?: string | null;
/** @minLength 1 */
name: string;
status?: string;
heartbeat_config?: AgentCreateHeartbeatConfig; heartbeat_config?: AgentCreateHeartbeatConfig;
identity_profile?: AgentCreateIdentityProfile; identity_profile?: AgentCreateIdentityProfile;
identity_template?: string | null; identity_template?: string | null;
/** @minLength 1 */
name: string;
soul_template?: string | null; soul_template?: string | null;
status?: string;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -9,8 +9,8 @@
* Heartbeat payload used to create an agent lazily. * Heartbeat payload used to create an agent lazily.
*/ */
export interface AgentHeartbeatCreate { export interface AgentHeartbeatCreate {
status?: string | null; board_id?: string | null;
/** @minLength 1 */ /** @minLength 1 */
name: string; name: string;
board_id?: string | null; status?: string | null;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -12,19 +12,19 @@ import type { AgentReadIdentityProfile } from "./agentReadIdentityProfile";
*/ */
export interface AgentRead { export interface AgentRead {
board_id?: string | null; board_id?: string | null;
/** @minLength 1 */ created_at: string;
name: string; gateway_id: string;
status?: string;
heartbeat_config?: AgentReadHeartbeatConfig; heartbeat_config?: AgentReadHeartbeatConfig;
id: string;
identity_profile?: AgentReadIdentityProfile; identity_profile?: AgentReadIdentityProfile;
identity_template?: string | null; identity_template?: string | null;
soul_template?: string | null;
id: string;
gateway_id: string;
is_board_lead?: boolean; is_board_lead?: boolean;
is_gateway_main?: boolean; is_gateway_main?: boolean;
openclaw_session_id?: string | null;
last_seen_at: string | null; last_seen_at: string | null;
created_at: string; /** @minLength 1 */
name: string;
openclaw_session_id?: string | null;
soul_template?: string | null;
status?: string;
updated_at: string; updated_at: string;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -12,11 +12,11 @@ import type { AgentUpdateIdentityProfile } from "./agentUpdateIdentityProfile";
*/ */
export interface AgentUpdate { export interface AgentUpdate {
board_id?: string | null; board_id?: string | null;
is_gateway_main?: boolean | null;
name?: string | null;
status?: string | null;
heartbeat_config?: AgentUpdateHeartbeatConfig; heartbeat_config?: AgentUpdateHeartbeatConfig;
identity_profile?: AgentUpdateIdentityProfile; identity_profile?: AgentUpdateIdentityProfile;
identity_template?: string | null; identity_template?: string | null;
is_gateway_main?: boolean | null;
name?: string | null;
soul_template?: string | null; soul_template?: string | null;
status?: string | null;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -13,10 +13,11 @@ import type { ApprovalCreateStatus } from "./approvalCreateStatus";
*/ */
export interface ApprovalCreate { export interface ApprovalCreate {
action_type: string; action_type: string;
task_id?: string | null; agent_id?: string | null;
payload?: ApprovalCreatePayload;
confidence: number; confidence: number;
payload?: ApprovalCreatePayload;
rubric_scores?: ApprovalCreateRubricScores; rubric_scores?: ApprovalCreateRubricScores;
status?: ApprovalCreateStatus; status?: ApprovalCreateStatus;
agent_id?: string | null; task_id?: string | null;
task_ids?: string[];
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -13,14 +13,15 @@ import type { ApprovalReadStatus } from "./approvalReadStatus";
*/ */
export interface ApprovalRead { export interface ApprovalRead {
action_type: string; action_type: string;
task_id?: string | null; agent_id?: string | null;
payload?: ApprovalReadPayload; board_id: string;
confidence: number; confidence: number;
created_at: string;
id: string;
payload?: ApprovalReadPayload;
resolved_at?: string | null;
rubric_scores?: ApprovalReadRubricScores; rubric_scores?: ApprovalReadRubricScores;
status?: ApprovalReadStatus; status?: ApprovalReadStatus;
id: string; task_id?: string | null;
board_id: string; task_ids?: string[];
agent_id?: string | null;
created_at: string;
resolved_at?: string | null;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -9,6 +9,6 @@
* Error detail payload listing blocking dependency task identifiers. * Error detail payload listing blocking dependency task identifiers.
*/ */
export interface BlockedTaskDetail { export interface BlockedTaskDetail {
message: string;
blocked_by_task_ids?: string[]; blocked_by_task_ids?: string[];
message: string;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -10,15 +10,15 @@ import type { BoardCreateSuccessMetrics } from "./boardCreateSuccessMetrics";
* Payload for creating a board. * Payload for creating a board.
*/ */
export interface BoardCreate { export interface BoardCreate {
name: string;
slug: string;
description: string;
gateway_id?: string | null;
board_group_id?: string | null; board_group_id?: string | null;
board_type?: string; board_type?: string;
objective?: string | null; description: string;
success_metrics?: BoardCreateSuccessMetrics; gateway_id?: string | null;
target_date?: string | null;
goal_confirmed?: boolean; goal_confirmed?: boolean;
goal_source?: string | null; goal_source?: string | null;
name: string;
objective?: string | null;
slug: string;
success_metrics?: BoardCreateSuccessMetrics;
target_date?: string | null;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -9,7 +9,7 @@
* Payload for creating a board group. * Payload for creating a board group.
*/ */
export interface BoardGroupCreate { export interface BoardGroupCreate {
description?: string | null;
name: string; name: string;
slug: string; slug: string;
description?: string | null;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -10,6 +10,6 @@
*/ */
export interface BoardGroupHeartbeatApply { export interface BoardGroupHeartbeatApply {
every: string; every: string;
target?: string | null;
include_board_leads?: boolean; include_board_leads?: boolean;
target?: string | null;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -11,7 +11,7 @@ import type { BoardGroupHeartbeatApplyResultRequested } from "./boardGroupHeartb
*/ */
export interface BoardGroupHeartbeatApplyResult { export interface BoardGroupHeartbeatApplyResult {
board_group_id: string; board_group_id: string;
failed_agent_ids: string[];
requested: BoardGroupHeartbeatApplyResultRequested; requested: BoardGroupHeartbeatApplyResultRequested;
updated_agent_ids: string[]; updated_agent_ids: string[];
failed_agent_ids: string[];
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -11,6 +11,6 @@
export interface BoardGroupMemoryCreate { export interface BoardGroupMemoryCreate {
/** @minLength 1 */ /** @minLength 1 */
content: string; content: string;
tags?: string[] | null;
source?: string | null; source?: string | null;
tags?: string[] | null;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -9,11 +9,11 @@
* Serialized board-group memory entry returned from read endpoints. * Serialized board-group memory entry returned from read endpoints.
*/ */
export interface BoardGroupMemoryRead { export interface BoardGroupMemoryRead {
id: string;
board_group_id: string; board_group_id: string;
content: string; content: string;
tags?: string[] | null;
source?: string | null;
is_chat?: boolean;
created_at: string; created_at: string;
id: string;
is_chat?: boolean;
source?: string | null;
tags?: string[] | null;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -9,11 +9,11 @@
* Board-group payload returned from read endpoints. * Board-group payload returned from read endpoints.
*/ */
export interface BoardGroupRead { export interface BoardGroupRead {
name: string; created_at: string;
slug: string;
description?: string | null; description?: string | null;
id: string; id: string;
name: string;
organization_id: string; organization_id: string;
created_at: string; slug: string;
updated_at: string; updated_at: string;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -11,6 +11,6 @@ import type { BoardGroupRead } from "./boardGroupRead";
* Top-level board-group snapshot response payload. * Top-level board-group snapshot response payload.
*/ */
export interface BoardGroupSnapshot { export interface BoardGroupSnapshot {
group?: BoardGroupRead | null;
boards?: BoardGroupBoardSnapshot[]; boards?: BoardGroupBoardSnapshot[];
group?: BoardGroupRead | null;
} }

View File

@@ -1,24 +1,26 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
*/ */
import type { TaskTagRef } from "./taskTagRef";
/** /**
* Task summary row used inside board-group snapshot responses. * Task summary row used inside board-group snapshot responses.
*/ */
export interface BoardGroupTaskSummary { export interface BoardGroupTaskSummary {
id: string;
board_id: string;
board_name: string;
title: string;
status: string;
priority: string;
assigned_agent_id?: string | null; assigned_agent_id?: string | null;
assignee?: string | null; assignee?: string | null;
due_at?: string | null; board_id: string;
in_progress_at?: string | null; board_name: string;
created_at: string; created_at: string;
due_at?: string | null;
id: string;
in_progress_at?: string | null;
priority: string;
status: string;
tags?: TaskTagRef[];
title: string;
updated_at: string; updated_at: string;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -9,7 +9,7 @@
* Payload for partial board-group updates. * Payload for partial board-group updates.
*/ */
export interface BoardGroupUpdate { export interface BoardGroupUpdate {
description?: string | null;
name?: string | null; name?: string | null;
slug?: string | null; slug?: string | null;
description?: string | null;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -11,6 +11,6 @@
export interface BoardMemoryCreate { export interface BoardMemoryCreate {
/** @minLength 1 */ /** @minLength 1 */
content: string; content: string;
tags?: string[] | null;
source?: string | null; source?: string | null;
tags?: string[] | null;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -9,11 +9,11 @@
* Serialized board memory entry returned from read endpoints. * Serialized board memory entry returned from read endpoints.
*/ */
export interface BoardMemoryRead { export interface BoardMemoryRead {
id: string;
board_id: string; board_id: string;
content: string; content: string;
tags?: string[] | null;
source?: string | null;
is_chat?: boolean;
created_at: string; created_at: string;
id: string;
is_chat?: boolean;
source?: string | null;
tags?: string[] | null;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -13,10 +13,10 @@ import type { BoardOnboardingUserProfile } from "./boardOnboardingUserProfile";
*/ */
export interface BoardOnboardingAgentComplete { export interface BoardOnboardingAgentComplete {
board_type: string; board_type: string;
lead_agent?: BoardOnboardingLeadAgentDraft | null;
objective?: string | null; objective?: string | null;
status: "complete";
success_metrics?: BoardOnboardingAgentCompleteSuccessMetrics; success_metrics?: BoardOnboardingAgentCompleteSuccessMetrics;
target_date?: string | null; target_date?: string | null;
status: "complete";
user_profile?: BoardOnboardingUserProfile | null; user_profile?: BoardOnboardingUserProfile | null;
lead_agent?: BoardOnboardingLeadAgentDraft | null;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -10,8 +10,8 @@ import type { BoardOnboardingQuestionOption } from "./boardOnboardingQuestionOpt
* Question payload emitted by the onboarding assistant. * Question payload emitted by the onboarding assistant.
*/ */
export interface BoardOnboardingAgentQuestion { export interface BoardOnboardingAgentQuestion {
/** @minLength 1 */
question: string;
/** @minItems 1 */ /** @minItems 1 */
options: BoardOnboardingQuestionOption[]; options: BoardOnboardingQuestionOption[];
/** @minLength 1 */
question: string;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -10,11 +10,11 @@ import type { BoardOnboardingLeadAgentDraftIdentityProfile } from "./boardOnboar
* Editable lead-agent draft configuration. * Editable lead-agent draft configuration.
*/ */
export interface BoardOnboardingLeadAgentDraft { export interface BoardOnboardingLeadAgentDraft {
name?: string | null;
identity_profile?: BoardOnboardingLeadAgentDraftIdentityProfile;
autonomy_level?: "ask_first" | "balanced" | "autonomous" | null; autonomy_level?: "ask_first" | "balanced" | "autonomous" | null;
verbosity?: "concise" | "balanced" | "detailed" | null; custom_instructions?: string | null;
identity_profile?: BoardOnboardingLeadAgentDraftIdentityProfile;
name?: string | null;
output_format?: "bullets" | "mixed" | "narrative" | null; output_format?: "bullets" | "mixed" | "narrative" | null;
update_cadence?: "asap" | "hourly" | "daily" | "weekly" | null; update_cadence?: "asap" | "hourly" | "daily" | "weekly" | null;
custom_instructions?: string | null; verbosity?: "concise" | "balanced" | "detailed" | null;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -11,12 +11,12 @@ import type { BoardOnboardingReadMessages } from "./boardOnboardingReadMessages"
* Stored onboarding session state returned by API endpoints. * Stored onboarding session state returned by API endpoints.
*/ */
export interface BoardOnboardingRead { export interface BoardOnboardingRead {
id: string;
board_id: string; board_id: string;
created_at: string;
draft_goal?: BoardOnboardingAgentComplete | null;
id: string;
messages?: BoardOnboardingReadMessages;
session_key: string; session_key: string;
status: string; status: string;
messages?: BoardOnboardingReadMessages;
draft_goal?: BoardOnboardingAgentComplete | null;
created_at: string;
updated_at: string; updated_at: string;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -9,9 +9,9 @@
* User-profile preferences gathered during onboarding. * User-profile preferences gathered during onboarding.
*/ */
export interface BoardOnboardingUserProfile { export interface BoardOnboardingUserProfile {
context?: string | null;
notes?: string | null;
preferred_name?: string | null; preferred_name?: string | null;
pronouns?: string | null; pronouns?: string | null;
timezone?: string | null; timezone?: string | null;
notes?: string | null;
context?: string | null;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -10,19 +10,19 @@ import type { BoardReadSuccessMetrics } from "./boardReadSuccessMetrics";
* Board payload returned from read endpoints. * Board payload returned from read endpoints.
*/ */
export interface BoardRead { export interface BoardRead {
name: string;
slug: string;
description: string;
gateway_id?: string | null;
board_group_id?: string | null; board_group_id?: string | null;
board_type?: string; board_type?: string;
objective?: string | null; created_at: string;
success_metrics?: BoardReadSuccessMetrics; description: string;
target_date?: string | null; gateway_id?: string | null;
goal_confirmed?: boolean; goal_confirmed?: boolean;
goal_source?: string | null; goal_source?: string | null;
id: string; id: string;
name: string;
objective?: string | null;
organization_id: string; organization_id: string;
created_at: string; slug: string;
success_metrics?: BoardReadSuccessMetrics;
target_date?: string | null;
updated_at: string; updated_at: string;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -14,10 +14,10 @@ import type { TaskCardRead } from "./taskCardRead";
* Aggregated board payload used by board snapshot endpoints. * Aggregated board payload used by board snapshot endpoints.
*/ */
export interface BoardSnapshot { export interface BoardSnapshot {
board: BoardRead;
tasks: TaskCardRead[];
agents: AgentRead[]; agents: AgentRead[];
approvals: ApprovalRead[]; approvals: ApprovalRead[];
board: BoardRead;
chat_messages: BoardMemoryRead[]; chat_messages: BoardMemoryRead[];
pending_approvals_count?: number; pending_approvals_count?: number;
tasks: TaskCardRead[];
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -10,15 +10,15 @@ import type { BoardUpdateSuccessMetrics } from "./boardUpdateSuccessMetrics";
* Payload for partial board updates. * Payload for partial board updates.
*/ */
export interface BoardUpdate { export interface BoardUpdate {
name?: string | null;
slug?: string | null;
description?: string | null;
gateway_id?: string | null;
board_group_id?: string | null; board_group_id?: string | null;
board_type?: string | null; board_type?: string | null;
objective?: string | null; description?: string | null;
success_metrics?: BoardUpdateSuccessMetrics; gateway_id?: string | null;
target_date?: string | null;
goal_confirmed?: boolean | null; goal_confirmed?: boolean | null;
goal_source?: string | null; goal_source?: string | null;
name?: string | null;
objective?: string | null;
slug?: string | null;
success_metrics?: BoardUpdateSuccessMetrics;
target_date?: string | null;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -10,7 +10,7 @@
*/ */
export interface DashboardKpis { export interface DashboardKpis {
active_agents: number; active_agents: number;
tasks_in_progress: number;
error_rate_pct: number; error_rate_pct: number;
median_cycle_time_hours_7d: number | null; median_cycle_time_hours_7d: number | null;
tasks_in_progress: number;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -13,11 +13,11 @@ import type { DashboardWipSeriesSet } from "./dashboardWipSeriesSet";
* Complete dashboard metrics response payload. * Complete dashboard metrics response payload.
*/ */
export interface DashboardMetrics { export interface DashboardMetrics {
range: DashboardMetricsRange;
generated_at: string;
kpis: DashboardKpis;
throughput: DashboardSeriesSet;
cycle_time: DashboardSeriesSet; cycle_time: DashboardSeriesSet;
error_rate: DashboardSeriesSet; error_rate: DashboardSeriesSet;
generated_at: string;
kpis: DashboardKpis;
range: DashboardMetricsRange;
throughput: DashboardSeriesSet;
wip: DashboardWipSeriesSet; wip: DashboardWipSeriesSet;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0
@@ -12,7 +12,7 @@ import type { DashboardSeriesPoint } from "./dashboardSeriesPoint";
* Series payload for a single range/bucket combination. * Series payload for a single range/bucket combination.
*/ */
export interface DashboardRangeSeries { export interface DashboardRangeSeries {
range: DashboardRangeSeriesRange;
bucket: DashboardRangeSeriesBucket; bucket: DashboardRangeSeriesBucket;
points: DashboardSeriesPoint[]; points: DashboardSeriesPoint[];
range: DashboardRangeSeriesRange;
} }

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

View File

@@ -1,5 +1,5 @@
/** /**
* Generated by orval v8.2.0 🍺 * Generated by orval v8.3.0 🍺
* Do not edit manually. * Do not edit manually.
* Mission Control API * Mission Control API
* OpenAPI spec version: 0.1.0 * OpenAPI spec version: 0.1.0

Some files were not shown because too many files have changed in this diff Show More