Skip to content

🚨 ⚠️ 💀 [NO TICKET]: Well inventory csv Feature Tests#247

Merged
jirhiker merged 196 commits into
stagingfrom
well-inventory-csv
Feb 8, 2026
Merged

🚨 ⚠️ 💀 [NO TICKET]: Well inventory csv Feature Tests#247
jirhiker merged 196 commits into
stagingfrom
well-inventory-csv

Conversation

@jirhiker

@jirhiker jirhiker commented Nov 14, 2025

Copy link
Copy Markdown
Member

🚨 ⚠️ 💀 DO NOT MERGE UNTIL VERIFYING DB SCHEMA IS COMPATIBLE WITH THIS PR

Why

This PR addresses the following problem / context:

  • Use bullet points here

How

Implementation summary - the following was changed / added / removed:

  • Use bullet points here

Notes

Any special considerations, workarounds, or follow-up work to note?

  • Use bullet points here

@jirhiker jirhiker marked this pull request as draft November 14, 2025 22:03

@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.

ℹ️ 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".

Comment thread tests/features/steps/well-inventory-csv.py Outdated
@codecov-commenter

codecov-commenter commented Nov 14, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 43.57035% with 373 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
api/well_inventory.py 14.63% 210 Missing ⚠️
schemas/well_inventory.py 61.57% 83 Missing ⚠️
services/thing_helper.py 6.75% 69 Missing ⚠️
schemas/thing.py 65.00% 7 Missing ⚠️
api/lexicon.py 33.33% 2 Missing ⚠️
schemas/__init__.py 71.42% 2 Missing ⚠️
Files with missing lines Coverage Δ
constants.py 100.00% <100.00%> (ø)
core/enums.py 100.00% <100.00%> (ø)
core/initializers.py 88.23% <100.00%> (+0.28%) ⬆️
db/__init__.py 98.03% <100.00%> (ø)
db/aquifer_system.py 100.00% <100.00%> (ø)
db/contact.py 100.00% <100.00%> (ø)
db/data_provenance.py 93.33% <100.00%> (ø)
db/geologic_formation.py 100.00% <100.00%> (ø)
db/group.py 100.00% <100.00%> (ø)
db/permission_history.py 95.83% <100.00%> (ø)
... and 17 more

Comment thread api/well_inventory.py Fixed

@jacob-a-brown jacob-a-brown 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.

Because a number of updates/changed from BDMS-221 and BDMS-227 will influence the import of these data should we wait for those two to get merged before this PR? So that necessary updates/refactors can occur

Comment thread api/well_inventory.py Outdated
Comment thread api/well_inventory.py Outdated
Comment thread api/well_inventory.py Outdated
Comment thread api/well_inventory.py Outdated
Comment thread api/well_inventory.py Outdated
@jirhiker jirhiker changed the title Well inventory csv Feature Tests NO TICKET: Well inventory csv Feature Tests Nov 18, 2025

@chasetmartin chasetmartin left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is looking great. The updates to the feature file based on AMP feedback should be relatively straightforward: 2 possible contacts and a few additional notes fields.

Comment thread api/well_inventory.py Fixed
Copilot AI review requested due to automatic review settings February 7, 2026 14:28

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 82 out of 86 changed files in this pull request and generated 5 comments.

Comment thread tests/test_well_inventory.py Outdated
Comment thread schemas/thing.py Outdated
Comment thread api/ogc/features.py
Comment thread services/well_inventory_csv.py Outdated
Comment thread api/well_inventory.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings February 7, 2026 21:13
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

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 82 out of 86 changed files in this pull request and generated 6 comments.

Comment thread services/well_inventory_csv.py Outdated
Comment thread tests/test_well_inventory.py
Comment thread tests/test_well_inventory.py
Comment thread transfers/tester.py
# See the License for the specific language governing permissions and
# limitations under the License.
# ===============================================================================
from transfers.util import get_transferable_wells, read_csv

Copilot AI Feb 7, 2026

