Operations
Deployment
Merging to master is deploying. The API ships to Heroku with migrations in the release phase. Both apps ship to Vercel.
master is production
A push to GitHub master in api-v2 or totlob-pos reaches real users within minutes, and API migrations run as part of it. master isn't branch-protected.
API: Heroku
| Item | Value |
|---|---|
| App | cypher-prod (git remote heroku). GitHub repo totlob/cypher. |
| Database | PostgreSQL on Stackhero (not a Heroku add-on) |
| Cache | Redis Cloud |
| Trigger | Auto-deploy from GitHub master, configured outside the repo |
Procfile:
release: npm run db:migrate # runs before new dynos take traffic
web: npm start
worker: npm run consumer # keep at 0 until a broker exists
- Consumers: use either a scaled
workerdyno orWEB_CONSUMES_QUEUE=trueonweb, never both. - Scheduler:
npm run sync-ratesdaily at 06:00 UTC, once the FX branch ships. Run it once by hand after the first deploy. - Planned move: PR #86
feat/aws-deploy(EC2 + Docker + Caddy, RDS, SQS replacing RabbitMQ).
Apps: Vercel
| App | Build | Output | Notes |
|---|---|---|---|
| Dashboard | tsc -b && vite build | dist/ | SPA rewrite. Target domain app.totlob.com. Expects a same-origin API or a reverse proxy. |
| POS | tsc -b && vite build | dist/ | SPA rewrite. VITE_API_BASE_URL is baked in at build time. |
Pushing safely
push.default = upstream
A branch cut from origin/master tracks master, so a plain git push pushes to master, whatever the branch is called. Always push with an explicit destination:
git push origin HEAD:refs/heads/<branch>
or unset branch.<name>.merge first.
Before pushing to a Heroku app directly, check which branch it's running. A wrong branch once removed endpoints from the live dashboard (HANDOVER.md).
Release order for a new endpoint
- Publish the contract (push the contracts repo's
master), then wait about a minute. - Pin it exactly in api-v2, implement it, and merge. The API deploys.
- Pin it in the dashboard or POS, use it, and merge. The app deploys.
Clients must never ship ahead of the API.
Post-deploy steps
Search backfill
With SEARCH_BACKEND=postgres, an empty search_document shows an empty catalogue with no error. After deploying search changes:
- Run
scripts/backfill-search.tslocally against the productionDATABASE_URL.tsxis pruned on Heroku, andheroku pg:psqldoesn't work with Stackhero. - Then run
VACUUM ANALYZE search_document.
FX rates
Run heroku run npm run sync-rates once after the FX job first ships. Until a rate exists, shops trading in anything but USD can't load their catalogue.
Client seeds
Client data scripts (e.g. seed-cafe-modifiers.mjs) run against production via .env.prod. Run them dry first, then with --apply.