Skip to content

Commit e768d8a

Browse files
committed
fix(contact): Make contact role and type non-nullable
Each contact should have a role and contact_type
1 parent 3ad295a commit e768d8a

12 files changed

+50
-97
lines changed

alembic/versions/p9c1d2e3f4a5_make_contact_role_nullable.py

Lines changed: 0 additions & 29 deletions
This file was deleted.

alembic/versions/q0d1e2f3a4b5_make_contact_type_nullable.py

Lines changed: 0 additions & 35 deletions
This file was deleted.

db/contact.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515
# ===============================================================================
16-
from typing import List, TYPE_CHECKING, Optional
16+
from typing import List, TYPE_CHECKING
1717

1818
from sqlalchemy import Integer, ForeignKey, String, UniqueConstraint
1919
from sqlalchemy.ext.associationproxy import association_proxy, AssociationProxy
@@ -49,8 +49,8 @@ class ThingContactAssociation(Base, AutoBaseMixin):
4949
class Contact(Base, AutoBaseMixin, ReleaseMixin, NotesMixin):
5050
name: Mapped[str] = mapped_column(String(100), nullable=True)
5151
organization: Mapped[str] = lexicon_term(nullable=True)
52-
role: Mapped[Optional[str]] = lexicon_term(nullable=True)
53-
contact_type: Mapped[Optional[str]] = lexicon_term(nullable=True)
52+
role: Mapped[str] = lexicon_term(nullable=False)
53+
contact_type: Mapped[str] = lexicon_term(nullable=False)
5454

5555
# primary keys of the nm aquifer tables from which the contacts originate
5656
nma_pk_owners: Mapped[str] = mapped_column(String(100), nullable=True)

schemas/contact.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,8 @@ class CreateContact(BaseCreateModel, ValidateContact):
150150
thing_id: int
151151
name: str | None = None
152152
organization: str | None = None
153-
role: Role | None = None
154-
contact_type: ContactType | None = None
153+
role: Role
154+
contact_type: ContactType
155155
nma_pk_owners: str | None = None
156156
# description: str | None = None
157157
# email: str | None = None
@@ -218,8 +218,8 @@ class ContactResponse(BaseResponseModel):
218218

219219
name: str | None
220220
organization: str | None
221-
role: Role | None
222-
contact_type: ContactType | None
221+
role: Role
222+
contact_type: ContactType
223223
incomplete_nma_phones: List[str] = []
224224
emails: List[EmailResponse] = []
225225
phones: List[PhoneResponse] = []

schemas/well_inventory.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,8 @@ def validate_model(self):
375375
key = f"contact_{jdx}"
376376
name = getattr(self, f"{key}_name")
377377
organization = getattr(self, f"{key}_organization")
378+
role = getattr(self, f"{key}_role")
379+
contact_type = getattr(self, f"{key}_type")
378380