Copy link

Choose a reason for hiding this comment

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

This appears to be an ad-hoc analysis script committed under the production transfers/ package. If it’s intended for one-off/interactive use, consider moving it to a scripts/ (or similar) directory to avoid it being treated as library code, and to reduce long-term maintenance surface in the transfers module.

Copilot uses AI. Check for mistakes.
Comment thread transfers/tester.py
Comment thread transfers/tester.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings February 7, 2026 21:26

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 82 out of 86 changed files in this pull request and generated 5 comments.

Comment thread schemas/thing.py
Comment thread schemas/well_inventory.py Outdated
Comment on lines +224 to +228
assert "datalogger_installation_status" in context.water_well_data
assert "open_status" in context.water_well_data
assert (
context.water_well_data["is_suitable_for_datalogger"]
== context.objects["wells"][0].is_suitable_for_datalogger
context.water_well_data["datalogger_installation_status"]
== context.objects["wells"][0].datalogger_installation_status

Copilot AI Feb 7, 2026

Copy link

Choose a reason for hiding this comment

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

This step asserts datalogger_installation_status, but the rest of the PR (e.g. Thing.datalogger_suitability_status property and OGC feature mapping) uses datalogger_suitability_status. Unless the API/ORM actually exposes datalogger_installation_status, this will fail. Align the test to the implemented field/property name.

Copilot uses AI. Check for mistakes.
Comment thread transfers/tester.py
Comment thread transfers/tester.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings February 7, 2026 22:57

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 82 out of 86 changed files in this pull request and generated 5 comments.

"well_construction_method_source",
]
)
well_data = data.model_dump(exclude=EXCLUDED_FIELDS)

Copilot AI Feb 7, 2026

Copy link

Choose a reason for hiding this comment

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

pydantic.BaseModel.model_dump(exclude=...) expects a set/dict include-exclude structure (Pydantic v2 IncEx), not a list. Passing a list can raise a type error depending on the runtime path. Consider defining EXCLUDED_FIELDS as a set[str] (or using exclude=set(EXCLUDED_FIELDS)) to ensure compatibility.

Suggested change
well_data = data.model_dump(exclude=EXCLUDED_FIELDS)
well_data = data.model_dump(exclude=set(EXCLUDED_FIELDS))

Copilot uses AI. Check for mistakes.
Comment thread api/well_inventory.py
Comment on lines +58 to +61
# router = APIRouter(prefix="/well-inventory-csv")


# @router.post("")

Copilot AI Feb 7, 2026

Copy link

Choose a reason for hiding this comment

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

The entire API implementation is commented out, so /well-inventory-csv will not be registered and the Behave tests that POST to that endpoint will fail. Implement and export the FastAPI router (or delete the feature/steps that assume it exists) so the endpoint is actually available.

Copilot uses AI. Check for mistakes.
Comment thread db/group.py
class Group(Base, AutoBaseMixin, ReleaseMixin):
# --- Column Definitions ---
name: Mapped[str] = mapped_column(String(100), nullable=False, unique=True)
name: Mapped[str] = mapped_column(String(100), nullable=False)

Copilot AI Feb 7, 2026

Copy link

Choose a reason for hiding this comment

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

This changes the DB uniqueness rules for group (from unique name to composite unique (name, group_type)), but this PR doesn’t include an Alembic migration to drop the old constraint and add the new one. Without a migration the runtime schema will drift and deployments/tests that rely on migrations will fail. Add an Alembic migration that (1) drops the previous unique constraint on name (if present) and (2) creates uq_group_name_type, accounting for existing data.

Copilot uses AI. Check for mistakes.
Comment thread services/well_inventory_csv.py Outdated
Comment thread tests/features/well-inventory-csv.feature Outdated
jirhiker and others added 3 commits February 8, 2026 10:09
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings February 7, 2026 23:19

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 82 out of 86 changed files in this pull request and generated 3 comments.

Comment thread api/well_inventory.py
Comment on lines +58 to +62
# router = APIRouter(prefix="/well-inventory-csv")


