Getting started
First use
Load a .well file and compute a well summary with @welldot/utils, covering depth, gravel pack volume, water levels, specific capacity, status and production.
This page builds a short summary of a well, the kind of block a report or a registry page shows. It uses one of the example wells, a 204 m supply well in crystalline rock with a pumping test, permits and meters.
summary.ts
import { readFile } from 'node:fs/promises';
import { createRequire } from 'node:module';
import { calculatedWellDepth, parseWell } from '@welldot/core';
import {
calculateHoleFillVolume,
calculateSubmergence,
formatNumber,
getCurrentWellStatus,
getLatestAquiferAnalysisField,
getLatestPumpingDynamicLevel,
getLatestStaticLevel,
getProductionTotal,
isFlowingArtesian,
} from '@welldot/utils';
const require = createRequire(import.meta.url);
const file =
require.resolve('@welldot/core/examples/coluna-mg-cristalino-abastecimento.well');
const well = parseWell(await readFile(file, 'utf8'));
const m = (v: number | undefined) =>
formatNumber(v, { fractionDigits: 2, suffix: 'm' });
console.log({
depth: m(well.well_depth ?? calculatedWellDepth(well)), // '204.00 m'
gravelPack: formatNumber(calculateHoleFillVolume('gravel_pack', well), {
fractionDigits: 2,
suffix: 'm³',
}), // '1.88 m³'
staticLevel: m(getLatestStaticLevel(well)), // '3.94 m'
flowing: isFlowingArtesian(well), // false
dynamicLevel: m(getLatestPumpingDynamicLevel(well)), // '52.75 m'
pumpSubmergence: m(calculateSubmergence(well)), // '9.25 m'
specificCapacity: getLatestAquiferAnalysisField(well, 'specific_capacity'), // 0.291 (m²/h)
status: getCurrentWellStatus(well) ?? 'unknown', // 'active'
produced: formatNumber(getProductionTotal(well).total, { suffix: 'm³' }), // '1,238,406 m³'
});
What each call does:
calculatedWellDepth(from core) is the deepest construction depth, used whenwell_depthis absent.calculateHoleFillVolumesums the net annular volume of every gravel pack interval, subtracting the casing and screens inside it.getLatestStaticLeveltakes the most recent static level from the hydrodynamic events, skipping any event retracted by a correction (corrections).isFlowingArtesianis true when that level is negative.getLatestPumpingDynamicLevelis the last level measured while pumping;calculateSubmergenceis the depth of the current pump's intake below it.getLatestAquiferAnalysisFieldreads a field from the most recent interpretation that has it.getCurrentWellStatusis the status of the lateststatus_changelog entry, orundefined(unknown) when there is none (status_change).getProductionTotalderives volumes from meter readings with the spec's rollover and gap rules (volume derivation).
Functions return
undefined when the data is not there: no test, no pump, no meter. That is the format's "absent means unknown" rule carried into code. formatNumber shows — for it.