379381
# Treat name or organization as contact data too, so bare contacts
380382
# still go through the same cross-field rules as fully populated ones.
@@ -399,6 +401,14 @@ def validate_model(self):
399401
raise ValueError(
400402
f"At least one of {key}_name or {key}_organization must be provided"
401403
)
404+
if not role:
405+
raise ValueError(
406+
f"{key}_role is required when contact data is provided"
407+
)
408+
if not contact_type:
409+
raise ValueError(
410+
f"{key}_type is required when contact data is provided"
411+
)
402412
for idx in (1, 2):
403413
if any(getattr(self, f"{key}_address_{idx}_{a}") for a in all_attrs):
404414
if not all(

services/well_inventory_csv.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -353,21 +353,12 @@ def _make_contact(model: WellInventoryRow, well: Thing, idx) -> dict:
353353
"address_type": address_type,
354354
}
355355
)
356-
357356
return {
358357
"thing_id": well.id,
359358
"name": name,
360359
"organization": organization,
361-
"role": (
362-
getattr(model, f"contact_{idx}_role").value
363-
if hasattr(getattr(model, f"contact_{idx}_role"), "value")
364-
else getattr(model, f"contact_{idx}_role")
365-
),
366-
"contact_type": (
367-
getattr(model, f"contact_{idx}_type").value
368-
if hasattr(getattr(model, f"contact_{idx}_type"), "value")
369-
else getattr(model, f"contact_{idx}_type")
370-
),
360+
"role": getattr(model, f"contact_{idx}_role"),
361+
"contact_type": getattr(model, f"contact_{idx}_type"),
371362
"emails": emails,
372363
"phones": phones,
373364
"addresses": addresses,
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
project,well_name_point_id,site_name,date_time,field_staff,utm_easting,utm_northing,utm_zone,elevation_ft,elevation_method,measuring_point_height_ft,field_staff_2,field_staff_3,contact_1_name,contact_1_organization,contact_1_role,contact_1_type,contact_1_phone_1,contact_1_phone_1_type,contact_1_phone_2,contact_1_phone_2_type,contact_1_email_1,contact_1_email_1_type,contact_1_email_2,contact_1_email_2_type,contact_1_address_1_line_1,contact_1_address_1_line_2,contact_1_address_1_type,contact_1_address_1_state,contact_1_address_1_city,contact_1_address_1_postal_code,contact_1_address_2_line_1,contact_1_address_2_line_2,contact_1_address_2_type,contact_1_address_2_state,contact_1_address_2_city,contact_1_address_2_postal_code,contact_2_name,contact_2_organization,contact_2_role,contact_2_type,contact_2_phone_1,contact_2_phone_1_type,contact_2_phone_2,contact_2_phone_2_type,contact_2_email_1,contact_2_email_1_type,contact_2_email_2,contact_2_email_2_type,contact_2_address_1_line_1,contact_2_address_1_line_2,contact_2_address_1_type,contact_2_address_1_state,contact_2_address_1_city,contact_2_address_1_postal_code,contact_2_address_2_line_1,contact_2_address_2_line_2,contact_2_address_2_type,contact_2_address_2_state,contact_2_address_2_city,contact_2_address_2_postal_code,directions_to_site,specific_location_of_well,repeat_measurement_permission,sampling_permission,datalogger_installation_permission,public_availability_acknowledgement,result_communication_preference,contact_special_requests_notes,ose_well_record_id,date_drilled,completion_source,total_well_depth_ft,historic_depth_to_water_ft,depth_source,well_pump_type,well_pump_depth_ft,is_open,datalogger_possible,casing_diameter_ft,measuring_point_description,well_purpose,well_purpose_2,well_status,monitoring_frequency,sampling_scenario_notes,well_measuring_notes,sample_possible
2-
Middle Rio Grande Groundwater Monitoring,MRG-001_MP1,Smith Farm Domestic Well,2025-02-15T10:30:00,A Lopez,250000,4000000,13N,5250,Survey-grade GPS,1.5,B Chen,,John Smith,NMBGMR,,Primary,505-555-0101,Primary,,,john.smith@example.com,Primary,,,123 County Rd 7,,Mailing,NM,Los Lunas,87031,,,,,,,Maria Garcia,NMBGMR,Principal Investigator,Secondary,505-555-0123,Home,,,maria.garcia@mrgcd.nm.gov,Work,,,1931 2nd St SW,Suite 200,Mailing,NM,Albuquerque,87102,,,,,,,Gate off County Rd 7 0.4 miles south of canal crossing,Domestic well in pump house east of residence,True,True,True,True,email,Call before visits during irrigation season,OSE-123456,2010-06-15,Interpreted fr geophys logs by source agency,280,45,"Memory of owner, operator, driller",Submersible,200,True,True,0.5,Top of steel casing inside pump house marked with orange paint,Domestic,,"Active, pumping well",Biannual,Sample only when pump has been off more than 12 hours,Measure before owner starts irrigation,True
2+
Middle Rio Grande Groundwater Monitoring,MRG-001_MP1,Smith Farm Domestic Well,2025-02-15T10:30:00,A Lopez,250000,4000000,13N,5250,Survey-grade GPS,1.5,B Chen,,John Smith No Role,NMBGMR,,Primary,505-555-0101,Primary,,,john.smith@example.com,Primary,,,123 County Rd 7,,Mailing,NM,Los Lunas,87031,,,,,,,Maria Garcia,NMBGMR,Principal Investigator,Secondary,505-555-0123,Home,,,maria.garcia@mrgcd.nm.gov,Work,,,1931 2nd St SW,Suite 200,Mailing,NM,Albuquerque,87102,,,,,,,Gate off County Rd 7 0.4 miles south of canal crossing,Domestic well in pump house east of residence,True,True,True,True,email,Call before visits during irrigation season,OSE-123456,2010-06-15,Interpreted fr geophys logs by source agency,280,45,"Memory of owner, operator, driller",Submersible,200,True,True,0.5,Top of steel casing inside pump house marked with orange paint,Domestic,,"Active, pumping well",Biannual,Sample only when pump has been off more than 12 hours,Measure before owner starts irrigation,True
33
Middle Rio Grande Groundwater Monitoring,MRG-003_MP1,Old Orchard Well,2025-01-20T09:00:00,B Chen,250000,4000000,13N,5320,Global positioning system (GPS),1.8,,,David Emily,NMBGMR,Biologist,Primary,505-555-0303,Work,,,emily.davis@example.org,Work,,,78 Orchard Ln,,Mailing,NM,Los Lunas,87031,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,From Main St turn east on Orchard Ln well house at dead end,Abandoned irrigation well in small cinderblock building,False,False,False,True,phone,Owner prefers weekday visits,,1965-04-10,From driller's log or well report,350,60,"Reported by person other than driller owner agency",Jet,280,False,False,0.75,Top of steel casing under removable hatch use fixed reference mark,Irrigation,,Abandoned,Annual,Sampling not permitted water level only when owner present,Well house can be locked coordinate ahead,False
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
project,well_name_point_id,site_name,date_time,field_staff,utm_easting,utm_northing,utm_zone,elevation_ft,elevation_method,measuring_point_height_ft,field_staff_2,field_staff_3,contact_1_name,contact_1_organization,contact_1_role,contact_1_type,contact_1_phone_1,contact_1_phone_1_type,contact_1_phone_2,contact_1_phone_2_type,contact_1_email_1,contact_1_email_1_type,contact_1_email_2,contact_1_email_2_type,contact_1_address_1_line_1,contact_1_address_1_line_2,contact_1_address_1_type,contact_1_address_1_state,contact_1_address_1_city,contact_1_address_1_postal_code,contact_1_address_2_line_1,contact_1_address_2_line_2,contact_1_address_2_type,contact_1_address_2_state,contact_1_address_2_city,contact_1_address_2_postal_code,contact_2_name,contact_2_organization,contact_2_role,contact_2_type,contact_2_phone_1,contact_2_phone_1_type,contact_2_phone_2,contact_2_phone_2_type,contact_2_email_1,contact_2_email_1_type,contact_2_email_2,contact_2_email_2_type,contact_2_address_1_line_1,contact_2_address_1_line_2,contact_2_address_1_type,contact_2_address_1_state,contact_2_address_1_city,contact_2_address_1_postal_code,contact_2_address_2_line_1,contact_2_address_2_line_2,contact_2_address_2_type,contact_2_address_2_state,contact_2_address_2_city,contact_2_address_2_postal_code,directions_to_site,specific_location_of_well,repeat_measurement_permission,sampling_permission,datalogger_installation_permission,public_availability_acknowledgement,result_communication_preference,contact_special_requests_notes,ose_well_record_id,date_drilled,completion_source,total_well_depth_ft,historic_depth_to_water_ft,depth_source,well_pump_type,well_pump_depth_ft,is_open,datalogger_possible,casing_diameter_ft,measuring_point_description,well_purpose,well_purpose_2,well_status,monitoring_frequency,sampling_scenario_notes,well_measuring_notes,sample_possible
2-
Middle Rio Grande Groundwater Monitoring,MRG-001_MP1,Smith Farm Domestic Well,2025-02-15T10:30:00,A Lopez,250000,4000000,13N,5250,Survey-grade GPS,1.5,B Chen,,John Smith,NMBGMR,Owner,,505-555-0101,Primary,,,john.smith@example.com,Primary,,,123 County Rd 7,,Mailing,NM,Los Lunas,87031,,,,,,,Maria Garcia,NMBGMR,Principal Investigator,Secondary,505-555-0123,Home,,,maria.garcia@mrgcd.nm.gov,Work,,,1931 2nd St SW,Suite 200,Mailing,NM,Albuquerque,87102,,,,,,,Gate off County Rd 7 0.4 miles south of canal crossing,Domestic well in pump house east of residence,True,True,True,True,email,Call before visits during irrigation season,OSE-123456,2010-06-15,From driller's log or well report,280,45,"Memory of owner, operator, driller",submersible,200,True,True,0.5,Top of steel casing inside pump house marked with orange paint,Domestic,,"Active, pumping well",Biannual,Sample only when pump has been off more than 12 hours,Measure before owner starts irrigation,True
2+
Middle Rio Grande Groundwater Monitoring,MRG-001_MP1,Smith Farm Domestic Well,2025-02-15T10:30:00,A Lopez,250000,4000000,13N,5250,Survey-grade GPS,1.5,B Chen,,John Smith No Type,NMBGMR,Owner,,505-555-0101,Primary,,,john.smith@example.com,Primary,,,123 County Rd 7,,Mailing,NM,Los Lunas,87031,,,,,,,Maria Garcia,NMBGMR,Principal Investigator,Secondary,505-555-0123,Home,,,maria.garcia@mrgcd.nm.gov,Work,,,1931 2nd St SW,Suite 200,Mailing,NM,Albuquerque,87102,,,,,,,Gate off County Rd 7 0.4 miles south of canal crossing,Domestic well in pump house east of residence,True,True,True,True,email,Call before visits during irrigation season,OSE-123456,2010-06-15,From driller's log or well report,280,45,"Memory of owner, operator, driller",submersible,200,True,True,0.5,Top of steel casing inside pump house marked with orange paint,Domestic,,"Active, pumping well",Biannual,Sample only when pump has been off more than 12 hours,Measure before owner starts irrigation,True
33
Middle Rio Grande Groundwater Monitoring,MRG-003_MP1,Old Orchard Well,2025-01-20T09:00:00,B Chen,250000,4000000,13N,5320,Global positioning system (GPS),1.8,,,Emily Davis,NMBGMR,Biologist,Primary,505-555-0303,Work,,,emily.davis@example.org,Work,,,78 Orchard Ln,,Mailing,NM,Los Lunas,87031,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,From Main St turn east on Orchard Ln well house at dead end,Abandoned irrigation well in small cinderblock building,False,False,False,True,phone,Owner prefers weekday visits,,1965-04-10,From driller's log or well report,350,60,"From driller's log or well report",Line Shaft,280,False,False,0.75,Top of steel casing under removable hatch use fixed reference mark,Irrigation,,Abandoned,Annual,Sampling not permitted water level only when owner present,Well house can be locked coordinate ahead,False

tests/features/steps/well-inventory-csv-given.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def _set_file_content(context: Context, name):
2929

3030
def _set_file_content_from_path(context: Context, path: Path, name: str | None = None):
3131
context.file_path = path
32+
print(context.file_path)
3233
import hashlib
3334

3435
context.file_name = name or path.name

tests/features/steps/well-inventory-csv-validation-error.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,14 +186,27 @@ def step_then_the_response_includes_a_validation_error_indicating_the_invalid_em
186186
_handle_validation_error(context, expected_errors)
187187

188188

189+
@then(
190+
'the response includes a validation error indicating the missing "contact_role" value'
191+
)
192+
def step_step_step_8(context):
193+
expected_errors = [
194+
{
195+
"field": "composite field error",
196+
"error": "Value error, contact_1_role is required when contact data is provided",
197+
}
198+
]
199+
_handle_validation_error(context, expected_errors)
200+
201+
189202
@then(
190203
'the response includes a validation error indicating the missing "contact_type" value'
191204
)
192205
def step_step_step_8(context):
193206
expected_errors = [
194207
{
195208
"field": "composite field error",
196-
"error": "Value error, contact_1_type is required when contact fields are provided",
209+
"error": "Value error, contact_1_type is required when contact data is provided",
197210
}
198211
]
199212
_handle_validation_error(context, expected_errors)

0 commit comments

Comments
 (0)