Referenta is split across several Next.js apps, supporting services (mostly Docker, a couple of standalone Rust binaries), and shared workspace packages. This page is the map: what each piece is, which port it runs on, and how the root pnpm dev command stitches the developer-facing surface together.
For the dev loop and environment model, see Developer Setup. For local-only admin tooling specifics, see Admin App.
Applications
| App | Path | Port | Tech | Purpose |
|---|---|---|---|---|
| Dashboard | apps/dashboard | 3000 | Next.js 16 | Main product UI — Assistant, Research, Knowledgebase, Contactbase, Press Monitor, Projects, Support. |
| Marketing site | apps/www | 3001 | Next.js 16 | Public marketing site at the apex domain. |
| Docs | apps/docs | 3002 | Next.js 16 + Fumadocs | This documentation site (public docs + this internal section + OpenAPI reference). |
| Admin | apps/admin | 3069 | Next.js 16 | Local-only admin tooling. Talks directly to hosted dev / prod Supabase to manage things like the Assistant model whitelist with a two-tier promotion flow. Never deployed. See Admin App. |
| CMS | apps/cms | 1337 | Strapi 5 | Headless CMS used to manage marketing-site content. |
Services
Long-running services live under services/. They split into two groups by lifecycle: services the root pnpm dev command boots locally for the dashboard, and services that only run in production (Railway).
Local (booted by pnpm dev)
| Service | Path | Host port | Container port | Purpose |
|---|---|---|---|---|
| Kreuzberg | services/kreuzberg | 8000 | 8000 | OCR + text extraction. Bearer-token gated behind a Caddy sidecar. |
| Presidio | services/presidio | 8080 | 8080 | PII masking via Microsoft Presidio. FastAPI wrapper, in-app token auth. |
| Gotenberg | services/gotenberg | 8090 | 3000 | PDF / document generation for the Assistant's generateDocument tool. |
| Press Monitor | services/press | 3009 | 8080 | Standalone Press Monitor backend (feed, article analysis, briefings, metrics, external proxy). Same Dockerfile Railway builds in prod. |
| Redis | services/redis | 6379 | 6379 | Hot buffer for resumable Assistant streams. Persistence disabled — stream buffers are ephemeral, the authoritative pointer lives on the chat row. |
Host ports are configurable through KREUZBERG_PORT, PRESIDIO_PORT, GOTENBERG_PORT, PRESS_PORT, REDIS_PORT env vars (see docker-compose.yml). The dashboard reads *_BASE_URL / PRESS_API_UPSTREAM_URL env vars to find them; those URLs are auto-written into apps/dashboard/.env.development.local by supabase/dev.sh (see pnpm dev orchestration below).
Production-only (not booted by pnpm dev)
| Service | Path | Tech | Notes |
|---|---|---|---|
| Uptime Kuma | services/uptime-kuma | Upstream Docker image, Railway-wrapped | Self-hosted status / uptime dashboard. Thin Railway wrapper around louislam/uptime-kuma. |
| Bundestag proxy | services/external/bundestag | Rust / Axum | Standalone Bundestag automation endpoints (xAI Grok). Replaces the legacy api/src/bundestag/* flow. Deployed on Railway. |
Local Supabase
The repo root supabase/ directory is the only supported Supabase CLI project. When pnpm db:start (or the supabase/dev.sh wrapper) brings up the local stack, the Docker bundle exposes these ports — declared in supabase/config.toml:
| Component | Port | Notes |
|---|---|---|
| REST API / Auth / Storage / Realtime | 54321 | What NEXT_PUBLIC_SUPABASE_URL points to locally. |
| Postgres | 54322 | Direct Postgres connection. |
| Postgres shadow DB | 54320 | Used by supabase db diff to compute schema deltas. |
| Postgres pooler | 54329 | Disabled by default. |
| Supabase Studio | 54323 | Web UI at http://127.0.0.1:54323. |
| Inbucket (email testing) | 54324 | Captures auth and notification emails. |
| Analytics | 54327 | Postgres-backed analytics. |
| Edge runtime inspector | 8083 | Chrome devtools attach point for edge functions. |
Packages
Shared workspace packages live under packages/:
packages/ui— shared React component library (shadcn/ui based) consumed by the apps.packages/editor— Tiptap v3 rich-text editor used by Research and the Assistant document tools. Carries the collaboration extensions for Yjs-backed editing.packages/quill-markdown— small, dependency-free Quill Delta ↔ Markdown converter. Retained to read documents written before the Tiptap migration.packages/migration— scripts for converting raw data during data migrations.packages/typescript-config— shared TypeScript configurations (base.json,nextjs.json, etc.).
Linting is Biome, configured once at the repo root (biome.json) — there is no shared ESLint package.
What pnpm dev orchestrates
The root pnpm dev runs turbo run dev filtered to the long-running tasks needed for end-to-end dashboard development:
turbo run dev \
--filter=www \
--filter=dashboard \
--filter=docs \
--filter=@referenta/presidio \
--filter=@referenta/kreuzberg \
--filter=@referenta/gotenberg \
--filter=@referenta/press \
--filter=@referenta/redis \
--filter=@referenta/supabaseIn plain English, that starts:
- Three Next.js dev servers — dashboard (3000), www (3001), docs (3002).
- Five Docker services — kreuzberg, presidio, gotenberg, press, redis (each via
docker compose -f docker-compose.yml up <service>). - The local Supabase stack —
@referenta/supabaseis the repo-rootsupabase/directory, and itsdevscript runssupabase/dev.sh. That script startssupabase startif it isn't already running, then writesapps/dashboard/.env.development.localwith the local Supabase API URL + anon / publishable / service-role keys, plusREDIS_PUBLIC_URL,KREUZBERG_BASE_URL,PRESIDIO_BASE_URL,GOTENBERG_BASE_URL, andPRESS_API_UPSTREAM_URL. The dashboard auto-points at the local stack on next restart — no manual env wiring needed.
Because supabase/dev.sh writes to apps/dashboard/.env.development.local on startup, after the first pnpm dev you may need to restart the dashboard process once to pick up freshly-written env values. Subsequent runs reuse the file as long as ports stay stable.
What is not in pnpm dev
These boot separately on purpose:
apps/admin— start withpnpm --filter admin dev. It targets hosted dev / prod Supabase directly (not local) and shouldn't run alongside the orchestrated local stack by default. See Admin App.apps/cms— start withpnpm --filter cms dev. Strapi is only needed when working on CMS-managed marketing content.services/external/bundestag— Rust service that runs on Railway in production. Usecargo runinside the service directory when developing against it locally.services/uptime-kuma— Railway-only; no local dev mode.