Skip to main content

API Contracts

:::info Source Sourced from services/analytics-service/API_CONTRACTS.md in the documentation repo. :::

0. Phase 1 — implemented (Ghasi-edTech monorepo)

This section is the normative contract for the current monorepo implementation. Sections §1–§8 below remain the target product surface; unlisted routes are Phase 2+ unless added here.

Implemented HTTP paths (see also openapi.json in the service package):

  • GET /api/v1/health
  • POST /api/v1/analytics/exports — raw (raw_events / ai_audit), quota + residency
  • GET /api/v1/analytics/exports/{id} / GET /api/v1/analytics/exports/{id}/download
  • GET /api/v1/analytics/compliance/summary (and related compliance summary route per OpenAPI)
  • POST /api/v1/analytics/dashboards/:dashboardId/widgets/:widgetId/render — compliance + provider widgets
  • POST /api/v1/analytics/reports, POST /api/v1/analytics/reports/:reportId/run — scheduled/on-demand reports (analytics.report.generated.v1 / analytics.report.failed.v1)
  • POST /api/v1/analytics/insights/at-risk — EP-15 US-75 (stub scoring + analytics.insight.generated.v1)
  • POST /api/v1/analytics/insights/board-summary — EP-15 US-76 (stub narrative + analytics.insight.generated.v1)

Raw export source (Phase 1): tenant-scoped rows from the service outbox table for the requested time window (keyset-paginated). Full warehouse / lake export is Phase 2.

Security (Phase 1): JWT and analytics:* scopes are enforced at the API gateway; the service trusts X-Tenant-Id / X-User-Id (UUID) on mutating and tenant-scoped reads and applies RLS in Postgres. Direct exposure of this service without a gateway is not supported in Phase 1.

Architecture decision: planning/adr/ADR-0012-ep12-analytics-phase1-boundary.md (monorepo).


1. Endpoints

1.1 Dashboards

GET /api/v1/analytics/dashboards
POST /api/v1/analytics/dashboards
GET /api/v1/analytics/dashboards/{id}
PATCH /api/v1/analytics/dashboards/{id}
DELETE /api/v1/analytics/dashboards/{id}
POST /api/v1/analytics/dashboards/{id}/render body: { filters, timeRange }

1.2 Metrics

GET /api/v1/analytics/metrics
GET /api/v1/analytics/metrics/{id}
POST /api/v1/analytics/metrics
GET /api/v1/analytics/metrics/{id}/query ?dimensions=...&filters=...&timeRange=...

1.3 Reports

GET /api/v1/analytics/reports
POST /api/v1/analytics/reports
GET /api/v1/analytics/reports/{id}/preview
POST /api/v1/analytics/reports/{id}/schedule
GET /api/v1/analytics/reports/{id}/last-render

1.4 Exports

POST /api/v1/analytics/exports body: { query, format, filters }
GET /api/v1/analytics/exports/{id}
GET /api/v1/analytics/exports/{id}/download (signed URL)

1.5 Cohorts

GET /api/v1/analytics/cohorts
POST /api/v1/analytics/cohorts
POST /api/v1/analytics/cohorts/{id}/evaluate
GET /api/v1/analytics/cohorts/{id}/members

1.6 Ad-hoc Query (admin only)

POST /api/v1/analytics/query body: { sql, params, timeoutSeconds }

1.7 Compliance Export (GDPR)

POST /api/v1/analytics/audit-export body: { userId | scope } (compliance_officer only)

1.8 AI Insights (M5+)

POST /api/v1/analytics/insights/query body: { question, timeRange? }
POST /api/v1/analytics/insights/anomaly body: { metricId }
POST /api/v1/analytics/insights/forecast body: { metricId, horizonDays }

1.9 Merkle audit anchor (US-106 — implemented slice)

GET /api/v1/audit/merkle/anchors/latest
GET /api/v1/audit/merkle/anchors/{date} date = YYYY-MM-DD (UTC)
GET /api/v1/audit/merkle/anchors/{date}/verify ?candidateRoot=<hex>

Daily materialization cron: set MERKLE_ANCHOR_ENABLED=true. Optional operator backfill: GET .../materialize when MERKLE_OPERATOR_API=true.

2. Request/Response

Standard envelope; query results in data with meta.query.timing, meta.query.rowCount.

3. Error Model

  • validation.query.syntax — SQL/DSL invalid.
  • validation.query.scope_out_of_bounds — query touches other tenants (disallowed).
  • query.timeout — query exceeded timeout.
  • export.quota_exceeded — tenant export quota exhausted.
  • ai.refused.* for AI insights.

4. Pagination

Cursor; max 10k rows per page for ad-hoc.

5. Rate Limits

  • Ad-hoc query: 10/min per admin.
  • Export: 5 concurrent per tenant.
  • Dashboard render: 100/min per user.

6. Security

  • JWT + tenant scope.
  • analytics:read, analytics:admin, analytics:ai, analytics:audit_export scopes.
  • Compliance-officer audit-exports logged.
  • Ad-hoc SQL parsed; tenant filter injected automatically.

7. SLOs

  • Dashboard render p95 < 2s (with cache).
  • Metric query p95 < 1s.
  • Export start-to-download p95 < 5 min (for 10M rows).
  • Ingestion lag p99 < 30s.