Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
d549947
feat: add missing fields
ksmuczynski Sep 9, 2025
3bc45f0
feat: add missing fields
ksmuczynski Sep 9, 2025
8936a2b
feat: add missing fields to the CREATE schema
ksmuczynski Sep 9, 2025
011fa73
feat: add missing fields to the RESPONSE schema
ksmuczynski Sep 9, 2025
fa95778
feat: add missing fields to the RESPONSE schema
ksmuczynski Sep 9, 2025
1f796f0
feat: add missing fields to the CREATE schema
ksmuczynski Sep 9, 2025
75c4782
refactor: relocate `notes` field so it matches the field order in th…
ksmuczynski Sep 9, 2025
afe97ab
feat: add missing fields to the RESPONSE schema
ksmuczynski Sep 9, 2025
f83b127
feat: add missing fields to the UPDATE schema
ksmuczynski Sep 9, 2025
1f359eb
refactor: remove `county` and `quad_name` fields from UPDATE schema.
ksmuczynski Sep 9, 2025
7ccbb48
refactor: remove `state`, `county`, `quad_name` fields from CREATE sc…
ksmuczynski Sep 9, 2025
956eb65
feat: add missing payload fields and `assert` statements to the POST …
ksmuczynski Sep 9, 2025
2ced402
refactor: reorder payload fields to match UPDATE schema
ksmuczynski Sep 9, 2025
af1f7bb
feat: add missing payload fields
ksmuczynski Sep 9, 2025
ed5f147
feat: add missing `assert` statements to PATCH test
ksmuczynski Sep 9, 2025
c987748
feat: add missing fields to location fixture in support of updating t…
ksmuczynski Sep 9, 2025
28071fa
feat: add missing `assert` statements to GET test
ksmuczynski Sep 9, 2025
4610105
feat: add missing fields to `make_location` function
ksmuczynski Sep 9, 2025
da0bfa1
refactor: add note about the mapping of PointID to location.name
ksmuczynski Sep 9, 2025
5ac0efa
Formatting changes
ksmuczynski Sep 9, 2025
b7c8f8f
refactor: remove `coordiante_accuracy_unit` field from the database m…
ksmuczynski Sep 10, 2025
e86a0b0
feat: add missing fields to `test_get_location_by_id` function.
ksmuczynski Sep 10, 2025
f5f4af2
refactor: update `county` name to a valid lexicon term.
ksmuczynski Sep 10, 2025
263397e
Merge branch 'pre-production' into location_model_update_kas
ksmuczynski Sep 10, 2025
7bdf53d
refactor: update lexicon-referenced fields with valid lexicon values
ksmuczynski Sep 11, 2025
c17ecb3
refactor: populate db credentials file for docker
ksmuczynski Sep 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
DB_DRIVER=postgres

POSTGRES_USER=
POSTGRES_PASSWORD=
POSTGRES_USER=admin
POSTGRES_PASSWORD=password
POSTGRES_DB=

# asset storage
Expand Down
5 changes: 5 additions & 0 deletions db/location.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ class Location(Base, AutoBaseMixin, ReleaseMixin):
quad_name: Mapped[str] = mapped_column(String(100), nullable=True)
notes: Mapped[str] = mapped_column(Text, nullable=True)
nma_notes_location: Mapped[str] = mapped_column(Text, nullable=True)
nma_coordinate_notes: Mapped[str] = mapped_column(Text, nullable=True)
elevation_accuracy: Mapped[float] = mapped_column(nullable=True)
elevation_method: Mapped[str] = lexicon_term(nullable=True)
coordinate_accuracy: Mapped[float] = mapped_column(nullable=True)
coordinate_method: Mapped[str] = lexicon_term(nullable=True)

