/api/v1 JSON API, the share viewer, and the retention worker.
Prerequisites
Local setup
1
Install and create databases
2
Configure
.env is loaded
as a fallback in development only. In production a missing variable fails fast with
an actionable message rather than silently resolving to whatever is on disk.3
Build and migrate
4
Run
5
Point the CLI at it
Required configuration
Everything else has a default. The full list, with what each one changes, is in
Environment variables.
Object storage
s3 requires the endpoint, bucket, access key, and secret key together.
Behind a proxy
X-Forwarded-For. Leave it unset when nothing proxies the app.
The reason is worth understanding: the leftmost X-Forwarded-For entry is whatever the
caller typed, so keying a throttle on it lets an attacker mint a fresh bucket per request
and the throttle stops existing. Only entries your own proxies added can be trusted.
Railway and most single-proxy platforms need 1.
If a trusted edge sets a real-client-address header, name it:
Multiple replicas
REDIS_URL, rate limits are process-local counters — fine for a single process,
but N replicas allow N times each limit. EVENT_BUS_DRIVER=postgres uses
LISTEN/NOTIFY and works across instances; memory is single-process only.
Platform administrator
The repository’s
README.md and docs/LOCAL-WALKTHROUGH.md state that the first account
in a fresh deployment becomes the platform administrator. The implementation in
apps/web/lib/auth-service.ts does not do that — only PLATFORM_ADMIN_EMAIL grants the
role. Trust the code.Health and readiness
The split is deliberate. A database outage must not put every replica into a restart loop,
and “the process is up” is not a usable signal on its own — a replica that cannot reach
Postgres serves 500s for every real operation while its marketing pages still return 200.
Both endpoints answer on any hostname, because redirecting a health check would make a
monitor report the redirect target’s health instead.
Container builds
Two Dockerfiles at the repository root, both building and running as non-root:railway.web.json and railway.worker.json carry deploy configuration: the Dockerfile
paths, a pre-deploy migration command, /api/v1/health as the health check, region
europe-west4, and drain and overlap windows so a deploy does not cut live streams.
scripts/railway-provision.sh creates the project, adds PostgreSQL and Redis, generates
REPORT_ENCRYPTION_KEY, and prints the short list of values it deliberately will not
invent. It is idempotent and refuses to change a project it did not create.
Canonical hostnames
apps/web/proxy.ts handles the three hostnames the product is intended to answer on.
None of them is deployed today, so this matters only once you put a deployment behind real
DNS — and if you self-host under your own domain, edit packages/brand/src/index.ts, which
is the single source of these strings.
Non-API paths are redirected to the canonical host with a 308, which preserves the
method and body — a 302 would silently turn a POST into a GET. API paths are deliberately
not redirected off the API host.
Payments (optional)
POST /api/v1/billing/webhook; the raw body is verified byte-for-byte before anything is
parsed, the delivery id is claimed before the plan changes so a retry cannot apply an
upgrade twice, and the plan is resolved from the product id through your own configuration
rather than from the request.
Verification suites
test:e2e use TEST_DATABASE_URL, default
postgresql://localhost:5432/myrqen_test.
Demonstration data
demo:seed
refuses a non-loopback or production database unless MYRQEN_DEMO_ALLOW_REMOTE=1 is set on
that command line, and the refusal says so. Every row it writes carries is_demo and the
run’s demo_seed_id, and demo:purge deletes nothing else. The demonstration accounts
cannot sign in; the workspace is meant to be viewed through the share links the seeder
prints.
Signed releases
UPDATE_MANIFEST_PATH at it; clients fetch it from
GET /api/v1/updates/manifest. Pin the public keys clients must verify against in
UPDATE_PUBLIC_KEYS as {"keyId":"-----BEGIN PUBLIC KEY-----…"}.
Clients verify the ed25519 signature against the pinned key, check the artifact digest and
size, and refuse downgrades, stale manifests, and revoked versions before anything is
written to disk. The server never signs on demand and never returns executable content.