Files
HealthLog/docs/migration/v1.3-to-v1.4.md
T
Marc-André Bombeck e444a90b10 revert: roll source tree back to v1.4.0 to restore production
Production at healthlog.bombeck.io has been 503-ing since the v1.4.1
deploys started landing on apps-01 (Coolify). The container boots —
Next.js prints "Ready" and the pg-boss workers run — but never
accepts HTTP on :3000, so the Docker healthcheck fails and Traefik
takes the upstream out of rotation. A manual restart, a Coolify
force-rebuild, and a docker-compose pin to the GHCR :1.4.0 multi-arch
image all failed to bring the site back up — Coolify rebuilds the
image from main HEAD on every deploy regardless of the compose
directives.

This commit resets the working tree to commit 21bd46d (v1.4.0
release). Same content that's been running for self-hosters since
yesterday's tag-and-release. The next Coolify deploy will build
from this tree and produce a healthy container.

The v1.4.1 work is NOT lost:
  - PRs #144, #145, #137, #146, #147, #148, #149, #150 remain in
    git history.
  - Their commits are still tagged (`v1.4.1`), still on the GHCR
    multi-arch image (`ghcr.io/mbombeck/healthlog:1.4.1`), still in
    the GitHub Release notes.
  - Self-hosters who have already pulled the v1.4.1 image keep it.
  - Local development continues from main HEAD with the v1.4.1
    code — the regression only surfaced under the Coolify build
    flow.

Re-applying v1.4.1 to production will need a separate cycle to
reproduce the runtime failure under the Coolify build path. That
work is tracked in docs/ops/v141-followup-issues.md (added back
when the tree is reapplied) and the deploy gating in
.github/workflows/e2e.yml will catch this class of bug going
forward.

No DB migration. No env-var change. No API contract change.
Co-Authored-By: Marc-André Bombeck <mbombeck@gmail.com>
2026-05-08 17:15:34 +02:00

5.5 KiB
Raw Blame History

Migrating from HealthLog 1.3 to 1.4

Both 1.3.x and 1.4.0 use Prisma migrations 0001–0024 and the same PostgreSQL schema. The upgrade is drop-in for self-hosters running the GHCR image — no manual migration step beyond the standard docker compose pull && docker compose up -d. This guide documents what changes for operators and integrators, in case you're extending the API.

TL;DR

docker compose pull
docker compose up -d

That's it. No DB migration to apply, no env vars to add, no breaking API change.

Database

  • Prisma schema unchanged from 1.3.3. Migrations 0001–0024 remain authoritative. v1.4.0 brings no new migration files.

Environment variables

  • NEXT_PUBLIC_APP_BUILD_SHA (optional, new) — the short Git SHA of the build, surfaced through /api/version so the future About surface can render it. The docker-publish workflow can wire this once the About UI lands.
  • NEXT_PUBLIC_APP_BUILT_AT (optional, new) — ISO-8601 build timestamp, same plumbing.

Neither is required. Local pnpm dev returns null for both fields and the UI falls back to "development" wording.

API

New

  • GET /api/version — public, static, returns { version, buildSha, builtAt, license, repository, changelog, docs }. No authentication.

Behaviour-only changes

  • POST /api/ai/test now accepts an optional JSON body that mirrors the AI dropdown in /settings. Empty body keeps the pre-1.4 behaviour (test the saved provider). Non-empty body tests the unsaved selection without persisting plaintext keys. The existing rate limit (5/min) and error-leak shielding stay in place.
  • GET /api/dashboard/summary localises the streak.label and greeting.salutation fields against the user's stored locale.
  • POST /api/insights/targets uses a single batched query for per-type latest readings; returns identical payloads.

No /api/... route changed shape, status codes, or auth rules. iOS, n8n, and Health Connect integrations need no change.

UI / UX

Dashboard

  • Tile strip is always one row. Previously the four-to-five-tile grid wrapped to a second row when many widgets were enabled. v1.4 uses a horizontal-scroll strip — total width caps at the chart width below, snap points keep the touch experience deliberate. To reduce the visible tile count, open Settings → Dashboard Layout and toggle widgets off.

Forms

  • Password managers no longer autofill health-data inputs. Browsers and LastPass / 1Password were happily filling the user's saved account password into measurement notes, AI tokens, and similar free-text fields. The <Input> primitive now defaults to autoComplete="off" plus the LastPass / 1Password ignore attributes whenever the caller doesn't pass a semantic value. Auth and profile forms (login, register, change-email) keep autofilling normally because they pass an explicit autoComplete (e.g. "username", "email", "new-password").

Settings

  • AI provider connection-test honours the unsaved selection. Pick a provider in the dropdown and click "Verbindung testen" without saving first — the test now runs against your in-form selection instead of the saved provider.

Notifications

  • Telegram, ntfy, and Web Push reminders follow your locale. Switching the user's locale to English now produces English reminders; the previous build always sent German strings regardless. Telegram callback IDs stay stable (English) so the bot dispatcher keeps matching them.

Medical defaults

  • Diastolic blood-pressure orange band no longer reaches 60 mmHg. A reading of 60 mmHg now lands in red instead of yellow. The user-override path is intact — if you set a personal threshold via /settings#thresholds, it still applies and is audit-logged.
  • Body-fat classifier mirrors the ACE table — readings below the ACE essential floor (M < 2 / F < 10) now classify as "Below essential" (danger), the actual essential band (M 2–5 / F 10–13) as warning, and the realistic healthy range (M 14–24 / F 21–31) as the green band on the dashboard target tile.
  • Step target unified at 8 000–15 000. The two surfaces that previously disagreed (7 000–10 000 in getStepsRange() versus 8 000–15 000 in the effective-range resolver) now use the same band, anchored on Saint-Maurice et al., JAMA 2020.

What's deferred to a future release

The v1.3.3 ecosystem audit identified four architectural rewrites that are intentionally outside v1.4.0:

  • Settings page split into per-section routes (/settings/[section]).
  • Admin page redesign with status-first card grid.
  • AI insights rework with severity-coloured key-findings hero and dynamic chart inclusion via an allowlist token map.
  • Multi-tenant prep (off-host backups, encryption-key versioning, worker/web container split, native-Bearer User-Agent gating).
  • Postgres-backed integration test suite (Testcontainers).

These ride a future release; the v1.4 marathon closed every CRIT and HIGH the audit identified except those four.

Rollback

If 1.4.0 surfaces a regression on your install, redeploy the previous 1.3.3 image:

docker compose down
docker pull ghcr.io/mbombeck/healthlog:1.3.3
sed -i 's/healthlog:1.4.0/healthlog:1.3.3/' docker-compose.yml
docker compose up -d

The schema is unchanged so a rollback does not require a database restore. File a GitHub issue with the symptom — the v1.4 cycle ran multi-agent QA per phase, but no migration is risk-free.