No description
  • TypeScript 74.7%
  • JavaScript 18.1%
  • HTML 5.1%
  • CSS 1.6%
  • Shell 0.5%
Find a file
Chris Harrington 105dfea9e3 [IRRIGOAPI-117] API survives Postgres not ready at boot; no watcher in live stack (#15)
## Ticket

[IRRIGOAPI-117](http://192.168.2.100:7123/home/browse/IRRIGOAPI-117/) API silently dies if Postgres isn't ready at boot (host reboot race + bun --watch masks crash)

After the 2026-09-26 host reboot, the API hit Postgres `57P03` in `verifyMigrations` and threw uncaught. `bun --watch` kept the dead process alive, and with no healthcheck the container sat "Up" with nothing on 9753 for ~3.5h.

## Summary

- `waitForDbReady` (`api/db/wait-for-db-ready.ts`): bounded 60s `select 1` probe before `verifyMigrations`. It retries transient SQLSTATE/socket errors (`57P03`, `ECONNREFUSED`, Docker DNS `ESERVFAIL`/`ENOTFOUND`, …) and throws on timeout or a non-transient error.
- New shared `findPgErrorCause` (`api/db/pg-error.ts`) walks `.cause`, because Drizzle's `db.execute` wraps driver errors in `DrizzleQueryError` without copying `.code`. It also fixes a latent bug: verify-migrations' "not migrated" (42P01/3F000) branch was unreachable in production.
- `runMain` (`api/run-main.ts`) is now the single startup exit point. Any startup error is logged and ends in `exit(1)`. `bootstrap` no longer calls `process.exit` itself.
- docker-compose: `command: ${API_COMMAND:-bun start}`. The live stack runs without the file watcher, so a crash exits and `restart: unless-stopped` recovers it. Worktrees opt into hot reload with `API_COMMAND=bun run dev` (documented in `.env.example` and `CLAUDE.md`).
- docker-compose: a Bun-fetch healthcheck on `127.0.0.1:9753/health` (the image has no curl/wget) with `start_period` 120s, plus the `autoheal=true` label.
- Live-verified on the primary stack:
  - `docker restart irrigo-db irrigo-api` → the API recovers unaided and reaches healthy.
  - DB stopped → retries for ~60s, then `"startup: fatal error, exiting"`, and the container cycles instead of sitting Up. After DB start it recovers.
  - Tests 1090/1090 and type-check pass.
- Operational note: the primary stack no longer hot-reloads. Run `docker restart irrigo-api` after editing `api/` code there.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Reviewed-on: #15
2026-09-27 21:16:00 -06:00
.claude Update docs and skills to use full IRRIGOAPI/IRRIGOAPP ticket keys 2026-06-12 08:17:57 -06:00
.devcontainer Update devcontainer configuration. 2026-05-22 22:42:50 -06:00
.forgejo/workflows Add plane-sync workflow. 2026-06-12 10:46:19 -06:00
.vscode Dev container setup. 2026-05-06 20:49:20 -06:00
api [IRRIGOAPI-117] API survives Postgres not ready at boot; no watcher in live stack (#15) 2026-09-27 21:16:00 -06:00
app [IRRIGOAPP-109] Replace in-app alert UI with Android system notifications (#10) 2026-08-23 21:45:17 -06:00
shared Fix type errors, fix tests, and shared workspace folder. 2025-12-23 20:09:42 -07:00
.env.example [IRRIGOAPI-117] API survives Postgres not ready at boot; no watcher in live stack (#15) 2026-09-27 21:16:00 -06:00
.gitignore [HOMELAB-141] Move Postgres data from named volume to bind mount 2026-09-26 14:10:14 -06:00
build-apk.sh Update build-apk.sh to avoid build locks. 2026-05-29 10:44:08 -06:00
CLAUDE.md [IRRIGOAPI-117] API survives Postgres not ready at boot; no watcher in live stack (#15) 2026-09-27 21:16:00 -06:00
docker-compose.yml [IRRIGOAPI-117] API survives Postgres not ready at boot; no watcher in live stack (#15) 2026-09-27 21:16:00 -06:00
Dockerfile.dev Add Claude Code CLI tool to dev container. 2026-06-25 10:58:21 -06:00
Dockerfile.metro Add push notification infrastructure and fix credential setup 2026-07-05 16:59:23 +00:00
migrate.sh Add a database migration script. 2026-05-24 17:34:04 -06:00
seed.sh Add seed script. 2026-05-31 18:58:24 -06:00