High-level components
Component descriptions
Frontend — Next.js (app.causeloop.ai)
The product UI is a Next.js application authenticated by Clerk. After exchanging the Clerk session for a platform JWT, the frontend communicates exclusively with the backend API and a WebSocket for realtime updates. Key routes:| Route group | Purpose |
|---|---|
/(auth)/login | Sign-in page (Clerk-powered) |
/(onboarding)/onboarding | Post-signup onboarding wizard |
/(platform)/dashboard | Main workspace dashboard |
/(platform)/issues | Issue list and detail |
/(platform)/patterns | Pattern list and detail |
/(platform)/predictions | Risk signals and forecast |
/(platform)/recommendations | Ranked fix queue |
/(platform)/integrations | Connector management |
/(platform)/reports | Generated reports |
/(platform)/settings | Workspace and member settings |
Backend API — FastAPI (api.causeloop.ai)
The backend is a FastAPI application serving all product functionality under/v1. It is stateless and horizontally scalable. Key responsibilities:
- Auth token issuance and verification
- Business logic for issues, patterns, predictions, recommendations, clusters, and connectors
- AI orchestration (dispatching analysis jobs to the LLM Router)
- Tenant isolation via database RLS
- Async job coordination via Kafka stubs (Celery-based workers in production)
- Rate limiting (1,000 requests per minute per tenant by default)
| Layer | Technology |
|---|---|
| Runtime | Python 3.11+ |
| Framework | FastAPI 0.115+ |
| Validation | Pydantic v2 |
| Auth | PyJWT (HS256 platform tokens), python-jose (RS256 Clerk verification) |
| Middleware | Rate limiting, Idempotency-Key support |
| Deployment | Docker, Railway, Render |
LLM Router — AI providers
The LLM Router dispatches AI analysis tasks (root-cause analysis, pattern detection confidence scoring, recommendation generation) to the configured provider. Providers are tried in order:- Anthropic — Claude models (
ANTHROPIC_API_KEY) - OpenAI — GPT-4o / GPT-4o-mini (
OPENAI_API_KEY) - Mock — Deterministic offline fallback (no keys required)
If both
ANTHROPIC_API_KEY and OPENAI_API_KEY are absent, the API falls back to the mock provider automatically. Analysis results are plausible but not real.Database — PostgreSQL with Row-Level Security
All product data lives in PostgreSQL 16. Multi-tenancy is enforced at the database layer using Row-Level Security (RLS):- Every tenant table has a
workspace_idcolumn. - Before executing any query, the API binds
app.current_workspace_idon the session. - RLS policies reject reads and writes that do not match the bound workspace ID.
- The application role (
causeloop_app) does not haveBYPASSRLS; a superuser role is kept separate for migrations only.
Connectors and Ingestion
Connectors pull issues into a workspace from external tools. They operate in two modes:- Poll — the backend fetches issues from the external API on a configurable schedule (
poll_interval_seconds). - Webhook (inbound push) — the external tool POSTs events to
POST /ingest/{connector_token}, verified by HMAC signature.
GET /connectors/{id}/sync-runs.
WebSocket Gateway — Realtime channel
The backend exposes a WebSocket endpoint at/v1/stream. Authenticated clients connect with their platform JWT as a query parameter (?token=<jwt>). The gateway pushes typed event envelopes to all sockets belonging to the same tenant:
activity.created, issue.updated, pattern.updated, prediction.alert, recommendation.created, and job.updated (for async job progress).
Request and auth flow
User signs in via Clerk
The Next.js frontend delegates authentication to Clerk. On success, Clerk issues a signed RS256 session JWT to the browser.
Exchange for a platform token
The frontend calls
POST /v1/auth/exchange with the Clerk session JWT. The backend verifies the JWT against Clerk’s JWKS endpoint (RS256), looks up or creates the user record, and issues a short-lived HS256 Bearer token bound to the user’s workspace.API calls with Bearer token
All subsequent requests include the Bearer token in the
Authorization header. Middleware resolves the token to {user_id, workspace_id, role, scopes} and binds the RLS session variable before any query runs.Deployment topology
In production, each logical layer runs as an independent set of replicas behind a load balancer:| Component | Replicas | Notes |
|---|---|---|
| Backend API | 2–8 (autoscale) | Stateless; any replica handles any request |
| WS Gateway | 2–4 | Per-tenant fan-out; replicas share a Redis pub/sub bus |
| Kafka consumers (workers) | 1–4 per topic group | Pattern detection, AI jobs, notification delivery |
| PostgreSQL | Primary + read replica | RLS enforced on all connections |
docker-compose.yml runs the API, PostgreSQL, and Caddy (reverse proxy) as a single-box stack.
Quickstart
Sign in and see your first insights in 10 minutes.
Deploy & Security
Self-hosting, environment variables, and security controls.