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>
545 lines
12 KiB
Markdown
545 lines
12 KiB
Markdown
# 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:
|
|
|
|
```http
|
|
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
|
|
|
|
```http
|
|
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:**
|
|
|
|
```json
|
|
{
|
|
"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
|
|
|
|
```http
|
|
GET /api/tasks/:id
|
|
```
|
|
|
|
**Response:** Same as task object above, plus `subtasks` array.
|
|
|
|
### Create Task
|
|
|
|
```http
|
|
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
|
|
|
|
```http
|
|
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
|
|
|
|
```http
|
|
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
|
|
|
|
```http
|
|
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:**
|
|
|
|
```json
|
|
{
|
|
"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
|
|
|
|
```http
|
|
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
|
|
|
|
```http
|
|
PATCH /api/events/:id
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"location": "Conference Room B"
|
|
}
|
|
```
|
|
|
|
All fields optional for partial updates.
|
|
|
|
### Delete Event
|
|
|
|
```http
|
|
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
|
|
|
|
```http
|
|
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:**
|
|
|
|
```json
|
|
{
|
|
"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
|
|
|
|
```http
|
|
GET /api/projects/:id
|
|
```
|
|
|
|
Returns project with embedded tasks and events arrays.
|
|
|
|
### Create Project
|
|
|
|
```http
|
|
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
|
|
|
|
```http
|
|
PATCH /api/projects/:id
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"status": "COMPLETED"
|
|
}
|
|
```
|
|
|
|
All fields optional for partial updates.
|
|
|
|
### Delete Project
|
|
|
|
```http
|
|
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.
|
|
|
|
```json
|
|
{
|
|
"statusCode": 400,
|
|
"message": "Validation failed",
|
|
"error": "Bad Request"
|
|
}
|
|
```
|
|
|
|
### 401 Unauthorized
|
|
|
|
Missing or invalid authentication token.
|
|
|
|
```json
|
|
{
|
|
"statusCode": 401,
|
|
"message": "No authentication token provided",
|
|
"error": "Unauthorized"
|
|
}
|
|
```
|
|
|
|
### 404 Not Found
|
|
|
|
Resource not found or not accessible in workspace.
|
|
|
|
```json
|
|
{
|
|
"statusCode": 404,
|
|
"message": "Task with ID 550e8400-e29b-41d4-a716-446655440003 not found",
|
|
"error": "Not Found"
|
|
}
|
|
```
|
|
|
|
### 422 Unprocessable Entity
|
|
|
|
Validation errors in request body.
|
|
|
|
```json
|
|
{
|
|
"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](../3-activity-logging/README.md) for querying audit trails.
|
|
|
|
## Examples
|
|
|
|
### Create Task with Project Association
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
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
|
|
|
|
- [Activity Logging API](../3-activity-logging/README.md)
|
|
- [Authentication](../2-authentication/1-endpoints.md)
|
|
- [API Conventions](../1-conventions/1-endpoints.md)
|