Operations
Platform
The applications run on a small, well-kept estate at home rather than in a cloud account: one host for the services, one for storage, a reverse proxy in front, and nothing exposed to the internet that does not need to be. What follows is how it is kept honest.
00
01
One shape per application
A NestJS API, a Next.js front end, and its own Postgres database. Same folder layout, same auth, same error handling — a change learned once applies everywhere.
02
Deploys that refuse
Every release builds the image, boots it in isolation and checks it answers, tags what was running as the rollback, then deploys and verifies: process stays up, health returns 200, unauthenticated requests are still refused, no errors in the log. Any failure rolls back on its own. It exists because a change that passed build, typecheck and 69 unit tests once crash-looped three applications at once.
03
Migrations are not automatic
A deploy is refused when the code's migrations disagree with the live database, naming the ones missing. Applying them is a deliberate step after a backup, because a missing migration otherwise passes every check while breaking every query.
04
Backups that have been restored
Nightly logical dumps of every database to network storage. A restore has been carried out into a scratch database and verified: row counts, balances and encrypted fields all readable. A backup nobody has restored is a hope, not a plan.
05
Tests pin the expensive rules
Not coverage for its own sake — tests for the rules whose absence cost money: duplicate imports, transactions that post late, money parsed through a float, a notifier that cannot tell silence from failure.
06
Secrets stay out of the repository
Credentials live in environment files on the host and in a password manager, never in git. Anything sensitive at rest is encrypted with a key held outside the database.
The services themselves are not reachable from the public internet, so there is no live status board here. That is the intended design, not an omission.