airi/server
RainbowBird 5ea7bb1083
Some checks are pending
CI / Lint (push) Waiting to run
CI / Build Test (stage-tamagotchi) (push) Waiting to run
CI / Build Test (stage-tamagotchi-godot) (push) Waiting to run
CI / Build Test (stage-web) (push) Waiting to run
CI / Build Test (ui-loading-screens) (push) Waiting to run
CI / Build Test (ui-transitions) (push) Waiting to run
CI / Unit Test (push) Waiting to run
CI / Type Check (push) Waiting to run
CI / Check Provenance (push) Waiting to run
Cloudflare Pages (Auth UI) / Deploy - ui-server-auth (push) Waiting to run
Cloudflare Workers / Deploy - stage-web (push) Waiting to run
feat(auth): add lastSeenAt field to user schema and tests
2026-08-17 21:57:25 +08:00
..
apps feat(auth): add lastSeenAt field to user schema and tests 2026-08-17 21:57:25 +08:00
dev/caddy refactor(server): split independent auth service (#2202) 2026-08-12 23:33:58 +08:00
packages/auth-shared feat(auth): add lastSeenAt field to user schema and tests 2026-08-17 21:57:25 +08:00
AGENTS.md feat(api): hot-reload ConfigKV from Postgres (#2289) 2026-08-15 22:24:32 +08:00
docker-compose.yaml refactor(server): split independent auth service (#2202) 2026-08-12 23:33:58 +08:00
README.md fix(api): load Drizzle migrations at runtime (#2307) 2026-08-17 11:19:53 +00:00

AIRI Backend

Project AIRI's hosted backend source lives under this folder. Workspace package names stay stable; the directory groups service source and database ownership while production deployment configuration remains in proj-airi/airi-railway.

Layout

  • apps/api: resource API, business domains, database migrations, and API runtime.
  • apps/auth: standalone Better Auth and OIDC service.
  • packages/auth-shared: Auth-owned database schema and principal contracts.
  • dev/caddy: local-only public edge routing for the shared Auth/API origin.
  • docker-compose.yaml: complete local API + Auth + PostgreSQL + Redis + Caddy stack.

Run locally

From the repository root:

pnpm dev:backend

The command uses server/docker-compose.yaml and exposes only Caddy at http://localhost:6112.

Railway deployment

API and Auth are separate long-running Railway services built from the same repository. Keep each service's Root Directory at the repository root: both Dockerfiles copy workspace manifests and shared packages from that build context. In each Railway service, configure the Config File Path explicitly:

Service Config File Path Public role Private dependency
Resource API /server/apps/api/railway.toml Product and resource API Auth issuer and JWKS
Auth /server/apps/auth/railway.toml Better Auth and OIDC issuer Resource API deletion endpoint

Each config pins its own Dockerfile, start command, /readyz healthcheck, and watch patterns. A change only deploys a service when it changes that service, one of its copied shared packages, or a copied root build input.

Service-to-service contract

Share database, Redis, and observability variables using Railway reference variables rather than copying secret values between services. Configure the two directional private links as follows:

Consumer Variable Value source Purpose
Resource API AUTH_SERVER_URL Auth's canonical public issuer URL JWT issuer, audience, and public JWKS identity
Resource API AUTH_SERVER_INTERNAL_URL Auth's Railway private domain Private JWKS fetch; it does not change issuer validation
Auth PUBLIC_URL Auth's canonical public issuer URL Better Auth and OIDC issuer URL; must equal API AUTH_SERVER_URL
Auth RESOURCE_SERVER_URL API's Railway private domain Private call before deleting a user's business data

Set RATE_LIMIT_TRUSTED_PROXY=railway only for services directly receiving Railway proxy traffic. Keep /internal/* private: Auth calls the API over its private domain, and public routing must not expose the API's internal Auth routes.

The API remains the shared database migration owner. Do not add a Railway pre-deploy migration command to Auth, and do not make Auth startup run shared migrations. After either service deploys, Railway must receive 200 from that service's /readyz; deployment success alone is not sufficient evidence that the service can reach its required dependencies.

Not included

Frontend applications remain under apps/. Cross-runtime server SDK and protocol packages remain under packages/ because Web, Electron, plugins, and independent services consume them.

Production Caddy routing, OpenTelemetry Collector configuration, observability storage, and Grafana dashboards live in proj-airi/airi-railway so deployment topology is not duplicated in the application repository.