Files
stack/docs/4-api/4-crud-endpoints/README.md
Jason Woltje 12abdfe81d feat(#93): implement agent spawn via federation
Implements FED-010: Agent Spawn via Federation feature that enables
spawning and managing Claude agents on remote federated Mosaic Stack
instances via COMMAND message type.

Features:
- Federation agent command types (spawn, status, kill)
- FederationAgentService for handling agent operations
- Integration with orchestrator's agent spawner/lifecycle services
- API endpoints for spawning, querying status, and killing agents
- Full command routing through federation COMMAND infrastructure
- Comprehensive test coverage (12/12 tests passing)

Architecture:
- Hub → Spoke: Spawn agents on remote instances
- Command flow: FederationController → FederationAgentService →
  CommandService → Remote Orchestrator
- Response handling: Remote orchestrator returns agent status/results
- Security: Connection validation, signature verification

Files created:
- apps/api/src/federation/types/federation-agent.types.ts
- apps/api/src/federation/federation-agent.service.ts
- apps/api/src/federation/federation-agent.service.spec.ts

Files modified:
- apps/api/src/federation/command.service.ts (agent command routing)
- apps/api/src/federation/federation.controller.ts (agent endpoints)
- apps/api/src/federation/federation.module.ts (service registration)
- apps/orchestrator/src/api/agents/agents.controller.ts (status endpoint)
- apps/orchestrator/src/api/agents/agents.module.ts (lifecycle integration)

Testing:
- 12/12 tests passing for FederationAgentService
- All command service tests passing
- TypeScript compilation successful
- Linting passed

Refs #93

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-03 14:37:06 -06:00

12 KiB

CRUD API Endpoints

Complete reference for Tasks, Events, and Projects API endpoints.

Overview

All CRUD endpoints follow standard REST conventions and require authentication. They support:

  • Full CRUD operations (Create, Read, Update, Delete)
  • Workspace-scoped isolation
  • Pagination and filtering
  • Activity logging for audit trails

Authentication

All endpoints require Bearer token authentication:

Authorization: Bearer {session_token}

The workspace context is extracted from the authenticated user's session.

Tasks API

Endpoints

GET    /api/tasks           # List tasks
GET    /api/tasks/:id       # Get single task
POST   /api/tasks           # Create task
PATCH  /api/tasks/:id       # Update task
DELETE /api/tasks/:id       # Delete task

List Tasks

GET /api/tasks?status=IN_PROGRESS&page=1&limit=20

Query Parameters:

  • workspaceId (UUID, required) — Workspace ID
  • status (enum, optional) — NOT_STARTED, IN_PROGRESS, PAUSED, COMPLETED, ARCHIVED
  • priority (enum, optional) — LOW, MEDIUM, HIGH
  • assigneeId (UUID, optional) — Filter by assigned user
  • projectId (UUID, optional) — Filter by project
  • parentId (UUID, optional) — Filter by parent task (for subtasks)
  • dueDateFrom (ISO 8601, optional) — Filter tasks due after this date
  • dueDateTo (ISO 8601, optional) — Filter tasks due before this date
  • page (integer, optional) — Page number (default: 1)
  • limit (integer, optional) — Items per page (default: 50, max: 100)

Response:

{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440003",
      "workspaceId": "550e8400-e29b-41d4-a716-446655440001",
      "title": "Complete API documentation",
      "description": "Write comprehensive docs for CRUD endpoints",
      "status": "IN_PROGRESS",
      "priority": "HIGH",
      "dueDate": "2026-02-01T00:00:00.000Z",
      "assigneeId": "550e8400-e29b-41d4-a716-446655440002",
      "creatorId": "550e8400-e29b-41d4-a716-446655440002",
      "projectId": null,
      "parentId": null,
      "sortOrder": 0,
      "metadata": {},
      "createdAt": "2026-01-28T18:00:00.000Z",
      "updatedAt": "2026-01-28T18:00:00.000Z",
      "completedAt": null,
      "assignee": {
        "id": "550e8400-e29b-41d4-a716-446655440002",
        "name": "John Doe",
        "email": "john@example.com"
      },
      "creator": {
        "id": "550e8400-e29b-41d4-a716-446655440002",
        "name": "John Doe",
        "email": "john@example.com"
      },
      "project": null
    }
  ],
  "meta": {
    "total": 42,
    "page": 1,
    "limit": 20,
    "totalPages": 3
  }
}

Get Single Task

GET /api/tasks/:id

Response: Same as task object above, plus subtasks array.

Create Task

POST /api/tasks
Content-Type: application/json

