Skip to content

F13: Destructive-action guards + prefill-failure overwrite fix (#59) - #61

Merged
mforce merged 2 commits into
mainfrom
feat/f13-destructive-guards
Jul 17, 2026
Merged

mforce merged 2 commits into
mainfrom
feat/f13-destructive-guards

Conversation

@mforce

@mforce mforce commented Jul 16, 2026

Copy link
Copy Markdown
Owner

Closes #59. SPA-only, 3 files. Follow-up to the mis-deplete incident that motivated #57.

What

  • Confirm dialogs on every one-way action: daily-entry Save & submit (creates lots), sales Confirm order (allocates stock — void is F14: Void confirmed sales order — return allocated stock #60) and Cancel draft, flock deplete/archive. Reversible actions stay one-click. Plain window.confirm for now; styled dialogs belong to the UI design revamp — distinctive visual identity #52 revamp.
  • Prefill-failure guard: the daily-entry edit prefill was best-effort — a failed lookup rendered zeros for a day that has data, and saving would overwrite the draft. Failure now blocks both save buttons with an explanatory error + retry; saving unblocks only after a successful prefill.

Verification (chromium, real stack, both dialog paths each)

  • Deplete: dismiss → stays Active; accept → Depleted.
  • Save & submit: dismiss → nothing submitted; accept → Submitted with lots.
  • Cancel draft: dismiss → draft panel intact; accept → cancelled.
  • Prefill: aborted the lookup via route interception → banner + disabled saves; retry after restoring → unblocked.
  • Confirm-order dialog: gate code identical to the three verified above; not driven live because a confirmable order needs stock seeding (dialog fires before any API call, so the dismiss path is the same logic).

mforce added 2 commits July 16, 2026 16:27
Follow-up to the mis-deplete incident (#57): one-way actions fired on
a single click, and one silent-overwrite path existed.

Confirm dialogs (window.confirm; styling revisits with #52):
- Daily entry: Save & submit — freezes the day, creates egg lots.
- Sales: Confirm order (allocates stock; void is #60) and Cancel
  draft (lines discarded).
- Flocks: deplete and archive (one-way until reactivate, #57).
Reversible actions (grade deactivate, line remove) stay one-click.

Prefill-failure guard (daily entry): the edit-aware prefill was
best-effort — if the lookup failed, the form showed zeros for a day
that has data and saving would overwrite the existing draft. Prefill
failure now shows an error, disables both save buttons, and offers a
retry; saving unblocks only after a successful prefill.

Verified in chromium against the real stack, both dialog paths each:
dismiss leaves state untouched (flock stays Active, nothing submits,
draft panel stays), accept proceeds (deplete, submit, cancel). Prefill
verified by aborting the lookup: banner + disabled saves, retry after
unroute re-enables.

Closes #59
- Prefill retry no longer clears the blocked state optimistically:
  saves stay disabled from the moment a prefill is in flight until it
  succeeds (new prefillPending state) — the optimistic clear reopened
  the exact overwrite window the guard exists to close. (codex P1,
  pi High)
- A retry that recovers for the same flock+date no longer zeroes the
  form: values typed while the banner was up survive (there is no
  server entry to overwrite); a normal date/flock change still resets.
  (pi Medium)
- Sales confirms hoisted above run(): buttons no longer flash disabled
  while the user is deciding, matching the Flocks pattern. (pi Medium)
- Cancel-draft dialog reworded: cancellation is a status change — the
  order keeps its lines and becomes read-only; "lines are discarded"
  was wrong. (codex P2)

Re-verified in chromium: retry-while-broken stays blocked, typed
values survive a retry recovery, normal date change still resets,
recovery unblocks saving.
@mforce

mforce commented Jul 16, 2026

Copy link
Copy Markdown
Owner Author

Review round: codex + pi

# Source Severity Finding Action
1 codex + pi P1/High Retry cleared prefillFailed optimistically before the lookup resolved — a quick save in that window could overwrite the draft, the exact bug the guard closes Fixed — prefillPending state; saves blocked from fetch start until success; clear only in .then (9f906e2)
2 pi Medium Retry recovery with no existing entry re-zeroed the form, wiping values typed while the banner was up Fixed — same-target retry recovery preserves the form; normal flock/date changes still reset (9f906e2)
3 pi Medium Sales confirms ran inside run() — all buttons flashed disabled while the user was deciding Fixed — confirms hoisted above run(), matching the Flocks pattern (9f906e2)
4 codex P2 Cancel dialog claimed "line items are discarded" — cancel is a status change; lines are kept, order becomes read-only Fixed — reworded (9f906e2)
5 pi Low window.confirm silently returns false in sandboxed/iframe contexts Accepted — noted; styled dialogs come with #52
6 pi Low Confirm strings hardcoded (i18n) Deferred — #45's string-extraction sweep will catch these with the rest of the SPA
7 pi Low Deplete dialog's "backfill still works" claim should track the domain Verified — matches CanRecordProductionOn semantics shipped in #48/#55

Re-verified after fixes: retry while the network is still broken stays blocked; typed values survive a retry recovery; a normal date change still resets the form; recovery unblocks saving.

@mforce
mforce merged commit 2e48984 into main Jul 17, 2026
2 checks passed
@mforce
mforce deleted the feat/f13-destructive-guards branch July 17, 2026 00:01
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.

F13: Destructive-action guards — confirms + prefill-failure overwrite fix

1 participant