Operations
Operations
Local development
make setup # first time: install + .env + Postgres + migrate + seed
make dev # Postgres (if needed) + web + apimake dev ensures the root .env exists, starts Postgres via Docker when port
5430 is not already reachable, applies pending migrations, then runs both dev
servers in parallel:
- web — Vite on http://localhost:5170 (proxies
/apito the API). - api — Hono via
tsx watchon http://localhost:8780 (loads root.env).
Other useful targets:
| Command | Purpose |
|---|---|
make dev-nodb | Start web + api only (skip Postgres startup) |
make dev-web | Vite only |
make dev-api | Postgres + migrations + API only |
make dev-docs | Fumadocs only on http://localhost:5171 |
make miniapp | Generate native-shell config and open WeChat DevTools |
make miniapp-open | Sync config, clear DevTools project cache, and reopen apps/miniapp |
make miniapp-sync-config | Generate gitignored AppID/API/PWA config from apps/miniapp/.env |
make miniapp-clear-cache | Clear DevTools file/compile cache and rebuild its file watcher |
make dev-miniapp-api | Postgres + API + PWA dev servers for shell development |
make postgres-up / make postgres-down | Start/stop local Postgres container |
make db-init | db:migrate + db:seed |
make db-reset | drop all tables, then db:migrate + db:seed |
make deploy-up | Full docker stack (postgres + api + web on :8090) |
WeChat Mini Program local debug details: ../frontend/miniapp.md.
.env is created from .env.example on first run. BASE_URL is the single
public origin used by the frontend API client and Better Auth (default:
http://localhost:5170). Ensure DATABASE_URL matches the Postgres credentials
(defaults: opentrip:opentrip@localhost:5430/opentrip).
Local verification
pnpm install
pnpm typecheck
pnpm test
pnpm build
pnpm docs:checkmake check runs typecheck + lint + test + build. Dev servers are intentionally
not part of automated verification.
Environment variables
| Variable | Used by | Notes |
|---|---|---|
BASE_URL | web + api | public API/auth origin used by browser and Better Auth |
DATABASE_PROVIDER | api | postgres (default) or mysql; inferred from DATABASE_URL when omitted |
DATABASE_URL | api (Node/Docker) | Postgres or MySQL connection string |
BETTER_AUTH_SECRET | api | >= 32 chars |
TRUSTED_ORIGINS | api | comma-separated web origins |
STORAGE_BACKEND | api | required: fs, s3, or native Worker r2 |
STORAGE_ROOT | api | filesystem root or optional object prefix |
STORAGE_PUBLIC_URL | api | optional public base URL; defaults to BASE_URL/api/uploads |
R2_BUCKET_NAME | Cloudflare deploy | bucket injected as R2_FILE_STORAGE; not exposed as a Worker var |
S3_BUCKET | api (s3) | bucket name |
S3_REGION | api (s3) | region; use auto for Cloudflare R2 |
S3_ENDPOINT | api (s3) | S3-compatible endpoint URL |
S3_ACCESS_KEY_ID | api (s3) | secret access key id |
S3_SECRET_ACCESS_KEY | api (s3) | secret access key |
S3_FORCE_PATH_STYLE | api (s3) | optional true/false, default false |
WECHAT_WEB_APP_ID / WECHAT_WEB_APP_SECRET | api | optional WeChat Open Platform website QR login |
WECHAT_MINI_PROGRAM_APP_ID / WECHAT_MINI_PROGRAM_APP_SECRET | api only | Mini Program login (jscode2session); never ship secret to the client |
MINIAPP_APP_ID | make miniapp* | AppID generated into gitignored project.private.config.json |
MINIAPP_API_BASE_URL | native shell | API request origin generated into gitignored miniprogram/config.js |
MINIAPP_WEB_BASE_URL | native shell | PWA business-domain origin generated into gitignored miniprogram/config.js |
CLOUDFLARE_OBSERVABILITY_TOKEN | local operator | historical Workers Logs query token; never synced to the Worker |
On Cloudflare, DATABASE_URL is replaced by the Hyperdrive binding; set Worker
var DATABASE_PROVIDER to postgres or mysql to match the origin database.
Better Auth and S3 credential values are set with wrangler secret.
Production Mini Programs must configure MINIAPP_WEB_BASE_URL as a WeChat
business domain and MINIAPP_API_BASE_URL as a request domain.
Common commands
| Command | Purpose |
|---|---|
pnpm db:migrate | apply pending Prisma migrations |
pnpm db:seed | load prototype seed data |
pnpm db:reset | drop public schema, then migrate + seed |
pnpm db:generate | regenerate Prisma Client after schema changes |
make help | list Make targets |
Deployment
- Cloudflare (Pages + Workers + Hyperdrive): cloudflare.md.
Production: https://opentrip.im (web) ·
https://docs.opentrip.im (docs) · https://api.opentrip.im (API).
Pushing to
mainauto-deploys via GitHub Actions; see the Cloudflare doc for required repo secrets and the Hyperdrive bootstrap step. Read-after-write pitfalls (create trip missing from list, etc.): cloudflare.md#hyperdrive-read-after-write and ../frontend/data-caching.md. - Docker Compose (postgres + api + web): docker.md.
Logs and backup
- Cloudflare:
pnpm logs:cffor historical Workers Logs andpnpm logs:cf -- --livefor Wrangler live logs. - Docker:
docker compose logs -f api; Postgres backup viapg_dump(see docker.md). - Agent/API trace correlation, Sentry queries, structured-log fields, and symptom runbooks: observability.md.
- Production incident notes and regression checks: incidents/2026-07-14-workers-caching.md.