{
  "title": "Complete API documentation",
  "description": "Write comprehensive docs for CRUD endpoints",
  "status": "IN_PROGRESS",
  "priority": "HIGH",
  "dueDate": "2026-02-01T00:00:00.000Z",
  "assigneeId": "550e8400-e29b-41d4-a716-446655440002",
  "projectId": null,
  "parentId": null,
  "sortOrder": 0,
  "metadata": {}
}

Fields:

  • title (string, required, 1-255 chars) — Task title
  • description (string, optional, max 10000 chars) — Detailed description
  • status (enum, optional) — Default: NOT_STARTED
  • priority (enum, optional) — Default: MEDIUM
  • dueDate (ISO 8601, optional) — Target completion date
  • assigneeId (UUID, optional) — Assigned user
  • projectId (UUID, optional) — Associated project
  • parentId (UUID, optional) — Parent task (for subtasks)
  • sortOrder (integer, optional, min: 0) — Display order
  • metadata (object, optional) — Custom metadata

Response (200): Created task object

Activity Log: Automatically logs CREATED action for task entity.

Update Task

PATCH /api/tasks/:id
Content-Type: application/json

{
  "status": "COMPLETED"
}

All fields are optional for partial updates. Setting status to COMPLETED automatically sets completedAt timestamp.

Response (200): Updated task object

Activity Logs:

  • UPDATED — Always logged
  • COMPLETED — Logged when status changes to COMPLETED
  • ASSIGNED — Logged when assigneeId changes

Delete Task

DELETE /api/tasks/:id

Response (200): Empty

Activity Log: Logs DELETED action with task title in details.

Note: Deleting a task with subtasks will cascade delete all subtasks.


Events API

Endpoints

GET    /api/events           # List events
GET    /api/events/:id       # Get single event
POST   /api/events           # Create event
PATCH  /api/events/:id       # Update event
DELETE /api/events/:id       # Delete event

List Events

GET /api/events?startFrom=2026-02-01&startTo=2026-02-28

Query Parameters:

  • workspaceId (UUID, required) — Workspace ID
  • projectId (UUID, optional) — Filter by project
  • startFrom (ISO 8601, optional) — Events starting after this date
  • startTo (ISO 8601, optional) — Events starting before this date
  • allDay (boolean, optional) — Filter all-day events
  • page (integer, optional) — Page number
  • limit (integer, optional) — Items per page

Response:

{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440004",
      "workspaceId": "550e8400-e29b-41d4-a716-446655440001",
      "title": "Team Meeting",
      "description": "Weekly sync",
      "startTime": "2026-02-01T10:00:00.000Z",
      "endTime": "2026-02-01T11:00:00.000Z",
      "allDay": false,
      "location": "Conference Room A",
      "recurrence": null,
      "creatorId": "550e8400-e29b-41d4-a716-446655440002",
      "projectId": null,
      "metadata": {},
      "createdAt": "2026-01-28T18:00:00.000Z",
      "updatedAt": "2026-01-28T18:00:00.000Z",
      "creator": {
        "id": "550e8400-e29b-41d4-a716-446655440002",
        "name": "John Doe",
        "email": "john@example.com"
      },
      "project": null
    }
  ],
  "meta": {
    "total": 15,
    "page": 1,
    "limit": 50,
    "totalPages": 1
  }
}

Create Event

POST /api/events
Content-Type: application/json

{
  "title": "Team Meeting",
  "description": "Weekly sync",
  "startTime": "2026-02-01T10:00:00.000Z",
  "endTime": "2026-02-01T11:00:00.000Z",
  "allDay": false,
  "location": "Conference Room A",
  "recurrence": null,
  "projectId": null,
  "metadata": {}
}

Fields:

  • title (string, required, 1-255 chars) — Event title
  • description (string, optional, max 10000 chars) — Description
  • startTime (ISO 8601, required) — Event start time
  • endTime (ISO 8601, optional) — Event end time
  • allDay (boolean, optional) — Default: false
  • location (string, optional, max 500 chars) — Location
  • recurrence (object, optional) — Recurrence rules (RRULE format)
  • projectId (UUID, optional) — Associated project
  • metadata (object, optional) — Custom metadata

Update Event

PATCH /api/events/:id
Content-Type: application/json

{
  "location": "Conference Room B"
}

All fields optional for partial updates.

Delete Event

DELETE /api/events/:id

Projects API

Endpoints

GET    /api/projects           # List projects
GET    /api/projects/:id       # Get single project
POST   /api/projects           # Create project
PATCH  /api/projects/:id       # Update project
DELETE /api/projects/:id       # Delete project

List Projects

GET /api/projects?status=ACTIVE

