diff --git a/src/server/routes.ts b/src/server/routes.ts index a633888..8acdec0 100644 --- a/src/server/routes.ts +++ b/src/server/routes.ts @@ -1,27 +1,69 @@ import { FastifyInstance } from 'fastify'; -import { Index } from '../core/index.js'; +import { createTask, listTasks, getTask, claimTask, doneTask } from '../core/services/taskService.js'; +import { createHandoff, listHandoffs, getHandoff } from '../core/services/handoffService.js'; +import { createDecision, listDecisions } from '../core/services/decisionService.js'; +import { addMemory, searchMemory, listMemory } from '../core/services/memoryService.js'; +import { getStatus, updateStatus } from '../core/services/statusService.js'; +import { autoDelegate, suggestDelegation } from '../core/services/delegateService.js'; +import type { Task, Handoff, Decision, Memory } from '../core/schema.js'; export async function registerRoutes(app: FastifyInstance, cwd: string): Promise { - app.get('/status', async () => { - const index = new Index(cwd); - const open = index.list('task', { status: 'open' }); - const inProgress = index.list('task', { status: 'in_progress' }); - index.close(); - return { open: open.length, inProgress: inProgress.length }; + app.get('/status', async () => ({ body: getStatus(cwd) })); + app.post('/status/update', async () => ({ body: updateStatus(cwd) })); + + app.get('/tasks', async (request) => { + const { status, role } = request.query as { status?: string; role?: string }; + return listTasks(cwd, { status, role }); }); - app.get('/tasks', async () => { - const index = new Index(cwd); - const tasks = index.list('task'); - index.close(); - return tasks; + app.post('/tasks', async (request) => { + return createTask(cwd, request.body as Partial); }); - app.get('/search', async (request) => { + app.get('/tasks/:id', async (request) => { + const { id } = request.params as { id: string }; + const { task, body } = getTask(cwd, id); + return { task, body }; + }); + + app.patch('/tasks/:id', async (request) => { + const { id } = request.params as { id: string }; + const patch = request.body as Partial; + if (patch.status === 'in_progress' && patch.assignedTo) { + return claimTask(cwd, id, patch.assignedTo); + } + if (patch.status === 'done') { + return doneTask(cwd, id); + } + return { error: 'Unsupported patch' }; + }); + + app.get('/handoffs', async () => listHandoffs(cwd)); + app.post('/handoffs', async (request) => createHandoff(cwd, request.body as Partial)); + app.get('/handoffs/:id', async (request) => { + const { id } = request.params as { id: string }; + const { handoff, body } = getHandoff(cwd, id); + return { handoff, body }; + }); + + app.get('/decisions', async () => listDecisions(cwd)); + app.post('/decisions', async (request) => createDecision(cwd, request.body as Partial)); + + app.get('/memory', async () => listMemory(cwd)); + app.post('/memory', async (request) => addMemory(cwd, request.body as Partial)); + app.get('/memory/search', async (request) => { const { q } = request.query as { q: string }; - const index = new Index(cwd); - const results = index.search(q); - index.close(); - return results; + return searchMemory(cwd, q ?? ''); + }); + + app.post('/delegate', async (request) => { + const { auto } = request.query as { auto?: string }; + const suggestion = suggestDelegation(cwd); + if (!suggestion) return { suggestion: null }; + if (auto === 'true') { + const handoff = autoDelegate(cwd); + return { suggestion, handoff }; + } + return { suggestion }; }); }