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 when well_depth is absent.
  • calculateHoleFillVolume sums the net annular volume of every gravel pack interval, subtracting the casing and screens inside it.
  • getLatestStaticLevel takes the most recent static level from the hydrodynamic events, skipping any event retracted by a correction (corrections). isFlowingArtesian is true when that level is negative.
  • getLatestPumpingDynamicLevel is the last level measured while pumping; calculateSubmergence is the depth of the current pump's intake below it.
  • getLatestAquiferAnalysisField reads a field from the most recent interpretation that has it.
  • getCurrentWellStatus is the status of the latest status_change log entry, or undefined (unknown) when there is none (status_change).
  • getProductionTotal derives 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.

Next