Referenta

This section is for contributors working inside the Referenta monorepo. The root README.md is the short version — clone, install, run. This section is the long version: it explains how product changes move from isolated local development to reviewed production delivery, and why the workflow is shaped the way it is.

Repository Layout

Referenta is a Turborepo-managed monorepo. The high-level shape is:

admin
cms
dashboard
docs
www
ui
editor
quill-markdown
migration
typescript-config
kreuzberg
presidio
redis
gotenberg
press
uptime-kuma
external/bundestag
schemas
migrations
config.toml

See Architecture for what each app and service does, what port it runs on, and which ones the root pnpm dev orchestrates together. The repo root supabase/ directory is the only supported Supabase CLI project.

Environment Model

Referenta uses a structured Supabase workflow with clear separation between local work, shared validation, and the live product. There are four environments in play:

  • Local — Supabase CLI + Docker on your machine.
  • Shared hosted dev — the existing hosted Supabase project (rieddfnddpsbdlmmalwk) for manual development and shared testing. Not auto-promoted.
  • Staging — auto-deployed from the dev branch.
  • Production — auto-deployed from the main branch.

dev is the only branch that deploys to staging. main is the only branch that deploys to production.

Local

Local development runs through the Supabase CLI and Docker. Each developer can start a full Supabase stack on their own machine, including the database, authentication, storage, and APIs.

Product impact:

  • developers can experiment safely without changing shared data,
  • schema changes can be validated before the team sees them, and
  • iteration is faster because local reset, seeding, and testing are under the developer's control.

Technical impact:

  • the repo root supabase/ directory is the supported Supabase CLI project,
  • local schema work is generated into migrations,
  • the dashboard can be pointed at http://127.0.0.1:54321, and
  • local-only test users are created during reset for role-based testing.

Shared Validation

After local work is ready, migrations move into shared hosted environments for integration and team validation.

In practice, the repo distinguishes between:

  • shared hosted development for linked remote work and manual testing,
  • staging as the remote validation layer for approved dev branch changes, and
  • production as the live environment used by customers.

This separation keeps collaboration predictable: local work stays isolated, while staging becomes the place where the team validates the same migration history together.

Production

Production only receives stable changes that have already been reviewed and validated. Direct edits in the dashboard or ad hoc schema changes are avoided in favor of committed migrations.

That gives Referenta:

  • a traceable database history,
  • repeatable environment setup,
  • lower production risk, and
  • clearer operational ownership over what changed and why.

Deploy Automation

Three systems collaborate to ship changes; each owns one slice and they don't overlap:

  • GitHub Actions (.github/workflows/ci.yml) validates pull requests and pushes to main. It runs builds, type checks, Biome quality, vitest, the Playwright e2e suite (runs only on the Release Candidate PR and blocks there — day-to-day PRs skip it), Presidio service tests, and migration hygiene checks (filename pattern, duplicate timestamps, stray files). It also creates the release tag + GitHub Release when a Release Candidate: / Release: PR merges into main. CI does not deploy anything; there are no longer deploy-dashboard.yml or preview-dashboard.yml workflows. See Continuous Integration for the full job-by-job breakdown and Release Automation for the release flow.
  • Vercel deploys apps/dashboard and apps/www directly through its GitHub integration. Every open PR gets a preview deploy, dev deploys to staging, main deploys to production. No GitHub Actions workflow is involved in dashboard or marketing deploys.
  • Supabase Branching deploys database migrations end to end. Every PR against dev automatically gets a preview Supabase branch, dev is connected to the Supabase staging branch, and main is connected to production. Migrations don't go through GitHub Actions — Supabase manages the branching and apply flow on its side.

At a glance, the chain is:

  • Preview — opening a PR against dev produces a Vercel preview deploy and a Supabase preview branch. The Supabase preview validates that your local schema is in sync with the migration history; if your local DB has drifted, the preview fails to provision and the check on the PR goes red. Resolve it before requesting review (see Database Workflow for what drift looks like).
  • dev — merging a PR rolls Vercel staging forward and applies the migration on the Supabase staging branch.
  • main — merging an RC PR rolls Vercel production forward and applies the migration on the Supabase production branch.

Direct pushes to dev should be avoided when the change contains schema files — dev is connected to staging, and bypassing the PR loop bypasses the preview-branch validation that catches drift before staging gets a bad migration. See Git Workflow for the full direct-push rule.

Migration-First Workflow

The expected progression is:

  1. Build and test locally with the Docker-managed Supabase stack.
  2. Generate or sync migrations from the local schema changes.
  3. Commit those migrations into the repo.
  4. Apply and validate them in shared remote environments.
  5. Promote reviewed changes through staging and then production.

This is both a product workflow and an engineering guardrail. Product-wise, it prevents unreviewed infrastructure drift. Technically, it makes the repo history the source of truth for database evolution. See Database Workflow for the schema file layout and standard migration commands.

Contributor Setup

Prerequisites

Make sure you have the following installed:

  • Node.js 24.x
  • pnpm 11.9.0 — pinned by packageManager in the root package.json; corepack enable gets you the right version
  • Vercel CLI, for pnpm env:pull
  • Docker, for the local Supabase stack and the supporting services

The Supabase CLI and Turborepo are workspace devDependencies, so pnpm install provides both. Don't install them globally — a global version that drifts from the pinned one is a source of confusing schema and build differences.

Clone And Install

git clone https://github.com/Referenta/referenta
cd referenta
git checkout dev
pnpm install

The dev branch is the default starting point because staging deploys from it and most active work lands there first.

Environment Variables From Vercel