# @router.post("")
# async def well_inventory_csv(

Copilot AI Feb 7, 2026

Copy link

Choose a reason for hiding this comment

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

This module is entirely commented out, so the /well-inventory-csv endpoint won’t exist at runtime. The Behave steps added in this PR post to /well-inventory-csv, so those feature tests will fail unless the router and handler are restored (and the router is included in the main FastAPI app).

Copilot uses AI. Check for mistakes.
elevation_ft = float(model.elevation_ft)
elevation_m = convert_ft_to_m(elevation_ft)

loc = Location(

Copilot AI Feb 7, 2026

Copy link

Choose a reason for hiding this comment

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

The CSV row contains elevation_method, and downstream tests in this PR assert location.elevation_method equals the CSV value. _make_location currently sets only point and elevation. If Location has an elevation_method column (as the tests imply), it needs to be persisted on the Location record (and/or the tests should be updated to validate DataProvenance instead).

Suggested change
loc = Location(
elevation=elevation_m,
elevation_method=model.elevation_method,

Copilot uses AI. Check for mistakes.
Comment thread core/lexicon.json
@@ -221,7 +221,7 @@
"description": null
},
{

Copilot AI Feb 7, 2026

Copy link

Choose a reason for hiding this comment

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

Renaming the lexicon category from origin_source to origin_type is a breaking change for any existing DB-seeded lexicon data and any code expecting the old category name. This needs an accompanying migration/seed-update path (or backward-compatible aliasing) to ensure environments with an existing lexicon table don’t fail when building enums or validating lexicon terms.

Suggested change
{
{
"name": "origin_source",
"description": null
},
{

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings February 8, 2026 00:40
@jirhiker jirhiker merged commit 96ecb5b into staging Feb 8, 2026
3 checks passed

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 84 out of 88 changed files in this pull request and generated 8 comments.

Comment thread api/well_inventory.py
Comment on lines +58 to +66
# router = APIRouter(prefix="/well-inventory-csv")


# @router.post("")
# async def well_inventory_csv(
# user: amp_editor_dependency,
# session: session_dependency,
# file: UploadFile = File(...),
# ):

Copilot AI Feb 8, 2026

Copy link

Choose a reason for hiding this comment

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

The entire /well-inventory-csv API router and handler are commented out, but the Behave steps post to /well-inventory-csv. As-is, this will return 404 and break feature tests; please implement the actual APIRouter route (or remove the feature steps) and ensure the router is included in the app.

Copilot uses AI. Check for mistakes.
Comment thread schemas/well_inventory.py
Comment on lines +26 to +29
validate_email,
AfterValidator,
field_validator,
)

Copilot AI Feb 8, 2026

Copy link

Choose a reason for hiding this comment

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

Importing validate_email directly from pydantic is not reliable (and commonly fails in Pydantic v2 where it’s not exported from the top-level). Use EmailStr for the field type or import the validator from the supported module (e.g., pydantic.networks) to avoid runtime ImportError.

Suggested change
validate_email,
AfterValidator,
field_validator,
)
AfterValidator,
field_validator,
)
from pydantic.networks import validate_email

Copilot uses AI. Check for mistakes.

loc = Location(
point=transformed_point.wkt,
elevation=elevation_m,

Copilot AI Feb 8, 2026

Copy link

Choose a reason for hiding this comment

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

The import creates Location records without setting elevation_method, but tests/test_well_inventory.py asserts location.elevation_method == file_content['elevation_method']. Either populate Location.elevation_method here (if it’s a column), or adjust the test to validate the intended provenance field instead.

Suggested change
elevation=elevation_m,
elevation=elevation_m,
elevation_method=model.elevation_method,

Copilot uses AI. Check for mistakes.
Comment on lines +224 to +229
assert "datalogger_installation_status" in context.water_well_data
assert "open_status" in context.water_well_data
assert (
context.water_well_data["is_suitable_for_datalogger"]
== context.objects["wells"][0].is_suitable_for_datalogger
context.water_well_data["datalogger_installation_status"]
== context.objects["wells"][0].datalogger_installation_status
)

Copilot AI Feb 8, 2026

Copy link

Choose a reason for hiding this comment

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

The codebase surfaces the computed field as datalogger_suitability_status (see db/thing.py and schemas/thing.py), but this step asserts datalogger_installation_status and accesses Thing.datalogger_installation_status (which doesn’t appear in the model changes). Align the step to the actual API/property name (datalogger_suitability_status) to prevent failing feature tests.

Copilot uses AI. Check for mistakes.
Comment on lines +79 to +95
EXCLUDED_FIELDS = [
"location_id",
"group_id",
"well_purposes",
"well_casing_materials",
"measuring_point_height",
"measuring_point_description",
"well_completion_date_source",
"well_construction_method_source",
"well_depth_source",
"alternate_ids",
"monitoring_frequencies",
"notes",
"is_suitable_for_datalogger",
"is_open",
"well_status",
]

Copilot AI Feb 8, 2026

Copy link

Choose a reason for hiding this comment

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

Pydantic v2 model_dump(exclude=...) expects a set/dict-style include/exclude structure; passing a plain list can raise a type error depending on the exact Pydantic version. To make this robust, define EXCLUDED_FIELDS as a set[str] (or a dict) before passing it to model_dump.

Copilot uses AI. Check for mistakes.
Comment on lines 505 to +508
rebuild = False
# rebuild = True
erase_data = True
erase_data = False
if rebuild:
erase_and_rebuild_db()
_drop_and_rebuild_db()

Copilot AI Feb 8, 2026

Copy link

Choose a reason for hiding this comment

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

Hard-coding rebuild = True makes every Behave run drop and rebuild the database, which is slow and potentially destructive for local workflows. Since .env.example introduces REBUILD_DB, this should be controlled via environment variables (e.g., default to no rebuild, enable in CI when needed).

Copilot uses AI. Check for mistakes.
Comment on lines +457 to +463
def test_upload_headers_only(self):
"""Upload fails when CSV has headers but no data rows."""
file_path = Path("tests/features/data/well-inventory-no-data-headers.csv")
if file_path.exists():
result = well_inventory_csv(file_path)
assert result.exit_code == 1
assert "No data rows found" in result.stderr

Copilot AI Feb 8, 2026

Copy link

Choose a reason for hiding this comment

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

Several tests are effectively skipped when fixture files are missing (if file_path.exists(): ...). This can silently reduce coverage and hide regressions. Prefer asserting the fixture exists (fail fast) or generate the CSV content in the test using tmp_path so the test always executes.

Copilot uses AI. Check for mistakes.
Comment on lines +629 to +635
permission = _make_well_permission(
well=well,
contact=contact_for_permissions,
permission_type=permission_type,
permission_allowed=permission_allowed,
start_date=model.date_time.date(),
)

Copilot AI Feb 8, 2026

Copy link

Choose a reason for hiding this comment

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

_make_well_permission raises PydanticStyleException when permissions are provided but no contact exists. _import_well_inventory_csv only catches ValueError and DatabaseError, so this exception would bubble out and abort the whole import unexpectedly. Handle PydanticStyleException (or convert this case into a row-level validation error) so the import returns consistent validation_errors output.

Suggested change
permission = _make_well_permission(
well=well,
contact=contact_for_permissions,
permission_type=permission_type,
permission_allowed=permission_allowed,
start_date=model.date_time.date(),
)
try:
permission = _make_well_permission(
well=well,
contact=contact_for_permissions,
permission_type=permission_type,
permission_allowed=permission_allowed,
start_date=model.date_time.date(),
)
except PydanticStyleException as exc:
# Convert to a ValueError so the import logic can treat this as
# a row-level validation error instead of aborting the import.
raise ValueError(str(exc)) from exc

Copilot uses AI. Check for mistakes.
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.

7 participants