Measurement services: editing, persistence, and recalculation
Measurement services: editing, persistence, and recalculation
This document summarizes the main flows in:
apps/hub/src/services/measurementService.tsapps/hub/src/services/measurementEditorService.ts
Goal: clarify responsibilities so geometry changes (alpha/beta/dip) and persistence changes (Supabase) stay aligned.
1. measurementService.ts (basic Supabase operations)
Main functions:
1.1 updateMeasurementStatus(measurementId, status)
Updates:
approval_statusupdated_at
1.2 Deletions
deleteMeasurement(measurementId, options?)- deletes from
measurements - optionally prepares image deletion (CDN), but this flow does not execute ImageKit deletion (credential reasons)
- optionally records deletion history with
saveDeletionRecord
- deletes from
deleteMeasurements(measurementIds, options?)- deletes one by one and accumulates errors
1.3 Full update
updateMeasurement(measurementId, updates)
Updates fields provided in updates:
point_trios(if provided)device_info(if provided)boh_lines(if provided)dynamic_data(assumed embedded indevice_infoasdynamic_data)sondaje_id(if provided)
Returns true when update succeeds.
1.4 Edit a single trio
updatePointTrio(measurementId, trioId, updates, editedBy?)- loads full measurement
- finds trio by
id - adds
editHistoryrecord when relevant changes occur (points/structureType/color/etc.) - persists with
updateMeasurement(...)
updateTrioPoints(measurementId, trioId, points, editedBy?)updateTrioStructureType(measurementId, trioId, structureType, color?, editedBy?)
1.5 Create measurement
createMeasurement(measurement)
Creates a Supabase record with:
device_info.measurement_sourceand source label
1.6 Recalculation and persistence from edited points
recalculateAndUpdatePlaneFromPoints(measurementId, trioId, points, options)
Flow:
- Dynamically imports
planeRecalculator.ts - Gets measured alpha/beta from original trio as fallback
- Recalculates dip/dipDirection and angles (alpha/beta optionally)
- Tries to recalculate
depthandstructureDepthMfromdevice_info.composite_image_depth(when parseable) - Updates the trio in Supabase through
updatePointTrio(...)
1.7 Measurement reassignment
reassignMeasurements(measurementIds, newSondajeId, sourceProjectId)
Updates:
sondaje_idproject_id(if destination drillhole belongs to another project)
2. measurementEditorService.ts (flows from Field/Editor)
Main functions:
2.1 loadMeasurementById(measurementId)
Loads measurement and normalizes:
- parses
point_trios(can be JSON string) - interprets
device_info.composite_image_depthas scene base - converts points to Hub conventions:
- x/y to meters
- z to Hub local Z ([-0.15, +0.15]) with detection to avoid reconverting data already created in Hub
- extracts
boh_anglesusingextractBohAngles(...)
2.2 updateMeasurement(measurementId, updates)
Flow:
- Verifies session (Supabase auth)
- Loads current measurement
- Ensures
boh_linesis saved as{line1_angle, line2_angle} - Normalizes coordinates before saving:
- projects points to max radius when needed
- clamps Z to Hub local visibility convention
- If
measurementIdis not a valid UUID:- creates new measurement and deletes old one (compatibility with non-standard IDs)
- Preserves
device_info(and ensuresmeasurement_sourcemetadata)
Returns true/false.
2.3 updateMeasurementTrioFromDiscontinuity(...)
Receives validated discontinuity payload:
alpha,beta, and equation (if available)
Calculates dip/dipDirection using:
calculateDipAndDipDirectionFromAlphaBeta(...)
Then updates trio and dynamicData with equation/alpha/beta.
2.4 addMeasurementTrioFromValidatedDiscontinuity(...)
Creates a new trio from validated candidate and appends it to measurement:
- assigns
idandpoints(clamped to 3 points) depthin cm calculated fromdepthCenterM- sets
structureType,color,angles, anddynamicData
3. Validation checklist
- Edit points in 3D editor:
- confirm coordinates are normalized to expected clamping
- confirm dip/dipDirection/angles recalculate and persist
- Update from discontinuities:
- confirm dip/dipDirection are derived from
alpha/beta+ drillhole context
- confirm dip/dipDirection are derived from
- ID compatibility:
- if ID is not valid UUID, verify new measurement is created and old one deleted without losing
device_info
- if ID is not valid UUID, verify new measurement is created and old one deleted without losing