Architecture Overview
Kairosis is a fan-in event pipeline. It has three moving parts: the API, the poller worker, and the dashboard. All three share the same PostgreSQL database and publish to the same RabbitMQ exchange.
High-level diagram
Section titled “High-level diagram”External sources ├── GitHub (webhook) ─┐ ├── Slack (webhook) │ ├── Email (poller) ├─▶ API (NestJS :3200) ├── Calendar (poller) │ │ └── Device/mobile ───────┘ │ publish ▼ RabbitMQ topic exchange kairosis.topic │ ┌──────┴──────┐ ▼ ▼ Consumer A Consumer B (your app) (your app)Components
Section titled “Components”API (apps/api)
Section titled “API (apps/api)”The central NestJS application. Responsibilities:
- Receive and verify webhook payloads (
POST /webhooks/:connectorId/:webhookToken) - Expose connector configuration endpoints
- Serve the live SSE event stream (
GET /events/stream) - Handle first-run setup
Poller Worker (apps/poller-worker)
Section titled “Poller Worker (apps/poller-worker)”A NestJS standalone application that runs scheduled polling jobs. For each enabled poller connector, it calls connector.poll() on the configured cron schedule and publishes the resulting events. The poller is currently a stub — not yet wired.
Dashboard (apps/dashboard)
Section titled “Dashboard (apps/dashboard)”A Next.js 15 App Router application. Provides:
- Setup wizard (first run)
- Connector management (enable, configure, view webhook URLs)
- Live event stream viewer
Connectors (connectors/)
Section titled “Connectors (connectors/)”Internal connector implementations. Each connector lives in connectors/<name>/ and is registered in apps/api/src/connectors/connectors.module.ts. Connectors are never published to npm — use packages/connector-sdk for that.
Event packages (events/)
Section titled “Event packages (events/)”Published as @kairosis/* scoped npm packages. Define the shared event type constants and Zod payload schemas consumed by both Kairosis and downstream applications.
Database schema
Section titled “Database schema”workspaces -- workspace registry (multi-tenant ready)connector_configs -- per-workspace connector state + encrypted secretssystem_config -- first-run flag, global settingsConnector secrets are stored as AES-256-GCM encrypted BYTEA. Config (non-sensitive) is stored as plain JSONB.
Security model
Section titled “Security model”- Webhook URLs use opaque tokens —
workspaceIdis never in the URL - Secrets are encrypted at rest (AES-256-GCM)
- Webhook payloads are HMAC-verified before normalization
- Secrets are never returned via API — only
hasSecrets: booleanis exposed
Next steps
Section titled “Next steps”- Event Flow — trace a single event through the system
- Normalized Events — the
NormalizedEventschema