Query Parameters:

  • workspaceId (UUID, required) — Workspace ID
  • status (enum, optional) — PLANNING, ACTIVE, PAUSED, COMPLETED, ARCHIVED
  • startDateFrom (ISO 8601, optional) — Projects starting after this date
  • startDateTo (ISO 8601, optional) — Projects starting before this date
  • page (integer, optional) — Page number
  • limit (integer, optional) — Items per page

Response:

{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440005",
      "workspaceId": "550e8400-e29b-41d4-a716-446655440001",
      "name": "API Development",
      "description": "Build CRUD APIs",
      "status": "ACTIVE",
      "startDate": "2026-01-15",
      "endDate": "2026-02-15",
      "creatorId": "550e8400-e29b-41d4-a716-446655440002",
      "color": "#FF5733",
      "metadata": {},
      "createdAt": "2026-01-28T18:00:00.000Z",
      "updatedAt": "2026-01-28T18:00:00.000Z",
      "creator": {
        "id": "550e8400-e29b-41d4-a716-446655440002",
        "name": "John Doe",
        "email": "john@example.com"
      },
      "_count": {
        "tasks": 12,
        "events": 3
      }
    }
  ],
  "meta": {
    "total": 5,
    "page": 1,
    "limit": 50,
    "totalPages": 1
  }
}

Get Single Project

GET /api/projects/:id

Returns project with embedded tasks and events arrays.

Create Project

POST /api/projects
Content-Type: application/json

{
  "name": "API Development",
  "description": "Build CRUD APIs",
  "status": "ACTIVE",
  "startDate": "2026-01-15",
  "endDate": "2026-02-15",
  "color": "#FF5733",
  "metadata": {}
}

Fields:

  • name (string, required, 1-255 chars) — Project name
  • description (string, optional, max 10000 chars) — Description
  • status (enum, optional) — Default: PLANNING
  • startDate (ISO 8601 date, optional) — Project start date
  • endDate (ISO 8601 date, optional) — Project end date
  • color (string, optional) — Hex color code (e.g., #FF5733)
  • metadata (object, optional) — Custom metadata

Update Project

PATCH /api/projects/:id
Content-Type: application/json

{
  "status": "COMPLETED"
}

All fields optional for partial updates.

Delete Project

DELETE /api/projects/:id

Note: Deleting a project sets projectId to null for all associated tasks and events (does NOT cascade delete).


Error Responses

400 Bad Request

Invalid request format or parameters.

{
  "statusCode": 400,
  "message": "Validation failed",
  "error": "Bad Request"
}

401 Unauthorized

Missing or invalid authentication token.

{
  "statusCode": 401,
  "message": "No authentication token provided",
  "error": "Unauthorized"
}

404 Not Found

Resource not found or not accessible in workspace.

{
  "statusCode": 404,
  "message": "Task with ID 550e8400-e29b-41d4-a716-446655440003 not found",
  "error": "Not Found"
}

422 Unprocessable Entity

Validation errors in request body.

{
  "statusCode": 422,
  "message": ["title must not be empty", "priority must be a valid TaskPriority"],
  "error": "Unprocessable Entity"
}

Activity Logging

All CRUD operations automatically create activity log entries for audit trails:

  • Tasks: CREATED, UPDATED, DELETED, COMPLETED, ASSIGNED
  • Events: CREATED, UPDATED, DELETED
  • Projects: CREATED, UPDATED, DELETED

See Activity Logging API for querying audit trails.

Examples

Create Task with Project Association

curl -X POST http://localhost:3001/api/tasks \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${TOKEN}" \
  -d '{
    "title": "Design database schema",
    "description": "Create ERD for new features",
    "priority": "HIGH",
    "projectId": "550e8400-e29b-41d4-a716-446655440005",
    "dueDate": "2026-02-05T00:00:00.000Z"
  }'

Filter Tasks by Multiple Criteria

curl "http://localhost:3001/api/tasks?\
workspaceId=550e8400-e29b-41d4-a716-446655440001&\
status=IN_PROGRESS&\
priority=HIGH&\
dueDateFrom=2026-02-01&\
dueDateTo=2026-02-28&\
page=1&\
limit=20" \
  -H "Authorization: Bearer ${TOKEN}"

Update Task Status to Completed

curl -X PATCH http://localhost:3001/api/tasks/550e8400-e29b-41d4-a716-446655440003 \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${TOKEN}" \
  -d '{
    "status": "COMPLETED"
  }'

Create Recurring Event

curl -X POST http://localhost:3001/api/events \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${TOKEN}" \
  -d '{
    "title": "Weekly Team Sync",
    "startTime": "2026-02-03T10:00:00.000Z",
    "endTime": "2026-02-03T11:00:00.000Z",
    "recurrence": {
      "freq": "WEEKLY",
      "interval": 1,
      "byweekday": ["MO"]
    },
    "location": "Zoom"
  }'

Next Steps