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:
76
solver-api/src/fieldTraceability.js
Normal file
76
solver-api/src/fieldTraceability.js
Normal file
@@ -0,0 +1,76 @@
|
||||
import { MVP_FIELDS } from "./schema.js";
|
||||
|
||||
/**
|
||||
* Static MVP field classification aligned with docs/engineering/field-traceability.md.
|
||||
*/
|
||||
const CATEGORY_BY_FIELD = {
|
||||
WellName: "metadata",
|
||||
Company: "metadata",
|
||||
PumpingSpeed: "physics",
|
||||
PumpDepth: "physics",
|
||||
TubingAnchorLocation: "physics",
|
||||
RodFrictionCoefficient: "physics",
|
||||
StuffingBoxFriction: "physics",
|
||||
PumpFriction: "physics",
|
||||
WaterCut: "physics",
|
||||
MeasuredDepthArray: "physics",
|
||||
InclinationFromVerticalArray: "physics",
|
||||
AzimuthFromNorthArray: "physics",
|
||||
UnitsSelection: "parseCalibration",
|
||||
UpStrokeDampingFactor: "physics",
|
||||
DownStrokeDampingFactor: "physics",
|
||||
NonDimensionalFluidDamping: "physics",
|
||||
TaperDiameterArray: "physics",
|
||||
TaperLengthArray: "physics",
|
||||
TaperModulusArray: "physics",
|
||||
TaperWeightArray: "physics",
|
||||
TaperMTSArray: "physics",
|
||||
TaperGuidesCountArray: "physics",
|
||||
RodTypeArray: "physics",
|
||||
MoldedGuideFrictionRatio: "physics",
|
||||
WheeledGuideFrictionRatio: "physics",
|
||||
OtherGuideFrictionRatio: "physics",
|
||||
PumpDiameter: "physics",
|
||||
PumpIntakePressure: "physics",
|
||||
TubingSize: "payloadInactive",
|
||||
TubingGradient: "parsedUnused",
|
||||
PumpFillageOption: "physics",
|
||||
PercentPumpFillage: "physics",
|
||||
PercentageUpstrokeTime: "payloadInactive",
|
||||
PercentageDownstrokeTime: "payloadInactive",
|
||||
PumpingUnitID: "parsedUnused",
|
||||
PumpingSpeedOption: "parsedUnused",
|
||||
FluidLevelOilGravity: "physics",
|
||||
WaterSpecGravity: "physics",
|
||||
RodGuideTypeArray: "parsedUnused",
|
||||
RodGuideWeightArray: "physics",
|
||||
SinkerBarDiameter: "physics",
|
||||
SinkerBarLength: "physics"
|
||||
};
|
||||
|
||||
const NOTES_BY_FIELD = {
|
||||
TubingSize: "Forwarded as tubing_id_m; annular refinements not yet in primary equations.",
|
||||
TubingGradient: "Parsed to tubingGradientPaM; not included in C stdin payload.",
|
||||
PercentageUpstrokeTime: "Payload percent_upstroke_time; harmonic kinematics still dominant.",
|
||||
PercentageDownstrokeTime: "Payload percent_downstroke_time; harmonic kinematics still dominant.",
|
||||
PumpingUnitID: "Parsed for future pumping-unit geometry tables.",
|
||||
PumpingSpeedOption: "Parsed for future drive/kinematics modes.",
|
||||
RodGuideTypeArray: "Parsed string; type-specific friction law not yet wired to C.",
|
||||
UnitsSelection: "Controls imperial/SI normalization during XML parse."
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {{ rawFields?: Record<string, unknown> } | null | undefined} parsed
|
||||
*/
|
||||
export function buildFieldTraceability(parsed) {
|
||||
const raw = parsed && typeof parsed === "object" && parsed.rawFields ? parsed.rawFields : {};
|
||||
return {
|
||||
schemaVersion: 2,
|
||||
fields: MVP_FIELDS.map((xmlKey) => ({
|
||||
xmlKey,
|
||||
category: CATEGORY_BY_FIELD[xmlKey] ?? "physics",
|
||||
presentInXml: Object.prototype.hasOwnProperty.call(raw, xmlKey),
|
||||
notes: NOTES_BY_FIELD[xmlKey] ?? ""
|
||||
}))
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user