fix(diff): ignore preview env rows so they cannot shadow production (#85) #86

Merged
dan-claude-bot merged 1 commit from fix/env-preview-shadow into main 2026-07-16 16:39:34 +00:00

1 commit

Author SHA1 Message Date
claude-hdb
d083f74bec fix(diff): ignore preview env rows so they cannot shadow production (#85)
`GET /applications/{uuid}/envs` does not return one row per key: it merges
the production vars with the PREVIEW ones into one flat array
(`environment_variables->merge(environment_variables_preview)`,
ApplicationsController@envs v4.1.2). The two relations are complements split
on `is_preview`, with a unique index per (key, resource, is_preview) — so the
same key legitimately arrives twice. `fetchEnv` keyed by `key` alone, and
`Object.fromEntries` keeps the LAST, so cast diffed the manifest against
whichever row Coolify happened to serialize last.

Confirmed on prod: REPORTING_ENABLED came back as {value:"true",
is_preview:false} AND {value:"false", is_preview:true}; cast read the "false"
twin and re-proposed a `change` that could never clear.

That is also why #78 looked like a stale read. Both rows are born equal
(Coolify seeds a preview twin), and syncEnv only ever PATCHes the PRODUCTION
row — so the two diverge for exactly the vars updated in place. Five prod
flags flipped false->true re-proposed on every diff forever, while
created-once vars stayed clean because their twins still agreed. Nothing was
stale: cast was reading the other deployment's value. `real_value` tracked
`value` on every row, exactly as the accessor predicts.

cast declares PRODUCTION env and already says so on every write — syncEnv
sends `is_preview: false` on each bulk upsert. This is the read finally
saying the same thing; the asymmetry was the whole bug. Services and
databases map a single set, so this is a no-op for them.

Tests pin the exact prod shape, both serialization orders (the fix is "drop
preview", not "take the first"), a preview-only key, and rows with no
is_preview field at all.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 16:37:32 +00:00