Summary
The Environment module can show a valid configured home location but remain permanently at 0 days recorded because every environment-fetch job fails when Prisma tries to write the source enum.
The database migration creates the PostgreSQL enum as:
public.environment_location_source
but the Prisma schema declares EnvironmentLocationSource without an enum @@map, so the Prisma 7 PostgreSQL driver adapter generates a cast/reference to:
public.EnvironmentLocationSource
That type does not exist. The fetch succeeds far enough to reach the database upsert, then the entire transaction fails and no environment_contexts rows are stored.
Affected version
Confirmed on a self-hosted server running:
- HealthLog
v1.32.31
- Prisma client
7.8.0
- PostgreSQL 16
Current main still has the same unmapped enum declaration, so this is not limited to the deployed patch version.
User-visible reproduction
- Enable/open the Environment module.
- Configure a valid home location and effective date.
- Wait for the immediate/default fetch or the nightly environment job.
- Open the native Environment screen.
Actual behavior
The screen shows:
Home location
<configured location>
Weather data
0 days recorded
No weather data ever appears.
Expected behavior
Recent eligible days should be fetched from Open-Meteo, persisted in environment_contexts, and reflected in the overview count and downstream environmental correlations.
Confirmed production evidence
The account had:
- a valid coarse home latitude/longitude;
- an IANA home timezone;
homeSince set to 20 July 2026;
- the Environment module enabled by the normal default-on module policy.
Read-only database queries showed:
environment_contexts rows: 0
environment_travel_locations rows: 0
The overview endpoint correctly returned context_days = 0; this is not an iOS-only display error.
The nightly pg-boss job ran at the documented 02:10 Europe/Berlin schedule and retried three times. Each attempt failed with PostgreSQL error 42704:
[pg-boss] [environment-fetch] failed Error [DriverAdapterError]:
type "public.EnvironmentLocationSource" does not exist
The repeated failure occurred before any row could be committed.
Migration/schema mismatch
Migration 0217_v125_environmental_context creates:
CREATE TYPE "environment_location_source" AS ENUM ('HOME', 'TRAVEL');
Migration 0219_v125_env_home_since later adds:
ALTER TYPE "environment_location_source" ADD VALUE IF NOT EXISTS 'DEVICE';
The applied production database therefore contains:
public.environment_location_source
HOME
TRAVEL
DEVICE
and environment_contexts.source uses that exact type.
Current prisma/schema.prisma declares:
enum EnvironmentLocationSource {
HOME
TRAVEL
DEVICE
}
with no mapping to the migrated snake-case PostgreSQL type.
The EnvironmentContext model itself is correctly mapped to environment_contexts, but its enum is not.
Root cause
A schema/migration naming drift:
- physical PostgreSQL enum:
environment_location_source
- logical Prisma enum:
EnvironmentLocationSource
- missing Prisma enum mapping
With the current Prisma PostgreSQL adapter, the upsert references the logical enum type name and PostgreSQL rejects it because only the snake-case type exists.
Smallest general fix
Map the Prisma enum to the existing database type and regenerate the client:
enum EnvironmentLocationSource {
HOME
TRAVEL
DEVICE
@@map("environment_location_source")
}
This preserves existing databases and future installs without renaming a live enum type or rewriting the column.
An alternative would be a migration that renames the physical PostgreSQL enum to "EnvironmentLocationSource", but mapping Prisma to the already-established snake-case database contract is smaller and less disruptive.
Recovery behavior
After the schema/client fix is deployed:
- the existing nightly seven-day lookback should automatically retry and fill recent eligible dates;
- an explicit backfill should work for the permitted range;
- no manual deletion or recreation of the home location should be necessary.
Regression tests
Migrated-database integration
Create a real PostgreSQL test database by applying the production migrations, then run an EnvironmentContext create/upsert using each source value:
This must be a database integration test, not only a mocked Prisma test, because mocks cannot detect physical enum-name drift.
Environment job
- Configure a home location with an eligible effective date.
- Stub Open-Meteo with one or more daily observations.
- Run
handleEnvironmentFetch().
- Assert
stored > 0 and rows exist in environment_contexts.
- Re-run and verify idempotent upsert behavior.
API/UI
GET /api/environment reports the stored day count and latest date.
- Native/web environment surfaces stop showing
0 days recorded after successful storage.
Migration-contract guard
Add a schema/migration consistency check for mapped PostgreSQL enums so a Prisma logical enum name cannot silently drift from its physical database type again.
Scope
This is not caused by Open-Meteo availability, the home effective-date rule, module configuration, or the native UI. The upstream fetch reaches the persistence path; the PostgreSQL enum lookup fails during the database write.
Summary
The Environment module can show a valid configured home location but remain permanently at 0 days recorded because every
environment-fetchjob fails when Prisma tries to write thesourceenum.The database migration creates the PostgreSQL enum as:
but the Prisma schema declares
EnvironmentLocationSourcewithout an enum@@map, so the Prisma 7 PostgreSQL driver adapter generates a cast/reference to:That type does not exist. The fetch succeeds far enough to reach the database upsert, then the entire transaction fails and no
environment_contextsrows are stored.Affected version
Confirmed on a self-hosted server running:
v1.32.317.8.0Current
mainstill has the same unmapped enum declaration, so this is not limited to the deployed patch version.User-visible reproduction
Actual behavior
The screen shows:
No weather data ever appears.
Expected behavior
Recent eligible days should be fetched from Open-Meteo, persisted in
environment_contexts, and reflected in the overview count and downstream environmental correlations.Confirmed production evidence
The account had:
homeSinceset to 20 July 2026;Read-only database queries showed:
The overview endpoint correctly returned
context_days = 0; this is not an iOS-only display error.The nightly pg-boss job ran at the documented
02:10 Europe/Berlinschedule and retried three times. Each attempt failed with PostgreSQL error42704:The repeated failure occurred before any row could be committed.
Migration/schema mismatch
Migration
0217_v125_environmental_contextcreates:Migration
0219_v125_env_home_sincelater adds:The applied production database therefore contains:
and
environment_contexts.sourceuses that exact type.Current
prisma/schema.prismadeclares:with no mapping to the migrated snake-case PostgreSQL type.
The
EnvironmentContextmodel itself is correctly mapped toenvironment_contexts, but its enum is not.Root cause
A schema/migration naming drift:
environment_location_sourceEnvironmentLocationSourceWith the current Prisma PostgreSQL adapter, the upsert references the logical enum type name and PostgreSQL rejects it because only the snake-case type exists.
Smallest general fix
Map the Prisma enum to the existing database type and regenerate the client:
This preserves existing databases and future installs without renaming a live enum type or rewriting the column.
An alternative would be a migration that renames the physical PostgreSQL enum to
"EnvironmentLocationSource", but mapping Prisma to the already-established snake-case database contract is smaller and less disruptive.Recovery behavior
After the schema/client fix is deployed:
Regression tests
Migrated-database integration
Create a real PostgreSQL test database by applying the production migrations, then run an
EnvironmentContextcreate/upsert using each source value:HOMETRAVELDEVICEThis must be a database integration test, not only a mocked Prisma test, because mocks cannot detect physical enum-name drift.
Environment job
handleEnvironmentFetch().stored > 0and rows exist inenvironment_contexts.API/UI
GET /api/environmentreports the stored day count and latest date.0 days recordedafter successful storage.Migration-contract guard
Add a schema/migration consistency check for mapped PostgreSQL enums so a Prisma logical enum name cannot silently drift from its physical database type again.
Scope
This is not caused by Open-Meteo availability, the home effective-date rule, module configuration, or the native UI. The upstream fetch reaches the persistence path; the PostgreSQL enum lookup fails during the database write.