Skip to content

Align in_flight_scripts_json to the array shape it actually carries#447

Merged
ppXD merged 2 commits into
mainfrom
fix/inflight-checkpoint-array-shape
Jun 15, 2026
Merged

Align in_flight_scripts_json to the array shape it actually carries#447
ppXD merged 2 commits into
mainfrom
fix/inflight-checkpoint-array-shape

Conversation

@ppXD

@ppXD ppXD commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • The deployment checkpoint's in_flight_scripts_json column was seeded/defaulted/documented as the legacy object form "{}", but InFlightScriptMap serializes a List<Entry> — a JSON array [{ "m": machineId, "s": stepId, "a": actionId, "t": scriptTicket }]. Parse("{}") throws (caught → treated as empty), so "{}" only ever worked via that catch fallback, and a fresh checkpoint's "{}" leaked past IsMachineBusyAsync's != "[]" pre-filter.
  • Align the empty form to "[]" across all four sources of truth: entity default (+ doc-comment), EF column default, EnsureExistsAsync seed, and a DbUp migration.

Changes

  • DeploymentExecutionCheckpoint.cs — default "[]" + doc-comment now describes the array shape.
  • DeploymentExecutionCheckpointConfiguration.csHasDefaultValue("[]").
  • DeploymentCheckpointService.EnsureExistsAsync — seed "[]".
  • 20260615_align_inflight_scripts_default_to_array.sqlALTER COLUMN ... SET DEFAULT '[]'::jsonb + rewrite existing empty '{}' rows to '[]' (empty object ≡ empty array — pure shape normalization).

Non-breaking

  • InFlightScriptMap.Parse still tolerates any leftover legacy shape (left untouched) — existing data unaffected.
  • EF always supplies an explicit value on insert, so the DB default is belt-and-braces.
  • No new MachineUpgradeStatus enum value; no change to the upgrade-defer logic. Purely a data-shape alignment.

Test plan

  • Integration (real Postgres, InFlightScriptStoreTests): new EnsureExists_SeedsInFlightScriptsJson_AsEmptyArray pins the seed is "[]" (discriminating vs the prior "{}"); existing suite (16) green incl. the seeded-checkpoint busy-check.
  • Unit (InFlightScriptMapTests, 23): legacy "{}" / malformed / "[]" all → empty via the retained Parse catch — confirms tolerance of pre-migration rows.
  • Build green; DbUp migration applies cleanly (the integration DB is freshly migrated).

The deployment checkpoint's in_flight_scripts_json column was seeded/defaulted
to the legacy object form "{}", but InFlightScriptMap serializes a List<Entry>
— a JSON array [{ "m", "s", "a", "t" }]. Parse("{}") throws (caught → treated
as empty), so "{}" only ever worked via that catch fallback, and a fresh
checkpoint's "{}" leaked past IsMachineBusyAsync's "!= []" pre-filter.

Align the empty form to "[]":
- Entity default (DeploymentExecutionCheckpoint) + doc-comment (now describes
  the array shape).
- EF column default (DeploymentExecutionCheckpointConfiguration) → "[]".
- EnsureExistsAsync seed → "[]".
- DbUp migration: ALTER COLUMN ... SET DEFAULT '[]'::jsonb and rewrite existing
  empty '{}' rows to '[]' (empty object == empty array in meaning, so a pure
  shape normalization).

Non-breaking: InFlightScriptMap.Parse still tolerates any leftover legacy shape
(left untouched), and EF always supplies an explicit value on insert, so the DB
default is belt-and-braces. No new MachineUpgradeStatus enum / no upgrade-defer
logic change — purely a data-shape alignment.

Tests: new integration case pins EnsureExistsAsync seeds "[]" (not "{}");
existing InFlightScriptStore (16) + InFlightScriptMap (23, incl. legacy-{}
→ empty via the catch) suites green.
@ppXD ppXD added this to the 1.9.3 milestone Jun 15, 2026
…t (review)

Adversarial review of #447 surfaced two fix-optional items, both addressed:

- The migration's UPDATE ('{}' -> '[]') was untested: the integration harness
  migrates a FRESH (empty) DB, so the UPDATE is a no-op there. Add an integration
  test that seeds BOTH legacy shapes (empty '{}' and a non-empty
  {machineId:ticket} object) then runs the same UPDATE, asserting the empty one
  normalizes to '[]' and the non-empty one is NOT clobbered (pins the WHERE = '{}'
  selectivity the migration comment promises).
- Update the IsMachineBusyAsync comment, which still claimed '{}' was the seed /
  column default — it is now '[]'; '{}' is the legacy shape kept defensively until
  the 20260615 migration normalizes it.

InFlightScriptStore (17) integration tests green.
@ppXD
ppXD merged commit c41de7b into main Jun 15, 2026
15 checks passed
@ppXD
ppXD deleted the fix/inflight-checkpoint-array-shape branch June 15, 2026 05:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant