Ir al contenido

API routes

EMA Vault expone 44 módulos API bajo el worker Hono, organizados por dominio operativo (negocio, finanzas, producto, sistema) y con verificación de permisos a nivel módulo vía canRead y canWrite. La autorización se aplica en cada handler en lugar de a través de una decorator global, lo que permite que cada endpoint declare su propio set de roles permitidos sin acoplar el resto del módulo. Cuatro layers de autenticación cubren los contextos posibles —staff con JWT Supabase, llamadas worker-a-worker con header de plataforma, webhooks de GitHub con HMAC, y rutas explícitamente públicas— y los cinco roles RBAC distribuyen los permisos sobre el resto.

LayerCómo funcionaMounting
publicSin credencialesrutas explícitas antes de authMiddleware
supabaseJWT Supabase + vault_users.is_active=trueapp.use("/api/*", authMiddleware)
platform-keyHeader X-Platform-Keymount antes de authMiddleware
webhook-sigHMAC verification (/api/github/webhook)mount antes de authMiddleware
RolBypassMódulos default
admin — bypass todos los checksTodo
technicalNoproducto, infra, audit, wiki, equipo
commercialNopipeline, contratos, directorio, catálogo, pricing
financeNofinanzas, facturación electrónica, MRR, obligaciones
viewerNolectura limitada

Tabla vault_permissions(role, module, can_read, can_write) — admin configura granular.

MétodoPathNotas
GET/api/healthLiveness probe
GET/api/configBootstrap: Supabase URL + anon key
GET/auth/me(con JWT — retorna user + permissions)
GET/auth/callbackOAuth Google redirect
POST/api/github/webhookHMAC verified — sync issues
POST/api/internal/tenantsX-Platform-Key — endpoint interno reservado
MóduloPathRol mínimo
Pipeline / Leads/api/leads/* · /api/pipeline/*commercial, admin
Assessments/api/assessments/*commercial, admin
Lead-EMI conversations/api/lead-emi-conversations/*commercial, admin
MóduloPathRol mínimo
Tenants (clientes)/api/tenants/*commercial, finance, admin
ProvisioningPOST /api/tenants/:id/provisionadmin
Clientes (DEPRECATED)/api/clients/*redirige a tenants
Organizations/api/organizations/*commercial, admin
Directorio (people)/api/directory/*commercial, admin
Equipo Vault/api/vault-team/*admin
MóduloPathRol mínimo
Contratos/api/contracts/*commercial, finance, admin
Catálogo/api/catalog/*commercial, admin
Catálogo costos/api/catalog/costs/*finance, admin
Catálogo pricing/api/catalog/pricing/*finance, admin
Productos catalog/api/products-catalog/*commercial, admin
Pricing tool/api/pricing-tool/*commercial, finance, admin
MóduloPathRol mínimo
Finance entries/api/finance/*finance, admin
Invoices (interna)/api/invoices/*finance, admin
Fiscal config (facturación electrónica)/api/fiscal/*finance, admin
MRR/api/mrr/*finance, admin
Exchange rates/api/exchange/*finance, admin
Obligaciones/api/obligations/*finance, admin
MóduloPathRol mínimo
Productos (catálogo)/api/products/*technical, admin
Cross-productGET /api/products/cross/issues
GET /api/products/cross/recent
technical, admin
Producto sub-pages/api/products/:slug/*technical, admin
GitHub sync/api/products/:slug/github-synctechnical, admin
Releases/api/products/:slug/releases/*technical, admin
Roadmap/api/products/:slug/layers/*technical, admin
Tech stack/api/products/:slug/tech-stack/*technical, admin
Quality/api/quality/*technical, admin
MóduloPathRol mínimo
Editorial posts/api/editorial/*commercial, admin
Wiki/api/wiki/*technical, admin
Documentos/api/documents/*technical, admin
Brand/api/brand/*commercial, admin
MóduloPathRol mínimo
Checklist/api/checklist/*admin, technical
Time tracking/api/time/*technical, admin
Notifications/api/notifications/*(todos)
Infra/api/infra/*technical, admin
Dashboard/api/dashboard/*(todos — read-only)
KPIs/api/kpis/*(todos — read-only)
Análisis/api/analysis/*admin, technical
Changelog/api/changelog/*technical, admin
MóduloPathRol mínimo
Audit log/api/audit/*admin
Vault permissions/api/vault-permissions/*admin
Vault roles/api/vault-roles/*admin
MóduloPathRol mínimo
EMI proxy chatPOST /api/emi/chat(todos) — auditado
EMI access checkGET /api/emi/access(todos)
EMI access admin/api/emi-access/*admin
EMI analytics/api/emi-analytics/*admin
MóduloPathRol mínimo
AI proposalPOST /api/ai/proposalcommercial, admin
AI contract summaryPOST /api/ai/contractcommercial, finance, admin
AI summaryPOST /api/ai/summary(todos con write en módulo origen)
MóduloPathRol mínimo
Well metrics overviewGET /api/well/metrics/overview(todos read)
Well metrics retentionGET /api/well/metrics/retention(todos read)
Well metrics streaksGET /api/well/metrics/streaks(todos read)
Well metrics pillarsGET /api/well/metrics/pillars(todos read)
Well metrics dailyGET /api/well/metrics/daily(todos read)

Helper en src/client/lib/api.ts que retorna JSON parseado directamente:

const tenants = await apiFetch<Tenant[]>('/api/tenants');
// tenants es Tenant[] directamente, no Response

Helper en src/client/lib/auth.ts:

import { canRead, canWrite } from '../lib/auth';
if (canRead('finance')) {
// mostrar módulo
}

Filtra navItems del sidebar dinámicamente.

  1. Mount order matters: rutas públicas ANTES de authMiddleware en index.ts. Cross-product /cross/* ANTES de /:slug/*.
  2. Permisos en handler: usar canRead(c, 'module') / canWrite(c, 'module') desde el contexto.
  3. Audit log para mutations críticas — el audit_trigger() SQL cubre 12 tablas, pero para acciones cross-product (provisioning) loggear manual en /api/audit/*.
  4. CSP whitelist — si llamás a un dominio externo nuevo, actualizar connect-src en security-headers.ts.
  5. Rate limiting — Vault es internal, no implementa rate-limit per-user (asume staff trusted). Aplicar solo a endpoints públicos (/api/github/webhook).
Ventana de terminal
# Listar todos los routes mounted
grep -n "app.route" src/index.ts
# Verificar canRead/canWrite usage
grep -rn "canRead\|canWrite" src/api/
# Ver módulos en vault_permissions
SELECT DISTINCT module FROM emavault.vault_permissions ORDER BY module;