Skip to content

feat: serve NGWMN exports from the new Ocotillo data model#718

Merged
jirhiker merged 8 commits into
stagingfrom
fix/ngwmn
Jun 12, 2026
Merged

feat: serve NGWMN exports from the new Ocotillo data model#718
jirhiker merged 8 commits into
stagingfrom
fix/ngwmn

Conversation

@jirhiker

Copy link
Copy Markdown
Member

What changed

Moves the /ngwmn endpoints off the static legacy copy tables and onto live views over the new Ocotillo data model.

  • NGWMN_WaterLevels, NGWMN_WellConstruction, NGWMN_Lithology views (migration u8v9w0x1y2z3): reproduce the original AMPAPI (NM_Aquifer) view_NGWMN_* definitions, but sourced from observation/sample/field_activity/field_event/thing, well_screen/well_casing_material, and thing_geologic_formation_association/geologic_formation.
  • transducer_daily_data materialized view (migration v0w1x2y3z4a5): daily aggregates of raw transducer observations per well, parameter, day, and QC status. Replaces NMA_WaterLevelsContinuous_Pressure_Daily as the daily rollup. Has a unique index so REFRESH MATERIALIZED VIEW CONCURRENTLY works via the refresh CLI.
  • services/ngwmn_helper.py: all three NGWMN queries now read the new views. The manual/transducer merge code was simplified from the 19-column positional legacy layout to the view's (point_id, date_measured, depth_to_water_bgs) rows; merge semantics are unchanged (manual reading wins on a shared date when shallower, one record per date), with a new NULL guard on the depth comparison.
  • .gitignore: ignore .claude/settings.local.json and .claude/worktrees/.

Notes for review

  • DepthToWaterBGS is computed as observation.value - measuring_point_height, because the transfer stored depth below the measuring point in value.
  • DateMeasured inverts the transfer's timezone logic: rows stored at 00:00 UTC (no time measured) keep the UTC date; others shift back to America/Denver.
  • The legacy CASE quirk mapping measurement-method code O ("Observed...") to "Acoustic Sounder" is preserved.
  • NGWMN_Lithology.Lithology and TERM both carry the resolved lithology term (the legacy abbreviation code was not migrated); StratSource is NULL (never transferred).
  • CasingDescription is rebuilt as a comma-separated list of well_casing_material terms; the legacy free text was not migrated.
  • NGWMN water-level freshness now depends on refreshing transducer_daily_data (oco refresh-pygeoapi-materialized-views --view transducer_daily_data).
  • The legacy NMA_view_NGWMN_* tables and their transfer scripts are untouched; references with the view_ prefix that remain in transfers/ point at legacy CSV sources, which is intentional.

Testing

  • New tests/test_ngwmn_endpoints.py: XML output for all three endpoints, BGS math, timezone date handling, method/accuracy mapping, private-record exclusion, and the manual/transducer merge (manual wins, transducer-only, transducer wins).
  • New tests/test_transducer_daily_data.py: aggregation correctness and concurrent refresh.
  • Full suite: 657 passed; the 2 tests/test_ogc.py failures are pre-existing on staging (verified on a clean tree).

🤖 Generated with Claude Code

