mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 04:32:42 +00:00
Six touch-disjoint waves landed on develop before this release: - W1-KNIP — exports/types tiers flipped to enforcing-mode on main; 35 unused exports + 52 unused types triaged to 0/0; shadcn surface + zod-infer contract types scoped via knip.json ignore-block. - W2-ZOD-MULTI-ISSUE — `returnAllZodIssues` shared helper + `/api/dashboard/widgets` 422 now returns every Zod issue + worker audit-ledger breadcrumb. 41 sibling routes documented for v1.4.43. - W3-QUERYKEY-LONGTAIL — 40 settings/medications/admin/hooks files migrated to the queryKeys factory; 9 new factory entries; ESLint rule + test-guard scope extended in lockstep. - W4-ARCH-HYGIENE — BERLIN_DAY_FORMATTER consolidated across nine sites (seven status helpers + bucket-series + bp-in-target); Suspense double-comment consolidated; doctor-report sanitiser regex rewritten to escape-form so diffs are reviewable; pr-detection- worker soft-delete filter; offhost-backup DR-intent comment. - W5-IOS-WORKOUTS — `dedupeWorkoutBatch` write-time cross-source dedup helper for the v1.5 iOS HealthKit observer ingest; dashboard tile-strip placeholder parity with the live TrendCard chrome. - W6-WITHINGS-OFF + ENV-CHECK — Withings off-response classifier (transient/reauth/persistent) + WithingsApiError typed throw + the `pnpm check-env` CLI. APNs `allOrNone: true` closes the AP-2 silent-disable gap the wave was conceived to close. No migration, no env-var change, no API contract break for iOS v0.5.4. The new `/api/dashboard/widgets` 422 envelope is additively extended. pnpm test --run green at 4815 passing / 1 skipped. pnpm typecheck, pnpm lint, pnpm knip (no --include flag) green.
108 lines
4.3 KiB
JSON
108 lines
4.3 KiB
JSON
{
|
|
"$schema": "./env-manifest.schema.json",
|
|
"description": "Manifest of env vars required by a HealthLog production deployment. Used by `pnpm check-env` to catch missing/empty vars BEFORE a deploy ships. v1.4.42 W6 — born out of the v1.4.40 AP-2 .p8 install gap that shipped silently for 3 days.",
|
|
"groups": [
|
|
{
|
|
"name": "Core",
|
|
"description": "Database, app URL, encryption keys. The app refuses to boot without these.",
|
|
"required": true,
|
|
"variables": [
|
|
{
|
|
"name": "DATABASE_URL",
|
|
"purpose": "Postgres connection string. App boot fails if missing.",
|
|
"example": "postgresql://healthlog:<pw>@db:5432/healthlog?schema=public"
|
|
},
|
|
{
|
|
"name": "POSTGRES_PASSWORD",
|
|
"purpose": "Database password for the bundled `db` service in docker-compose.yml.",
|
|
"example": "<openssl rand -base64 24>"
|
|
},
|
|
{
|
|
"name": "NEXT_PUBLIC_APP_URL",
|
|
"purpose": "Public URL embedded in OAuth redirects, webhook callbacks, APNs deep-links."
|
|
},
|
|
{
|
|
"name": "APP_URL",
|
|
"purpose": "Server-side mirror of NEXT_PUBLIC_APP_URL; used by background workers."
|
|
},
|
|
{
|
|
"name": "ENCRYPTION_KEY",
|
|
"purpose": "AES-256-GCM key for at-rest encryption of provider tokens. 64 hex chars (32 bytes). Required unless ENCRYPTION_KEYS is set."
|
|
},
|
|
{
|
|
"name": "API_TOKEN_HMAC_KEY",
|
|
"purpose": "HMAC-SHA256 key for hashing external Bearer tokens. 64 hex chars."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Withings OAuth",
|
|
"description": "Required to enable the Withings integration. App boots without these but Withings sync stays disabled.",
|
|
"required": false,
|
|
"variables": [
|
|
{
|
|
"name": "WITHINGS_CLIENT_ID",
|
|
"purpose": "Withings OAuth client_id from https://developer.withings.com."
|
|
},
|
|
{
|
|
"name": "WITHINGS_CLIENT_SECRET",
|
|
"purpose": "Withings OAuth client_secret."
|
|
},
|
|
{
|
|
"name": "WITHINGS_WEBHOOK_SECRET",
|
|
"purpose": "Random secret carried as a path segment in the Withings webhook callback URL. Generate with `openssl rand -hex 32`."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "APNs (iOS push)",
|
|
"description": "All four core APNS_* vars together. Missing any disables APNs silently — the v1.4.40 AP-2 gap that motivated this manifest. allOrNone trips the synthetic <all-or-none> required row whenever 1-3 of the 4 are set.",
|
|
"required": false,
|
|
"allOrNone": true,
|
|
"variables": [
|
|
{
|
|
"name": "APNS_KEY_ID",
|
|
"purpose": "10-char Key ID from Apple Developer."
|
|
},
|
|
{
|
|
"name": "APNS_TEAM_ID",
|
|
"purpose": "10-char Team ID from Apple Developer."
|
|
},
|
|
{
|
|
"name": "APNS_BUNDLE_ID",
|
|
"purpose": "iOS app bundle id, e.g. dev.healthlog.ios."
|
|
},
|
|
{
|
|
"name": "APNS_KEY",
|
|
"purpose": "APNs auth key (.p8 contents). Use APNS_KEY for 12-factor env-block deploys; APNS_KEY_FILE is the filesystem alternative — at least one of the two must be set.",
|
|
"anyOf": ["APNS_KEY", "APNS_KEY_FILE"]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Deploy webhook",
|
|
"description": "Coolify -> HealthLog deploy-result webhook. Without this, the auto-deploy success/failure feedback loop is broken.",
|
|
"required": false,
|
|
"variables": [
|
|
{
|
|
"name": "DEPLOY_WEBHOOK_SECRET",
|
|
"purpose": "Shared secret for the X-Deploy-Webhook-Secret header on POST /api/internal/deploy-webhook. 64 hex chars."
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Off-host backups",
|
|
"description": "Required ALL-OR-NONE: any of these without the rest disables backups silently.",
|
|
"required": false,
|
|
"allOrNone": true,
|
|
"variables": [
|
|
{ "name": "BACKUP_S3_ENDPOINT", "purpose": "S3-compatible endpoint URL." },
|
|
{ "name": "BACKUP_S3_BUCKET", "purpose": "Bucket name." },
|
|
{ "name": "BACKUP_S3_ACCESS_KEY", "purpose": "S3 access key." },
|
|
{ "name": "BACKUP_S3_SECRET_KEY", "purpose": "S3 secret key." },
|
|
{ "name": "BACKUP_ENCRYPTION_KEY", "purpose": "Separate AES key for the backup body — MUST NOT match ENCRYPTION_KEY." }
|
|
]
|
|
}
|
|
]
|
|
}
|