Referenta

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 the operator admin app (hosting, sign-in, permissions), see Admin App.

The dashboard, marketing site and docs apps sit alongside five Docker services and the local Supabase stack inside the pnpm dev boundary; the admin and CMS apps sit outside it and are started separately.
Everything inside the dashed boundary comes up with the root pnpm dev command. The admin and CMS apps are started on their own; the production-only Bundestag proxy has no local dev mode at all.

Applications

AppPathPortTechPurpose
Dashboardapps/dashboard3000Next.js 16Main product UI — Assistant, Research, Knowledgebase, Contactbase, Press Monitor, Projects, Support.
Marketing siteapps/www3001Next.js 16Public marketing site at the apex domain.
Docsapps/docs3002Next.js 16 + FumadocsThis documentation site (public docs + this internal section + OpenAPI reference).
Adminapps/admin3069Next.js 16Local-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.
CMSapps/cms1337Strapi 5Headless 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 (Dokploy). Deployment settings live per service in dokploy.json; the runbook is docs/dokploy-deployment.md.

Local (booted by pnpm dev)

ServicePathHost portContainer portPurpose
xbergservices/xberg80008000OCR + text extraction (replaced Kreuzberg). Bearer-token gated behind a Caddy sidecar.
Presidioservices/presidio80808080PII masking via Microsoft Presidio. FastAPI wrapper, in-app token auth.
Gotenbergservices/gotenberg80903000PDF / document generation for the Assistant's generateDocument tool.
Press Monitorservices/press30098080Standalone Press Monitor backend (feed, article analysis, briefings, metrics, external proxy). Same Dockerfile Dokploy builds in prod.
Redisservices/redis63796379Hot buffer for resumable Assistant streams. Persistence disabled — stream buffers are ephemeral, the authoritative pointer lives on the chat row.

Host ports are configurable through XBERG_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.mjs (see pnpm dev orchestration below).

Production-only (not booted by pnpm dev)

ServicePathTechNotes
Bundestag proxyservices/external/bundestagRust / AxumStandalone Bundestag automation endpoints (xAI Grok). Replaces the legacy api/src/bundestag/* flow. Deployed on Dokploy.

Local Supabase

The repo root supabase/ directory is the only supported Supabase CLI project. When pnpm db:start (or the supabase/dev.mjs wrapper) brings up the local stack, the Docker bundle exposes these ports — declared in supabase/config.toml:

ComponentPortNotes
REST API / Auth / Storage / Realtime24321What NEXT_PUBLIC_SUPABASE_URL points to locally.
Postgres24322Direct Postgres connection.
Postgres shadow DB24320Used by supabase db diff to compute schema deltas.
Postgres pooler24329Disabled by default.
Supabase Studio24323Web UI at http://127.0.0.1:24323.
Local SMTP / Mailpit24324Captures auth and notification emails. Declared as [local_smtp]; the container is still named supabase_inbucket_*.
Analytics (Logflare)24327Disabled in config.toml. It only backs the Studio Logs tab, and its vector log shipper crash-loops unless Docker Desktop exposes an unauthenticated TCP daemon. Use docker logs <container> instead.
Edge runtime inspector8083Chrome devtools attach point for edge functions.

These are deliberately not the Supabase defaults (54320–54329). Anything above 49152 sits in the OS ephemeral port range, and on Windows the Hyper-V NAT service — installed alongside Docker Desktop and WSL2 — reserves random 100-port blocks out of that range on every boot. When a block lands on 543xx, pnpm db:start fails with bind: An attempt was made to access a socket in a way forbidden by its access permissions, and it clears itself on the next reboot, so it reads as flaky rather than as a port conflict. The 243xx block is below the ephemeral range on Windows, macOS and Linux alike, so no OS ever claims it. See the comment at the top of supabase/config.toml.

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/xberg \
  --filter=@referenta/gotenberg \
  --filter=@referenta/press \
  --filter=@referenta/redis \
  --filter=@referenta/supabase

In plain English, that starts:

  • Three Next.js dev servers — dashboard (3000), www (3001), docs (3002).
  • Five Docker services — xberg, presidio, gotenberg, press, redis (each via docker compose -f docker-compose.yml up <service>).
  • The local Supabase stack — @referenta/supabase is the repo-root supabase/ directory, and its dev script runs supabase/dev.mjs. That script starts supabase start if it isn't already running, then writes apps/dashboard/.env.development.local with the local Supabase API URL + anon / publishable / service-role keys, plus UPSTASH_REDIS_REDIS_URL, XBERG_BASE_URL, PRESIDIO_BASE_URL, GOTENBERG_BASE_URL, and PRESS_API_UPSTREAM_URL. The dashboard auto-points at the local stack on next restart — no manual env wiring needed.

Because supabase/dev.mjs 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 with pnpm --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 with pnpm --filter cms dev. Strapi is only needed when working on CMS-managed marketing content.
  • services/external/bundestag — Rust service that runs on Dokploy in production. Use cargo run inside the service directory when developing against it locally.

On this page