Skip to content

Fix/pr49 verify unification bugs#55

Open
diegokingston wants to merge 15 commits into
pr/3-calc-report-and-pro-polishfrom
fix/pr49-verify-unification-bugs
Open

Fix/pr49 verify unification bugs#55
diegokingston wants to merge 15 commits into
pr/3-calc-report-and-pro-polishfrom
fix/pr49-verify-unification-bugs

Conversation

@diegokingston

Copy link
Copy Markdown
Collaborator

No description provided.

Batuis and others added 15 commits May 29, 2026 14:10
Phase 1 of verification architecture cleanup (SOLVER_APP_COVERAGE_MAP.md §13):

- New verification-service.ts: centralized station-demand computation and
  unified CIRSOC verification entry point (computeStationDemands,
  runUnifiedVerification)
- ProDesignTab: uses shared service instead of inline station computation
- ProVerificationTab: replaced 116-line endpoint-only force extraction loop
  with one call to runUnifiedVerification (fixes Bug #2: interior forces missed,
  Bug #4: two divergent paths)
- Serviceability: deflection now estimates midspan deflection when endpoint
  displacements are negligible (fixes Bug #3); service moment uses dead-load
  case when available instead of Mu/1.4 approximation (fixes Bug #5)
- Both tabs now produce identical verification results through the same
  station-based pipeline and store them in verificationStore.setConcrete()

What this does NOT do (blocked by no-solver-changes constraint):
- No new WASM exports (§13.5 verify_members still pending)
- No deletion of JS verification modules (§13.9 — still needed as primary path)
- No VerificationReport Rust types (§13.6 — solver-side)
- verification-service.ts: header now lists Phase 1 vs Phase 2 scope and
  exactly which app-side bridges remain (station extraction, JS CIRSOC, autoVerify)
- ProVerificationTab: service moment, midspan deflection estimate, and steel
  verification loop all marked as TEMPORARY Phase 1 bridges with Phase 2 targets
- No behavior changes — annotation only
…t type

Steel path reduction:
- Moved 65-line steel verification loop from ProVerificationTab into
  verification-service.ts as runSteelVerification()
- Steel path now uses station-based demands when available (same source as RC),
  falling back to endpoint extraction only when combos aren't computed
- Removed getEnvelopeSolicitations (endpoint-only legacy function) — no longer
  called by either RC or steel paths
- Cleaned unused imports from ProVerificationTab (verifySteelElement,
  SteelVerificationInput, SteelDesignParams)

VerificationReport type:
- New VerificationReport interface in verification-service.ts shaped to mirror
  the eventual solver-side output (§13.6 of SOLVER_APP_COVERAGE_MAP.md)
- Contains: codeId, codeName, elements (MemberDesignResult[]), summary,
  optional stationData, and legacy detail arrays for Phase 1 compatibility
- Components can consume this shape without knowing whether the source is
  JS-side or future WASM-side

Net effect on ProVerificationTab: -96 lines of inline computation removed.
Both RC and steel verification now flow through verification-service.ts.
…cess

- New runCirsocDesign() in verification-service.ts: single entry point that
  runs verification + normalizes + updates both verificationStore.setConcrete()
  and setDesignResults() — replaces 3 separate calls in ProDesignTab
- ProDesignTab: CIRSOC path reduced to one runCirsocDesign() call; removed
  direct imports of normalizeCirsoc201 and autoVerifyFromResults
- Replaced 6 O(n) verificationStore.concrete.find() scans with O(1)
  concreteMap.get() lookups throughout ProDesignTab
- Non-CIRSOC paths still handled inline (WASM payload assembly is code-specific)

Net: ProDesignTab no longer assembles or normalizes CIRSOC verification data —
it calls the service and renders the result.
…nsitional access

- constructibility, autoSplitRows, rowFits: now use getElemSection() (model data)
  + provided reinforcement stirrup diameter instead of reading from concreteMap.
  Eliminates 3 of 6 concreteMap accesses — these were geometry queries that
  belonged on the model, not verification results.

- Remaining 3 concreteMap accesses (acceptAutoDesign, getProvidedVerification,
  template memos/drawings) explicitly labeled as TRANSITIONAL with Phase 2
  migration targets documented inline.

- acceptAutoDesignAll also labeled as transitional iteration over concrete array.

Net: ProDesignTab's 6 concreteMap accesses → 3 (all labeled transitional).
The other 3 now depend only on model geometry + provided reinforcement.
…ependencies

- New getCodeDetail() adapter in verification-service.ts: extracts render-ready
  memos, interaction diagram params, detailing, and slenderness from the
  transitional concreteMap. Components call this instead of reaching into
  concreteMap directly.
- New CodeDetail interface: normalized shape for code-specific rendering data.
  Phase 2: solver returns this as VerificationReport.elements[].detail.
- ProDesignTab template: replaced direct concreteMap.get() + 40 lines of
  v.flexure.steps / v.shear.steps / v.column / v.torsion / v.biaxial / v.slender
  rendering with codeDetail.memos loop + codeDetail.slender + codeDetail.detailing.
- acceptAutoDesignAll: now iterates normalized designResults instead of
  transitional concrete array.
- Net: ProDesignTab concreteMap accesses 6 → 2 (both in labeled TRANSITIONAL
  functions). Template has zero direct concreteMap access.
ProPanel had its own autoVerify() + computeStationDemands() — a full duplicate
of the service-layer functions, used only for the report generation flow. This
was a third independent verification path alongside ProDesignTab and
ProVerificationTab.

- Replaced ProPanel's inline computeStationDemands() (15 lines) with
  computeStationDemandsService() from verification-service.ts
- Replaced ProPanel's inline autoVerify() (12 lines, calling autoVerifyFromResults
  directly) with runUnifiedVerification() from verification-service.ts
- Removed ProPanel's direct imports of extractElementStations,
  extractGoverningDemands, autoVerifyFromResults

All three verification consumers (Design, Verification, Report) now flow
through the same service-layer functions. No component directly imports
auto-verify.ts or station-design-forces.ts extraction functions.
…rop chain

- ProPanel: verificationsRef changed from local $state (duplicate) to $derived
  from verificationStore.concrete. Eliminates the second copy of verification
  results that was maintained independently from the store.
- ProPanel: report auto-verify now writes to store only, not to local state.
  verificationsRef updates automatically via derivation.
- ProRcWorkflowTab: removed dead verifications bindable prop — it was accepted
  but never used by ProDesignTab or passed anywhere.
- ProPanel: removed bind:verifications on ProRcWorkflowTab (no prop to bind).

Write path simplification:
  Before: 3 setConcrete calls (service, ProVerificationTab, ProPanel)
  After:  2 setConcrete calls (service, ProVerificationTab)
  ProPanel's write was redundant — the store already has the data.

Read path simplification:
  Before: ProPanel maintained local verificationsRef + prop chain to
          ProRcWorkflowTab → (unused)
  After:  ProPanel reads directly from verificationStore.concrete
ProVerificationTab is not imported or rendered by any active component.
It was disconnected when ProRcWorkflowTab was simplified to render only
ProDesignTab (QA3 pass). The file is retained as a reference for features
that should be re-integrated:
- Serviceability (cracking, deflection)
- Quantities / bar marks
- Slab reinforcement design
- Steel verification rendering
- Story drift
- Frame-line / column-stack elevations

Added header documenting dormant status and reactivation guidelines:
read from verificationStore, use getCodeDetail(), route through service.
Primary path now uses solver-side `extractBeamStationsGrouped3D` WASM for
station extraction instead of the JS reimplementation in
station-design-forces.ts. Falls back to JS when WASM is unavailable.

What changed:
- computeStationDemands() now accepts optional model data; when provided,
  builds BeamStationInput3D payload and calls the existing WASM export
- New computeStationDemandsWasm(): builds payload from perCombo3D + model,
  calls extractBeamStationsGrouped3D, adapts output
- New wasmMemberToStationResult(): adapts MemberStationGroup3D → app-side
  ElementStationResult for compatibility with extractGoverningDemands
- All 3 callers (ProDesignTab, ProVerificationTab, ProPanel) updated to
  pass model data, enabling the WASM path

Architecture effect:
- Station interpolation is now solver-backed (Rust evaluates beam diagrams)
- Only demand extraction (stations → governing demands) remains JS-side
  (design_demands.rs exists internally but is not exported as WASM)
- JS extractElementStations (~300 LOC) remains as fallback, could be
  deleted once WASM path is confirmed stable

Deferred (deliberate):
- CIRSOC 201 WASM: exists and exported, but switching would lose step-by-step
  memo output that the JS path provides (needed for QA-confirmed UX)
- Serviceability WASM: exists but only checks limits, doesn't compute midspan
  deflection — no advantage over current app-side limit check
Two bugs in wasmMemberToStationResult dropped data the JS path required:

1. The WASM `StationComboForces3D.torsion` field was discarded when
   building `StationForces`, so downstream `extractGoverningDemands`
   read `s.torsion === undefined`. The Torsion `GoverningDemand` was
   created with `value: undefined`, crashing the Design tab when
   `expandedDemands.demands` rendered `d.value.toFixed(1)`.

2. `ElementStationResult.stationTs` was omitted from the WASM-built
   result; carry the distinct station t-values explicitly.

Also tighten the fallback gate: replace bare try/catch (which silently
swallowed all errors, including #1 above) with an explicit
`isSolverReady()` check. Genuine WASM-not-ready falls through to JS;
real WASM-call errors now propagate.
ProMaterialsTab and ProSectionsTab were discarding the boolean from
modelStore.removeMaterial / removeSection, so a user clicking × on a
material or section that is still referenced by elements got no feedback
at all (no toast, no inline error, nothing in the console). The model
layer correctly refuses the deletion to preserve referential integrity,
but the UX silently absorbed the rejection.

Surface the rejection via the existing toast pattern (uiStore.toast,
already used throughout PRO for similar feedback) and the existing
i18n keys table.cannotDeleteMaterial / table.cannotDeleteSection
(already used in the Basic-mode tables). No model-layer change — the
integrity guard is preserved unchanged.

Found in Phase 5 audit: silent in-use-rejection of material/section
delete with no user feedback.
…in ProVerificationTab (SEAM 3 anchor)

After the verification-service unification, the inline _mzMax/_myMax/_mzM mapping that anchored SEAM 3 in the component disappeared. Reintroduce as endpointDemandEnvelope(ef) and route the dead-load crack-width service moment through .Mu (byte-identical to the prior inline Math.max). Station-based demands still flow through verification-service; no divergence in displayed verification numbers.
…ign, batch accept)

Bounded, non-domain fixes from the review. Web suite: 2125 passing
(5 skipped); vite build clean.

- ProPanel: the report only re-verified CIRSOC when verificationStore was
  empty, so after editing the model (store still populated from a prior run)
  the report showed stale verification results next to current model data.
  Always re-verify against the current model on report open.
- verification-service (runSteelVerification): the station-demand branch
  collapsed demands with the SIGNED `.value` via Math.max, so a compression-
  only axial (n<0) or hogging-only moment (Mz-<0) became 0 — designing the
  steel member as unloaded. Use `.absValue` (the magnitude used for ranking),
  matching the RC path in auto-verify.ts. NOTE: this path is currently only
  reachable from the dormant ProVerificationTab, so the bug is latent today;
  fixing it removes the landmine before that tab is reactivated.
- ProDesignTab (acceptAutoDesignAll): accepting auto-design for N elements
  cloned the whole elements Map and bumped the reinforcement version once per
  element, and each bump re-ran the WASM station extraction + re-verified
  every element (O(M·N)). Thread a commit flag through setProvided/
  acceptAutoDesign so the batch mutates all elements then triggers reactivity
  once. Default commit=true keeps all other call sites unchanged.

Deliberately NOT fixed (documented in review — need domain work / are
intentional):
- WASM station extraction samples 11 uniform stations and drops the critical
  interior stations (point-load/zero-shear peaks) the JS path inserted, so
  governing moment/shear can be under-sampled (unconservative) in the live
  Design tab + report. Needs the Rust beam-station extractor to accept/insert
  critical stations (or reinstating JS critical sampling) — PE-relevant.
- Two CIRSOC capacity engines (cirsoc201.ts vs station-design-forces.ts) still
  coexist; the dormant ProVerificationTab and the unused VerificationReport
  interface were kept intentionally by the authors as a reactivation reference.
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.

2 participants