To run the applications locally you'll need the hosted environment variables from Vercel.

  1. Link the local repository to the Vercel project:
vercel link --repo

This command will guide you through connecting the monorepo to the corresponding project on Vercel.

  1. Pull the development environment variables:
pnpm env:pull

This downloads the development environment variables from Vercel and creates .env files in the respective application directories.

Local Supabase Setup

Use the root supabase/ directory as the only supported Supabase CLI project for this repo. Bringing up a local stack is two commands:

pnpm db:start
pnpm db:reset

pnpm db:reset applies the committed migration history, runs the seed files, and creates the local-only test accounts. Password for all of them: Referenta!2024#

EmailRoleUse it for
role0-user1@local.referenta.testMemberNon-privileged paths
role1-user1@local.referenta.testAdminMost work — the default
role2-user1@local.referenta.testSuperadminOrganization management
logout-user1@local.referenta.testAdminNothing — reserved for the e2e logout spec

These accounts exist only in the local Docker-managed Supabase stack. They are not used for shared dev, staging, or production. Leave logout-user1 alone: signOut() defaults to global scope and revokes every refresh token on the account, which invalidates the persisted sessions the Playwright suite runs against.

Onboarding does not involve pulling a schema baseline. The migration history is already committed to supabase/migrations/, so pnpm db:reset is all a fresh clone needs. Running pnpm db:pull against hosted dev manufactures a duplicate baseline and creates exactly the drift the Supabase preview-branch check exists to catch — see Database Workflow.

Linking Hosted Dev (Optional)

Only needed to push migrations to, or generate types from, the shared hosted dev project — not for local development:

pnpm supabase:login
pnpm supabase:link:dev

This links the repo to shared dev project rieddfnddpsbdlmmalwk, and requires a logged-in Supabase CLI session plus the remote database password.

Point The Dashboard To Local Supabase

pnpm dev does this for you. The root script orchestrates @referenta/supabase, which starts the local Supabase stack and writes apps/dashboard/.env.development.local with the local Supabase URL, keys, and supporting service endpoints. Next.js picks the file up on the next start, so a fresh clone needs no manual env wiring to point the dashboard at local Supabase.

The auto-generated file contains:

  • The four Supabase keys (NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY, NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY, SUPABASE_SERVICE_ROLE_KEY), read from supabase status -o env.
  • URLs for the supporting services pnpm dev also starts: REDIS_PUBLIC_URL, KREUZBERG_BASE_URL, PRESIDIO_BASE_URL, GOTENBERG_BASE_URL.

The file is marked # Auto-generated by supabase/dev.sh at the top and gets rewritten every time pnpm dev boots. Don't hand-edit it. Persistent local overrides belong in apps/dashboard/.env.local, which still wins over .env.development.local in Next.js precedence.

Wiring The Dashboard Without pnpm dev

If you'd rather run the dashboard alone (pnpm dev:dashboard) without spinning up the rest of the local services, start Supabase yourself and provide the env manually. Copy apps/dashboard/.env.local.example to apps/dashboard/.env.local, then fill the Supabase values from pnpm db:status:env:

  • API_URL -> NEXT_PUBLIC_SUPABASE_URL
  • ANON_KEY -> NEXT_PUBLIC_SUPABASE_ANON_KEY
  • PUBLISHABLE_KEY -> NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY
  • SERVICE_ROLE_KEY -> SUPABASE_SERVICE_ROLE_KEY

This same approach is how you selectively override individual keys from the auto-written file, for example pointing one service URL at a remote host while the rest of the stack stays local.

Env File Precedence

A normal local checkout has several env files coexisting. Next.js loads them in this order, highest priority first:

  1. .env.local (persistent local overrides, always wins except in test mode).
  2. .env.development.local (what pnpm dev auto-writes, points at local Supabase plus local services).
  3. .env.development
  4. .env (what pnpm env:pull writes, holds the hosted dev credentials from Vercel).

In practice:

  • Fresh clone after pnpm dev: .env.development.local exists and beats .env, so the dashboard hits local Supabase automatically.
  • .env.local overrides everything else. Use it sparingly, only for keys you specifically want to change.
  • Restart matters. Next.js reads env at process start. After editing .env.local, deleting .env.development.local, or re-running pnpm env:pull, restart the dev server before expecting changes to take effect.
  • Verify the wiring. The first Supabase request in your browser's network tab should hit 127.0.0.1:54321. If it's hitting the hosted host, the dev server didn't pick up the auto-written file; restart and check that .env.development.local exists.

To switch the dashboard back to remote Supabase: delete apps/dashboard/.env.development.local and don't re-run pnpm dev (which would recreate it). Next.js falls back to .env from Vercel.

.env, .env.development.local, and .env.local are all gitignored, so none of them leak into the repo. But .env still contains hosted dev credentials even when the dashboard is pointed locally. Be careful copying values out of it for one-off shell commands like psql; those will hit shared Supabase, not your local stack.

Run The App

Start the full local stack with:

pnpm dev

This boots local Supabase (and auto-writes apps/dashboard/.env.development.local), the dashboard, www, docs, and the supporting Docker services in parallel. The dashboard is served on http://localhost:3000. See Architecture for the full list of apps, ports, and what each filter starts.

If you only need the dashboard and have already wired up the env manually (see Wiring The Dashboard Without pnpm dev), run:

pnpm dev:dashboard

pnpm dev only stops the Supabase containers it started; if Supabase was already running (for example via pnpm db:start), it stays running after Ctrl+C. pnpm db:stop cleans up leaked containers after a hard exit.

Included Pages

On this page