[P3] Pre-dive main-page gas select offers to replace all cylinders even when a cylinder already holds that gas #124
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Priority: P3
Type: bug
Source: full codebase review requested 2026-10-31 (independently reproduced against
2cac7cf)Location:
src/App.tsx:233-266,src/App.tsx:1361-1368,src/App.tsx:3046-3074,docs/USER-GUIDE.md:74Problem and evidence
Before the dive starts (depth 0 and no cylinder usage),
selectMainGasnever checks whether a cylinder already holds the chosen gas. If there is more than one non-oxygen cylinder, it always setspendingGasand opens the "Replace cylinder setup?" dialog. Accepting rewrites the active cylinder to the new gas ([id]: { ...cylinder, gas: gas.name }) and removes every other cylinder (except the CCR oxygen cylinder). That includes a cylinder that already held the chosen gas, along with its label, volume, pressures and reserve. It also removes ascent switches for other gases. Rejecting keeps the old gas. So pre-dive, the main-page select cannot simply switch to a gas you have already set up in another cylinder. USER-GUIDE.md:74 says gas changes use the selected cylinder if its mix matches, otherwise the first matching cylinder. The guide does not mention the replace-setup prompt at all. During the dive the same select goes straight toswitchGasand follows the documented rule.Line-by-line trace of selectMainGas at HEAD
2cac7cf:beforeDiveis true whendive.depth === 0and allcylinderUsagevalues are 0.extraCylindersholds every cylinder except the CCR oxygen cylinder. With two OC cylinders (Cylinder 1 Air, Cylinder 2 EAN32) its length is 2 andacceptedis false, sosetPendingGas(EAN32)runs and the function returns. Nothing ever looks atcylinders[*].gas.selectMainGas(pendingGas, true)runs.id= activeCylinder ("1").setCylindersgets only{ "1": {...cyl1, gas: "EAN32"} }(plus the oxygen cylinder on CCR), so Cylinder 2 is deleted.setPlannedSwitcheskeeps only EAN32 switches (and Oxygen on CCR).Suggested correction
At the start of the beforeDive branch in selectMainGas, look for a matching cylinder: prefer
selectedCylinderif its gas matches, otherwise the firstObject.keys(cylinders).find(id => cylinders[id].gas === gas.name). If one exists, callsetSelectedCylinder(id), clear automatic deco andswitchGaswithout prompting or changing the cylinder layout. Keep the replace-setup prompt only when no cylinder holds the chosen gas, and describe that pre-dive behaviour in USER-GUIDE.md near line 74.Acceptance criteria
Regression test (App-level, Testing Library or Playwright):
USER-GUIDE.md describes the pre-dive replace prompt. pnpm verify passes.
Scope: maintenance of the educational simulator. Preserve historical R1 acceptance and operational-validation limits.