Skip to Content

Configuration Reference

Backend Environment Variables

Set these in docker-compose.yml under the backend service, or in a .env file.

VariableDefaultDescription
PORT3001Backend API port
DATABASE_URLPostgreSQL connection string (e.g., postgresql://tandemu:tandemu@postgres:5432/tandemu)
REDIS_URLRedis connection string (e.g., redis://redis:6379)
CLICKHOUSE_URLClickHouse HTTP URL (e.g., http://clickhouse:8123)
JWT_SECRETchange-me-in-productionSecret for signing JWT tokens. Change this in production.
CORS_ORIGINhttp://localhost:3000Allowed CORS origin for the frontend
STRIPE_SECRET_KEYStripe secret key (SaaS billing, optional)
STRIPE_WEBHOOK_SECRETStripe webhook signing secret (optional)
OPENAI_API_KEYOpenAI API key for memory embeddings. Required for memory search to work.
APP_URLhttp://localhost:3001Backend URL used for redirects and callbacks
FRONTEND_URLhttp://localhost:3000Frontend URL used for email links and redirects
ENCRYPTION_KEYAES-256 key for encrypting integration API tokens at rest
WATCHTOWER_API_URLhttp://watchtower:8080Watchtower HTTP API URL for triggering updates from the dashboard
WATCHTOWER_API_TOKENtandemu-updateBearer token for Watchtower HTTP API. Change this in production.

Frontend Environment Variables

VariableDefaultDescription
NEXT_PUBLIC_API_URLhttp://localhost:3001Backend API URL (accessed from the browser)

OTel Collector Configuration

The collector config is at otel-collector.yaml in the repo root. It defines:

Receivers:

  • OTLP gRPC on port 4317
  • OTLP HTTP on port 4318

Processors:

  • memory_limiter — Prevents OOM (512 MiB limit)
  • batch — Batches 10,000 records or 5s, whichever comes first

Exporters:

  • clickhouse — Writes to ClickHouse with auto-schema creation
  • debug — Logs basic info (useful for troubleshooting)

To modify the pipeline, edit otel-collector.yaml and restart the collector:

docker compose restart otel-collector

Database

PostgreSQL Schema

Tables are created by migration scripts in packages/database/src/migrations/:

MigrationCreates
0001_initial.sqlorganizations, users, memberships tables + RLS policies
0002_teams_and_invites.sqlteams, team_members, invites tables + RLS
0003_integrations.sqlintegrations, integration_project_mappings tables + RLS
00040010Additional tables and schema updates (applied automatically on startup)

Migrations are applied automatically when the backend starts. The manual psql commands below are a fallback if auto-migration fails.

All tables use Row-Level Security (RLS) for tenant isolation. Every query is scoped to the current organization via SET LOCAL app.current_tenant.

ClickHouse Tables

Created automatically by the OTel Collector on first startup:

TableData
otel_tracesTask session spans
otel_metrics_sumCode line counters (AI vs manual)
otel_logsFriction events (prompt loops, errors)
memory_access_logMemory usage tracking (has 90-day TTL)

The memory_access_log table has a 90-day TTL. Core telemetry tables do not have a TTL configured — data is retained indefinitely unless you add one.

Applying Migrations

Migrations are idempotent (safe to run multiple times):

for f in packages/database/src/migrations/*.sql; do docker exec -i tandemu-postgres-1 psql -U tandemu -d tandemu < "$f" done

Security Notes

  • Change JWT_SECRET in production — the default is not secure
  • API tokens for integrations are encrypted at rest using AES-256-GCM (set ENCRYPTION_KEY in production)
  • RLS ensures organization data isolation at the database level
  • CORS is restricted to the configured origin
  • Stripe webhooks use cryptographic signature verification
Last updated on