feat: gate heavy solver JSON, field traceability API, GUI rod/export depth

- C: emit profiles/diagnostics/fourier only when enable flags are set; null otherwise
- API: fieldTraceability on case parse/default and solve; fix GET /solve/default options
- Tests: golden fingerprint, quality gates, C diagnostics invariants; cardQa mean empty guard
- Makefile: test-solver-sanitize ASan/UBSan target; README and COMPUTE_PLAN updates
- GUI: taper weight/MTS/guides/sinker round-trip, rod catalog, solver output toggles,
  results (profiles/diagnostics/Fourier/traceability), engineering checks and tabs
- Restore canonical WellName in base-case for regression; trace TaperGuidesCountArray

Made-with: Cursor
This commit is contained in:
2026-04-16 23:19:00 -06:00
parent 10f6ae1c2b
commit 64e9d31373
39 changed files with 1318 additions and 369 deletions

View File

@@ -17,6 +17,10 @@ describe("solver-api", () => {
expect(response.status).toBe(200);
expect(response.body.runMetadata.source).toBe("base-case.xml");
expect(response.body.solver.pointCount).toBe(200);
expect(response.body.solver.profiles).toBeNull();
expect(response.body.solver.diagnostics).toBeNull();
expect(response.body.fieldTraceability?.schemaVersion).toBe(2);
expect(Array.isArray(response.body.fieldTraceability?.fields)).toBe(true);
});
it("returns fea prototype result and comparison payload", async () => {
@@ -70,7 +74,7 @@ describe("solver-api", () => {
expect(response.status).toBe(200);
expect(response.body.solver.pointCount).toBe(200);
expect(response.body.parsed.model.wellName).toContain("191/01-27-007-09W2/00");
expect(response.body.parsed.model.wellName).toBe("PLACEHOLDER-WELL");
expect(Array.isArray(response.body.parsed.unsupportedFields)).toBe(true);
});
@@ -99,6 +103,7 @@ describe("solver-api", () => {
expect(response.body.unsupportedFields.sort()).toEqual(
defaultResp.body.unsupportedFields.sort()
);
expect(response.body.fieldTraceability?.fields?.length).toBeGreaterThan(0);
});
it("rejects empty body on POST /case/parse", async () => {