jirhiker and others added 6 commits June 11, 2026 15:34
Add view_NGWMN_WaterLevels, view_NGWMN_WellConstruction, and
view_NGWMN_Lithology as PostgreSQL views over the new Ocotillo tables,
replicating the legacy AMPAPI (NM_Aquifer) view definitions so NGWMN
exports no longer depend on the static NMA_view_NGWMN_* copy tables.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Point the /ngwmn endpoint queries at view_NGWMN_WaterLevels,
view_NGWMN_WellConstruction, and view_NGWMN_Lithology instead of the
legacy NMA_view_NGWMN_* copy tables, and add endpoint tests covering
the XML output, BGS depth math, timezone date handling, measurement
method and accuracy mapping, and private-record exclusion.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Aggregate raw transducer observations into one row per well, parameter,
day, and QC status, replacing the legacy
NMA_WaterLevelsContinuous_Pressure_Daily table as the daily rollup.
Includes a unique index so the view supports REFRESH MATERIALIZED VIEW
CONCURRENTLY via the refresh CLI.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replace the legacy NMA_WaterLevelsContinuous_Pressure_Daily query in
make_waterlevels_response with the transducer_daily_data materialized
view, and simplify the merge/XML code to use the view's
(point_id, date_measured, depth_to_water_bgs) rows instead of the
19-column positional legacy layout. The merge rule is unchanged: on
overlapping dates the manual reading wins when shallower, and only one
record is emitted per date. Guard the depth comparison against NULLs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
view_NGWMN_WaterLevels, view_NGWMN_WellConstruction, and
view_NGWMN_Lithology become NGWMN_WaterLevels, NGWMN_WellConstruction,
and NGWMN_Lithology. The migration has not shipped, so it is edited in
place rather than adding a rename migration. References to the legacy
AMPAPI view names and CSV source tables keep the view_ prefix.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 11, 2026 22:32
@jirhiker jirhiker changed the title Serve NGWMN exports from the new Ocotillo data model feat: serve NGWMN exports from the new Ocotillo data model Jun 11, 2026
@jirhiker jirhiker requested review from ksmuczynski and lizalino June 11, 2026 22:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR moves the /ngwmn/* export endpoints off legacy static copy tables and onto live database views/materialized views backed by the new Ocotillo data model, including a new daily transducer aggregation MV used by the water-level export.

Changes:

  • Added NGWMN_WaterLevels, NGWMN_WellConstruction, and NGWMN_Lithology SQL views sourced from the Ocotillo tables.
  • Added transducer_daily_data materialized view (with indexes) to provide daily transducer aggregates and support concurrent refresh.
  • Updated the NGWMN service helper to query the new views and simplified manual/transducer merge logic; added new endpoint and MV tests.

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
alembic/versions/u8v9w0x1y2z3_add_ngwmn_views_from_ocotillo_model.py Introduces NGWMN_* views over the new Ocotillo schema.
alembic/versions/v0w1x2y3z4a5_add_transducer_daily_data_materialized_view.py Adds transducer daily aggregate materialized view + indexes for concurrent refresh.
services/ngwmn_helper.py Switches NGWMN endpoints to the new views and updates manual/transducer merge.
tests/test_ngwmn_endpoints.py Adds coverage for XML responses, BGS math, timezone handling, privacy exclusion, and merge behavior.
tests/test_transducer_daily_data.py Adds coverage for MV aggregation correctness and concurrent refresh capability.
.gitignore Ignores Claude Code local settings/worktrees.

Comment thread alembic/versions/u8v9w0x1y2z3_add_ngwmn_views_from_ocotillo_model.py Outdated
Comment thread services/ngwmn_helper.py Outdated
@jirhiker jirhiker marked this pull request as draft June 11, 2026 22:35
jirhiker and others added 2 commits June 12, 2026 09:24
Add read-only ORM mappings for the NGWMN_* views and the
transducer_daily_data materialized view on a separate declarative base,
kept out of Base.metadata so Alembic autogenerate does not try to
create tables for them. The NGWMN response builders now query these
models column-wise instead of executing raw SQL strings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The NGWMN views filtered only on observation.release_status, so a
private thing (or private screen/casing/lithology rows) could still be
exported. Require release_status='public' on the thing, field event,
field activity, sample, and observation in NGWMN_WaterLevels; on the
thing, well_screen, and well_casing_material rows in
NGWMN_WellConstruction; and on the thing and formation association in
NGWMN_Lithology. The transducer daily query in make_waterlevels_response
now joins thing and requires it to be public as well.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@jirhiker jirhiker marked this pull request as ready for review June 12, 2026 16:40
Copilot AI review requested due to automatic review settings June 12, 2026 16:40

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d7e7c5d18a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 7 changed files in this pull request and generated no new comments.

@jirhiker jirhiker merged commit 5c82913 into staging Jun 12, 2026
11 checks passed
@jirhiker jirhiker deleted the fix/ngwmn branch June 12, 2026 18:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants