Docs · 40
API interna.
Server actions y HTTP endpoints — qué expone hoy y qué shape devuelven.
El modelo de API
Codacle no expone una API pública versionada todavía. Lo que existe son dos superficies internas que pueden usar consumers en el monorepo:
- Server actions (Next.js) — funciones marcadas
'use server'invocadas desde formularios o components. Tipadas end-to-end, no se ven como endpoints HTTP separados. - Route handlers (
apps/web/app/api/...) — endpoints HTTP reales, usados por componentes client para polling.
Server actions
createWorkspaceAndStart(formData)
Ubicación: apps/web/lib/actions/workspace.ts
Input form fields:
kitId(string) — el id del kit del catálogo.
Comportamiento:
- Resuelve el kit con
getKitById. Throw si no existe o si!isRegistered(sin agents). - Encuentra la versión publicada (o la última registrada) en
kits/kit_publications. - INSERT
workspacesconkit_id+kit_versionpinneados. redirecta/migrations/new?ws=...&kit=....
publishKitVersion(formData) / unpublishKit(formData)
Ubicación: apps/web/lib/actions/kits.ts
Input form fields:
kitId(string)version(string) — sólo parapublishKitVersion.
Comportamiento:
publishKitVersion: UPSERT enkit_publications.revalidatePatha/kits,/kits/[id],/marketplace.unpublishKit: DELETE dekit_publicationspara ese kit. Mismo revalidate.
uploadWorkspaceFile(formData) / triggerAnalyze(formData)
Ubicación: apps/web/lib/actions/workspace.ts
Suben archivos a Supabase Storage para el workspace y disparan el job analyze. triggerAnalyze cambia workspace.status a analyzing y encola el job.
Route handlers
GET /api/workspaces/[id]/ops-state
Devuelve el snapshot completo del workspace para el polling de /ops/[id]:
{
"workspace": { "id": "...", "status": "...", "kit_id": "...", ... },
"runs": [{ "id": "...", "stage": "analyze", "status": "done", "usage": {...}, ... }],
"phases": [{ "phase_k": "...", "status": "completed", ... }],
"jobs": [{ "id": "...", "type": "analyze", "status": "done", ... }]
}
Polling frecuente (5–10s) mientras el workspace está activo.
GET /api/workspaces/[id]/phases
Versión más liviana — sólo workspace_phases. Usado por PipelineLive en el tab /pipeline.
[
{ "phase_k": "extract", "label": "Extraer atoms", "status": "completed",
"started_at": "...", "completed_at": "...", "updated_at": "..." }
]
GET /api/workspaces/[id]/files
Lista archivos subidos al workspace, con metadata (size, original_path, slot key). Usado por el wizard.
GET /api/workspaces/[id]/vault
Lista de atoms del Vault con filtros por tipo. Usado por /migrations/[id]/vault.
Convenciones
- Sin auth todavía: las routes usan service-role bypass de RLS. Cuando lleguemos a auth (Slice 5+), agregamos middleware que valida la sesión y el org_id contra el workspace.
- Tipado: las route handlers exportan el shape como
type ... = { ... }desde el mismo archivo para que el client component que pollea pueda importarlo (import type { PhaseRow } from '@/app/api/workspaces/[id]/phases/route'). - Errores: server actions hacen
throw new Error(message)y Next renderiza el error boundary. Las route handlers devuelven{ error: string }con status 4xx/5xx.
Webhooks
No hay webhooks externos. La interacción con Anthropic es síncrona dentro de cada job del worker — abrimos session, consumimos stream, cerramos. No hay callback de Anthropic hacia nosotros.
CLI scripts útiles
Todos están en apps/web/scripts/ y se invocan via pnpm:
| Script | Para qué |
|---|---|
register-kit --kit-dir <path> | Sube un kit a Anthropic + upsertea row en kits. |
validate-kit -- --kit-dir <path> | Sólo valida schema, sin subir nada. |
inspect-run <run_id> | Imprime el timeline de un workspace_run con tokens + costo. |
cost-report --days <n> | Suma USD por kit / modelo / período. |
anthropic-resources | Lista recursos en Anthropic (sessions, environments, memory_stores) y cruza contra DB para detectar huérfanos. |
cleanup-orphaned | Borra recursos de Anthropic que no aparecen en ninguna tabla nuestra. |
debug-pricing | Imprime los rates actuales + un ejemplo de cálculo. |