# --- Relationship Definitions ---
thing_associations: Mapped[list["LocationThingAssociation"]] = relationship(
Expand Down
3 changes: 3 additions & 0 deletions db/thing.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@
from sqlalchemy.orm import relationship, mapped_column, Mapped
from sqlalchemy_utils import TSVectorType

from uuid import UUID

from db import lexicon_term
from db.base import AutoBaseMixin, Base, ReleaseMixin


class Thing(Base, AutoBaseMixin, ReleaseMixin):

name = mapped_column(String(255), nullable=False)
description = mapped_column(String(500))
thing_type = lexicon_term(nullable=True)
Expand Down
21 changes: 19 additions & 2 deletions schemas/location.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ class CreateLocation(BaseCreateModel):
notes: str | None = None
point: str # point is required and should be in WKT format
release_status: str | None = "draft"
elevation_accuracy: float | None = None
elevation_method: str | None = None
coordinate_accuracy: float | None = None
coordinate_method: str | None = None

@classmethod
@field_validator("point")
Expand All @@ -60,9 +64,17 @@ class LocationResponse(BaseResponseModel):
Response schema for sample location details.
"""

name: str | None = None
name: str | None
notes: str | None
point: str
release_status: str
release_status: str | None
elevation_accuracy: float | None
elevation_method: str | None
coordinate_accuracy: float | None
coordinate_method: str | None
state: str | None
county: str | None
quad_name: str | None

@field_validator("point", mode="before")
def point_to_wkt(cls, value):
Expand Down Expand Up @@ -94,6 +106,11 @@ class UpdateLocation(BaseUpdateModel):
name: str | None = None
notes: str | None = None
point: str | None = None
release_status: str | None = None
elevation_accuracy: float | None = None
elevation_method: str | None = None
coordinate_accuracy: float | None = None
coordinate_method: str | None = None


# ============= EOF =============================================
12 changes: 11 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,17 @@
def location():
with session_ctx() as session:
loc = Location(
name="first location", release_status="draft", point="POINT(0 0 0)"
name="first location",
notes="these are some test notes",
point="POINT(0 0 0)",
release_status="draft",
elevation_accuracy=100,
elevation_method="Survey-grade GPS",
coordinate_accuracy=50,
coordinate_method="GPS, uncorrected",
state="New Mexico",
county="Socorro",
quad_name="some NM quad",
)
session.add(loc)
session.commit()
Expand Down
39 changes: 37 additions & 2 deletions tests/test_location.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,13 @@ def override_dependencies_fixture():
def test_add_location():
payload = {
"name": "test location",
"notes": "these are some test notes",
"point": "POINT Z (10.1 10.1 0)",
"release_status": "draft",
"elevation_accuracy": 1.0,
"elevation_method": "Survey-grade GPS",
"coordinate_accuracy": 5.0,
"coordinate_method": "GPS, uncorrected",
}
response = client.post("/location", json=payload)

Expand All @@ -53,8 +58,13 @@ def test_add_location():
assert "id" in data
assert "created_at" in data
assert data["name"] == payload["name"]
assert data["notes"] == payload["notes"]
assert data["point"] == payload["point"]
assert data["release_status"] == payload["release_status"]
assert data["elevation_accuracy"] == payload["elevation_accuracy"]
assert data["elevation_method"] == payload["elevation_method"]
assert data["coordinate_accuracy"] == payload["coordinate_accuracy"]
assert data["coordinate_method"] == payload["coordinate_method"]

# cleanup after test
cleanup_post_test(Location, data["id"])
Expand All @@ -65,17 +75,27 @@ def test_add_location():

def test_update_location(location):
payload = {
"name": "patched name",
"notes": "these are some patched notes",
"point": "POINT Z (10.1 20.2 0)",
"release_status": "draft",
"name": "patched name",
"elevation_accuracy": 2.0,
"elevation_method": "Survey-grade GPS",
"coordinate_accuracy": 10.0,
"coordinate_method": "GPS, uncorrected",
}
response = client.patch(f"/location/{location.id}", json=payload)
assert response.status_code == 200
data = response.json()
assert data["id"] == location.id
assert data["name"] == payload["name"]
assert data["notes"] == payload["notes"]
assert data["point"] == payload["point"]
assert data["release_status"] == payload["release_status"]
assert data["name"] == payload["name"]
assert data["elevation_accuracy"] == payload["elevation_accuracy"]
assert data["elevation_method"] == payload["elevation_method"]
assert data["coordinate_accuracy"] == payload["coordinate_accuracy"]
assert data["coordinate_method"] == payload["coordinate_method"]

# cleanup after test
cleanup_patch_test(Location, payload, location)
Expand Down Expand Up @@ -111,8 +131,16 @@ def test_get_locations(location):
"+00:00", "Z"
)
assert data["items"][0]["name"] == location.name
assert data["items"][0]["notes"] == location.notes
assert data["items"][0]["point"] == to_shape(location.point).wkt
assert data["items"][0]["release_status"] == location.release_status
assert data["items"][0]["elevation_accuracy"] == location.elevation_accuracy
assert data["items"][0]["elevation_method"] == location.elevation_method
assert data["items"][0]["coordinate_accuracy"] == location.coordinate_accuracy
assert data["items"][0]["coordinate_method"] == location.coordinate_method
assert data["items"][0]["state"] == location.state
assert data["items"][0]["county"] == location.county
assert data["items"][0]["quad_name"] == location.quad_name


def test_get_location_by_id(location):
Expand All @@ -124,6 +152,13 @@ def test_get_location_by_id(location):
assert data["name"] == location.name
assert data["point"] == to_shape(location.point).wkt
assert data["release_status"] == location.release_status
assert data["elevation_accuracy"] == location.elevation_accuracy
assert data["elevation_method"] == location.elevation_method
assert data["coordinate_accuracy"] == location.coordinate_accuracy
assert data["coordinate_method"] == location.coordinate_method
assert data["state"] == location.state
assert data["county"] == location.county
assert data["quad_name"] == location.quad_name


def test_get_sample_by_id_404_not_found(location):
Expand Down
13 changes: 8 additions & 5 deletions transfers/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,15 +207,18 @@ def make_location(row: pd.Series) -> Location:
# created_at = row.DateCreated

location = Location(
# nma_pk_location=row.LocationId,
nma_pk_location=row.LocationId,
# TODO: determine if PointID should map to location.name or thing.name or if the Location table needs a name field at all.
name=row.PointID,
point=transformed_point.wkt,
release_status="public" if row.PublicRelease else "private",
# elevation_accuracy=row.AltitudeAccuracy,
# elevation_method=row.AltitudeMethod,
elevation_accuracy=row.AltitudeAccuracy,
elevation_method=row.AltitudeMethod,
# created_at=created_at,
# point_accuracy=row.CoordinateAccuracy,
# point_method=row.CoordinateMethod,
coordinate_accuracy=row.CoordinateAccuracy,
coordinate_method=row.CoordinateMethod,
nma_coordinate_notes=row.CoordinateNotes,
nma_notes_location=row.LocationNotes,
Comment on lines +215 to +221

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.

I can update this when I merge your work with the lexicon updates, but now that we are not using lookup table codes I think we'll need to amend this section (and for other tables/fields that are lexicon/lookup tables) to get the MEANING from the LU tables. Otherwise they won't be found in the lexicon term table and we'll run into errors.

On that note, I'll wait to open a PR for lexicon so that I can take care of that in the transfer scripts where it is relevant.

)
return location

Expand Down
Loading