Porting · porting/2026-05-05-zweistein-server-local-runtime.md Docs Home

Zweistein Server Local Runtime Slice

Date: 2026-05-05

Objective

Make the imported legacy zweistein/server reproducible locally against the shared local Postgres and Redis services.

This is the second backend-level proof after Studio API. It does not yet mean the full platform is running end to end.

What Was Added

  • configs/local/zweistein-server.env.example Local-only placeholder values for the Zweistein database, Studio API database connection, Redis streams, Auth0 placeholders, Stripe placeholders, LLM placeholders, and storage placeholders.
  • scripts/zweistein-server-local.mjs Small helper for install, build, start, health checks, and database table-count checks.
  • package.json scripts:
    • zweistein-server:install
    • zweistein-server:build
    • zweistein-server:start
    • zweistein-server:health
    • zweistein-server:db-status
  • legacy-src/zweistein/server/src/main.ts Now reads PORT with default 3000, preserving old behavior while making local and Hetzner-style runtime configuration easier.

The helper prefers Homebrew node@20 when available, because the legacy Dockerfile uses Node 20.

Local Commands

Start the shared local infrastructure first:

npm run legacy:infra:up

Install Zweistein server dependencies:

npm run zweistein-server:install

Build Zweistein server:

npm run zweistein-server:build

Start Zweistein server:

npm run zweistein-server:start

In another terminal, check health:

npm run zweistein-server:health

Expected health response:

Server is healthy

Check how many local Postgres tables were created in the zweistein database:

npm run zweistein-server:db-status

Expected current result:

Zweistein public tables: 39

Verification Evidence

  • npm run zweistein-server:install completed with Yarn 4.5.0 and warnings only.
  • npm run zweistein-server:build passed.
  • npm run zweistein-server:start launched the API on localhost:3000.
  • npm run zweistein-server:health returned Server is healthy.
  • npm run zweistein-server:db-status returned Zweistein public tables: 39.
  • http://localhost:3000/ai/docs served Swagger UI.
  • Redis contains the stream:zweistein:notifications stream with consumer group group:zweistein:notifications.

Important Findings

The imported Zweistein server package has migration scripts in package.json, but the expected src/dataSource.ts and migration files are not present in the imported snapshot.

Current local schema creation happens because AppModule configures the main TypeORM connection with:

synchronize: true

That is acceptable for this local rebuild proof, but it is not a production-grade Hetzner database strategy.

Before production, this needs one of these safer paths:

  • recover the original migration history if it exists elsewhere;
  • generate a baseline migration from the local synchronized schema;
  • design a fresh schema migration plan for the rebuilt service.

Runtime Placeholders Required For Boot

Zweistein server initializes some external clients during application boot. For local health checks, placeholder values are enough because no external requests are made.

Required non-empty placeholder groups:

  • Auth0 issuer and audience values
  • SERVER_JWT_SECRET
  • OPENAI_API_KEY
  • GOOGLE_API_KEY
  • STRIPE_API_KEY
  • STRIPE_WEBHOOK_SECRET
  • storage provider placeholders

These placeholders are not production secrets.

Not Yet Done

  • Authenticated API routes were not exercised.
  • Stripe flows were not tested.
  • LLM/chat flows were not tested.
  • Storage upload/download was not tested against MinIO or Hetzner storage.
  • Redis stream worker behavior was not tested beyond boot-time stream/group creation.
  • Zweistein server is not containerized in the new project yet.
  • Zweistein admin and embedding widget are not wired to this local server yet.
  • Python query and ingestion services are still not running locally.