From 069771dadf6e61ed1aaa28f428791cc555a89d53 Mon Sep 17 00:00:00 2001 From: Bryson Spilman Date: Fri, 15 May 2026 13:28:24 -0700 Subject: [PATCH 01/12] CDA-103 - initial stubbed out ADR (draft) --- .../0009-location-kind-persistence.rst | 80 +++++++++++++++++++ docs/source/decisions/index.rst | 1 + 2 files changed, 81 insertions(+) create mode 100644 docs/source/decisions/0009-location-kind-persistence.rst diff --git a/docs/source/decisions/0009-location-kind-persistence.rst b/docs/source/decisions/0009-location-kind-persistence.rst new file mode 100644 index 0000000000..7791963ca7 --- /dev/null +++ b/docs/source/decisions/0009-location-kind-persistence.rst @@ -0,0 +1,80 @@ +##### +Location Kind Persistence and Metadata +##### + + +Summary +======= + +This ADR documents the issue where storing a Location with a set KIND does not always respect that KIND, often defaulting to ``SITE``, and discusses the implications of "marker" kinds and metadata retention. + + +Problem Statement +================= + +Currently, when a physical location is stored without an assigned kind, it defaults to ``SITE``. If a user explicitly changes the kind to ``PROJECT`` (or another specific kind), it is treated as a "marker" kind. The location endpoint then works off that particular marker kind. + +However, this transition can lead to loss of context or missing metadata. For example: +1. A location is stored as a ``SITE``. +2. A stream location is then stored for that ``SITE`` location. +3. If the location is subsequently changed to a ``PROJECT``, it becomes a "marker project" but "forgets" that it was also a stream location. + +The location endpoint currently lacks the ability to denote all kinds that a single location might embody, leading to incomplete metadata representation. + + +Proposed Goals +============== + +1. **Respect Explicit Kind**: Ensure that if a KIND is explicitly set during storage, it is preserved and respected by the system. +2. **Handle Marker Kinds**: Recognize and correctly handle "marker" kinds (like ``PROJECT``) without losing underlying location identity (like being a stream location). +3. **Identify Incomplete Metadata**: Provide a mechanism to identify which locations do not have all their expected metadata filled out. +4. **Metadata Density**: It is acceptable for some metadata to be missing or stubbed initially, provided there is a way to denote the state of the location's metadata. + + +Key Considerations +================== + +.. list-table:: + :header-rows: 1 + :widths: 20 25 55 + + * - Topic + - Decision/Observation + - Justification + * - Default Kind + - Defaults to ``SITE`` if unassigned. + - Maintains backwards compatibility and provides a sane default for physical locations. + * - Marker Kinds + - Kinds like ``PROJECT`` act as markers that certain endpoints (like the location endpoint) use for filtering. + - Allows specialized views of locations based on their primary functional role. + * - Kind Multiplicity + - Locations may need to support multiple kinds or at least retain metadata associated with previous kinds. + - Prevents "identity loss" when a location's primary marker is updated. + * - View Inclusion + - Should marker-only rows in tables like ``at_project`` be visible in general views? + - Open question: Depending on use case, we may or may not want to see these markers in general av_project views. + * - Stubbing + - Stubbing missing info is an acceptable short-term solution. + - Allows the API to remain functional while identifying where more detailed metadata is required. + + +Example Scenario +~~~~~~~~~~~~~~~~ + +* **Initial State**: Location ``LOC123`` is created as a ``SITE``. +* **Step 2**: ``LOC123`` is defined as a stream location (associating it with stream-specific metadata). +* **Step 3**: ``LOC123`` is updated to have a ``PROJECT`` kind. +* **Result**: The system now sees ``LOC123`` primarily as a Project marker, but the stream location metadata may be inaccessible or unassociated through standard location queries. + + +Decision Status +=============== + +(Status: proposed) + + +References +========== + +Related Types: ``cwms.cda.data.dto.Location``, ``cwms.cda.data.dto.CwmsIdLocationKind``, ``cwms.cda.data.dto.stream.StreamLocation`` +Issue/Discussion: [Internal Issue Tracking] diff --git a/docs/source/decisions/index.rst b/docs/source/decisions/index.rst index 0dc16c28f5..56942d9553 100644 --- a/docs/source/decisions/index.rst +++ b/docs/source/decisions/index.rst @@ -25,3 +25,4 @@ Some decisions may also be a proposal and marked appropriately. CDA Authorization Filtering <./0006-cda-authorization-filtering.md> Access Management Clients <./0007-access-management-clients.md> Timeseries CSV Format <./0008-timeseries-csv-format.rst> + Location Kind Persistence <./0009-location-kind-persistence.rst> From b298da80699eb2d3d65d3fbed696ac303eb9e306 Mon Sep 17 00:00:00 2001 From: Bryson Spilman Date: Thu, 28 May 2026 10:31:48 -0700 Subject: [PATCH 02/12] CDA-103 - updates to draft ADR --- .../0009-location-kind-persistence.rst | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/docs/source/decisions/0009-location-kind-persistence.rst b/docs/source/decisions/0009-location-kind-persistence.rst index 7791963ca7..25305691fd 100644 --- a/docs/source/decisions/0009-location-kind-persistence.rst +++ b/docs/source/decisions/0009-location-kind-persistence.rst @@ -6,7 +6,7 @@ Location Kind Persistence and Metadata Summary ======= -This ADR documents the issue where storing a Location with a set KIND does not always respect that KIND, often defaulting to ``SITE``, and discusses the implications of "marker" kinds and metadata retention. +This ADR documents the behavior and relationship between general location endpoints and kind-specific endpoints (e.g., Stream, Project), specifically addressing how storing a Location with a set KIND acts as a "marker" and the implications for metadata retention. Problem Statement @@ -22,13 +22,15 @@ However, this transition can lead to loss of context or missing metadata. For ex The location endpoint currently lacks the ability to denote all kinds that a single location might embody, leading to incomplete metadata representation. -Proposed Goals -============== +Proposed Goals and Behavioral Expectations +========================================= -1. **Respect Explicit Kind**: Ensure that if a KIND is explicitly set during storage, it is preserved and respected by the system. -2. **Handle Marker Kinds**: Recognize and correctly handle "marker" kinds (like ``PROJECT``) without losing underlying location identity (like being a stream location). -3. **Identify Incomplete Metadata**: Provide a mechanism to identify which locations do not have all their expected metadata filled out. -4. **Metadata Density**: It is acceptable for some metadata to be missing or stubbed initially, provided there is a way to denote the state of the location's metadata. +1. **Location Endpoint as Marker**: The general location endpoint is responsible for establishing the primary identity and "KIND" marker for a location. +2. **Kind-Specific Endpoint Responsibility**: Metadata and database rows specific to a KIND (like stream or project details) are the responsibility of their respective specialized endpoints. +3. **Respect Explicit Kind**: Ensure that if a KIND is explicitly set during storage at the location endpoint, it is preserved and respected as the primary marker. +4. **Handle Marker Kinds**: Recognize and correctly handle "marker" kinds (like ``PROJECT``) without losing underlying location identity (like being a stream location). +5. **Identify Incomplete Metadata**: Provide a mechanism to identify which locations do not have all their expected metadata filled out. +6. **Metadata Density**: It is acceptable for some metadata to be missing or stubbed initially, provided there is a way to denote the state of the location's metadata. Key Considerations @@ -56,6 +58,9 @@ Key Considerations * - Stubbing - Stubbing missing info is an acceptable short-term solution. - Allows the API to remain functional while identifying where more detailed metadata is required. + * - Endpoint Responsibility + - Location endpoints establish the KIND as a marker. Kind-specific endpoints (e.g., Stream, Project) handle detailed metadata. + - Clearly separates general location identity from specialized metadata management. Example Scenario From 27a04b33fa2fc99b561d3c217b32f140c6c8f766 Mon Sep 17 00:00:00 2001 From: Bryson Spilman Date: Thu, 28 May 2026 11:53:18 -0700 Subject: [PATCH 03/12] CDA-103 - updates to draft ADR --- .../0009-location-kind-persistence.rst | 355 +++++++++++++++--- 1 file changed, 299 insertions(+), 56 deletions(-) diff --git a/docs/source/decisions/0009-location-kind-persistence.rst b/docs/source/decisions/0009-location-kind-persistence.rst index 25305691fd..d595fe40af 100644 --- a/docs/source/decisions/0009-location-kind-persistence.rst +++ b/docs/source/decisions/0009-location-kind-persistence.rst @@ -2,84 +2,327 @@ Location Kind Persistence and Metadata ##### - Summary ======= -This ADR documents the behavior and relationship between general location endpoints and kind-specific endpoints (e.g., Stream, Project), specifically addressing how storing a Location with a set KIND acts as a "marker" and the implications for metadata retention. - +This ADR defines the relationship between the general Location identity and specialized Location Kinds (e.g., Stream, Project, Basin). It establishes the concept of "Marker" kinds versus "Metadata" rows and provides a mapping of Kinds to their respective database tables. Problem Statement ================= -Currently, when a physical location is stored without an assigned kind, it defaults to ``SITE``. If a user explicitly changes the kind to ``PROJECT`` (or another specific kind), it is treated as a "marker" kind. The location endpoint then works off that particular marker kind. +CWMS locations can embody multiple roles (e.g., a physical site that is both a Stream Gage and a Weather Gage). Currently, the transition between these kinds is not always well-defined, leading to potential data orphans or loss of specialized metadata. We need a clear policy on how the "KIND" column in ``AT_PHYSICAL_LOCATION`` interacts with specialized tables like ``AT_STREAM`` or ``AT_PROJECT``. -However, this transition can lead to loss of context or missing metadata. For example: -1. A location is stored as a ``SITE``. -2. A stream location is then stored for that ``SITE`` location. -3. If the location is subsequently changed to a ``PROJECT``, it becomes a "marker project" but "forgets" that it was also a stream location. +Location Kind and Table Mapping +=============================== -The location endpoint currently lacks the ability to denote all kinds that a single location might embody, leading to incomplete metadata representation. +The following table defines the required and allowed associations between Location Kinds and database tables. +.. list-table:: Location Kind to Table Mapping + :header-rows: 1 + :stub-columns: 1 -Proposed Goals and Behavioral Expectations -========================================= + * - Location Kind + - AT_PHYSICAL_LOCATION + - AT_STREAM + - AT_BASIN + - AT_GAGE + - AT_ENTITY + - AT_PROJECT + - AT_EMBANKMENT + - AT_OUTLET + - AT_TURBINE + - AT_LOCK + - AT_OVERFLOW + - AT_STREAM_LOCATION + - AT_STREAM_REACH + - AT_PUMP + * - SITE + - X + - + - + - + - + - + - + - + - + - + - + - + - + - + * - STREAM + - X + - X + - + - + - + - + - + - + - + - + - + - + - + - + * - BASIN + - X + - + - X + - + - + - + - + - + - + - + - + - + - + - + * - PROJECT + - X + - + - + - + - + - X + - + - + - + - + - + - + - + - + * - EMBANKMENT + - X + - + - + - + - + - + - X + - + - + - + - + - + - + - + * - OUTLET + - X + - + - + - + - + - + - + - X + - + - + - + - + - + - + * - TURBINE + - X + - + - + - + - + - + - + - + - X + - + - + - + - + - + * - LOCK + - X + - + - + - + - + - + - + - + - + - X + - + - + - + - + * - STREAM_LOCATION + - X + - + - + - + - + - + - + - + - + - + - + - X + - + - + * - GATE + - X + - + - + - + - + - + - + - X + - + - + - + - + - + - + * - OVERFLOW + - X + - + - + - + - + - + - + - X + - + - + - X + - + - + - + * - STREAM_GAGE + - X + - + - + - X + - + - + - + - + - + - + - + - X + - + - + * - STREAM_REACH + - X + - + - + - + - + - + - + - + - + - + - + - + - X + - + * - PUMP + - X + - + - + - + - + - + - + - + - + - + - + - X + - + - X + * - WEATHER_GAGE + - X + - + - + - X + - + - + - + - + - + - + - + - + - + - + * - ENTITY + - X + - + - + - + - X + - + - + - + - + - + - + - + - + - -1. **Location Endpoint as Marker**: The general location endpoint is responsible for establishing the primary identity and "KIND" marker for a location. -2. **Kind-Specific Endpoint Responsibility**: Metadata and database rows specific to a KIND (like stream or project details) are the responsibility of their respective specialized endpoints. -3. **Respect Explicit Kind**: Ensure that if a KIND is explicitly set during storage at the location endpoint, it is preserved and respected as the primary marker. -4. **Handle Marker Kinds**: Recognize and correctly handle "marker" kinds (like ``PROJECT``) without losing underlying location identity (like being a stream location). -5. **Identify Incomplete Metadata**: Provide a mechanism to identify which locations do not have all their expected metadata filled out. -6. **Metadata Density**: It is acceptable for some metadata to be missing or stubbed initially, provided there is a way to denote the state of the location's metadata. +**Legend:** +- **X**: Required (The presence of this Kind requires a row in the corresponding table). +- (Blank): Not Allowed or Not Applicable for the primary definition of the Kind. +Terminology +=========== -Key Considerations -================== +Marker +------ +A location is "marked" as a specific Kind in the ``AT_PHYSICAL_LOCATION`` table, but may or may not have the corresponding metadata rows in specialized tables yet. The Kind in ``AT_PHYSICAL_LOCATION`` serves as the primary functional role indicator. -.. list-table:: - :header-rows: 1 - :widths: 20 25 55 - - * - Topic - - Decision/Observation - - Justification - * - Default Kind - - Defaults to ``SITE`` if unassigned. - - Maintains backwards compatibility and provides a sane default for physical locations. - * - Marker Kinds - - Kinds like ``PROJECT`` act as markers that certain endpoints (like the location endpoint) use for filtering. - - Allows specialized views of locations based on their primary functional role. - * - Kind Multiplicity - - Locations may need to support multiple kinds or at least retain metadata associated with previous kinds. - - Prevents "identity loss" when a location's primary marker is updated. - * - View Inclusion - - Should marker-only rows in tables like ``at_project`` be visible in general views? - - Open question: Depending on use case, we may or may not want to see these markers in general av_project views. - * - Stubbing - - Stubbing missing info is an acceptable short-term solution. - - Allows the API to remain functional while identifying where more detailed metadata is required. - * - Endpoint Responsibility - - Location endpoints establish the KIND as a marker. Kind-specific endpoints (e.g., Stream, Project) handle detailed metadata. - - Clearly separates general location identity from specialized metadata management. - - -Example Scenario -~~~~~~~~~~~~~~~~ - -* **Initial State**: Location ``LOC123`` is created as a ``SITE``. -* **Step 2**: ``LOC123`` is defined as a stream location (associating it with stream-specific metadata). -* **Step 3**: ``LOC123`` is updated to have a ``PROJECT`` kind. -* **Result**: The system now sees ``LOC123`` primarily as a Project marker, but the stream location metadata may be inaccessible or unassociated through standard location queries. +Orphan +------ +An "orphan" occurs when a location's Kind is designated (e.g., as a ``PROJECT``), but no corresponding row exists in the kind-specific metadata table (e.g., ``AT_PROJECT``). While functionally a "marker," this state may be considered incomplete for certain API operations. + +Behavioral Rules +================ +Kind Transitions +---------------- +1. **New Rows Required**: Changing a Location's Kind in ``AT_PHYSICAL_LOCATION`` should generally require the creation of a new row in the corresponding ``AT_`` table if it doesn't already exist. +2. **Preservation of Existing Data**: Storing a new Kind marker should not automatically delete existing metadata from other kind-specific tables. A location that was a ``STREAM_GAGE`` and is now marked as a ``PROJECT`` should ideally retain its gage metadata unless explicitly removed. + +API Endpoint Expectations +------------------------- +1. **Filtering by Kind**: The general Location endpoint (getAll) should filter based on the Kind marker in ``AT_PHYSICAL_LOCATION``. +2. **Specialized Endpoints**: Kind-specific endpoints (e.g., ``/projects``, ``/streams``) must decide whether to return "marker-only" (orphan) locations. + - *Proposed*: A "marker-project" should be visible to the project endpoint, but may return null or default values for specialized fields if the ``AT_PROJECT`` row is missing. +3. **Workflow**: Defining a complex Kind (like a Project) involves two steps: + - Establishing the identity and Marker via the Location endpoint. + - Populating specialized metadata via the Kind-specific endpoint. + +Implementation Strategy +======================= + +1. **Database Procedures**: Leverage existing CWMS database procedures for storing locations and kinds, ensuring they handle the cross-table logic correctly. +2. **CDA Endpoints**: Update CDA controllers to respect the marker-based filtering and handle "sparse" metadata gracefully. +3. **Risk Mitigation**: Ensure that existing applications expecting "complete" rows in specialized tables are not broken by the introduction of marker-only entries. Decision Status =============== (Status: proposed) - References ========== -Related Types: ``cwms.cda.data.dto.Location``, ``cwms.cda.data.dto.CwmsIdLocationKind``, ``cwms.cda.data.dto.stream.StreamLocation`` -Issue/Discussion: [Internal Issue Tracking] +Related Types: ``cwms.cda.data.dto.Location``, ``cwms.cda.data.dto.CwmsIdLocationKind`` +Database Tables: ``AT_PHYSICAL_LOCATION``, ``AT_STREAM``, ``AT_BASIN``, ``AT_GAGE``, ``AT_ENTITY``, ``AT_PROJECT``, ``AT_EMBANKMENT``, ``AT_OUTLET``, ``AT_TURBINE``, ``AT_LOCK``, ``AT_OVERFLOW``, ``AT_STREAM_LOCATION``, ``AT_STREAM_REACH``, ``AT_PUMP`` From 396c2c2a88672ff8deee41b780f5d45262964d10 Mon Sep 17 00:00:00 2001 From: Bryson Spilman Date: Thu, 28 May 2026 12:10:54 -0700 Subject: [PATCH 04/12] CDA-103 - updates to draft ADR --- .../decisions/0009-location-kind-persistence.rst | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/source/decisions/0009-location-kind-persistence.rst b/docs/source/decisions/0009-location-kind-persistence.rst index d595fe40af..2052fb3af3 100644 --- a/docs/source/decisions/0009-location-kind-persistence.rst +++ b/docs/source/decisions/0009-location-kind-persistence.rst @@ -10,7 +10,9 @@ This ADR defines the relationship between the general Location identity and spec Problem Statement ================= -CWMS locations can embody multiple roles (e.g., a physical site that is both a Stream Gage and a Weather Gage). Currently, the transition between these kinds is not always well-defined, leading to potential data orphans or loss of specialized metadata. We need a clear policy on how the "KIND" column in ``AT_PHYSICAL_LOCATION`` interacts with specialized tables like ``AT_STREAM`` or ``AT_PROJECT``. +CWMS locations can embody multiple roles (e.g., a physical site that is both a Stream Gage and a Weather Gage). Currently, changing a location's Kind in ``AT_PHYSICAL_LOCATION`` generally requires a corresponding row in the specialized ``AT_`` table. If the row does not exist, the operation may fail or the Kind may not be properly updated. + +The concept of "Marker Kinds"—where a Kind is set in ``AT_PHYSICAL_LOCATION`` as a functional indicator without requiring immediate population of specialized metadata—is not currently supported. This ADR addresses how such a system would work, allowing for more flexible location management and preventing data orphans or loss of specialized metadata during transitions. Location Kind and Table Mapping =============================== @@ -278,7 +280,7 @@ The following table defines the required and allowed associations between Locati - **Legend:** -- **X**: Required (The presence of this Kind requires a row in the corresponding table). +- **X**: Required in the current system. Under the proposed Marker system, this indicates the table where metadata *would* reside if the Kind is more than just a marker. - (Blank): Not Allowed or Not Applicable for the primary definition of the Kind. Terminology @@ -297,8 +299,9 @@ Behavioral Rules Kind Transitions ---------------- -1. **New Rows Required**: Changing a Location's Kind in ``AT_PHYSICAL_LOCATION`` should generally require the creation of a new row in the corresponding ``AT_`` table if it doesn't already exist. -2. **Preservation of Existing Data**: Storing a new Kind marker should not automatically delete existing metadata from other kind-specific tables. A location that was a ``STREAM_GAGE`` and is now marked as a ``PROJECT`` should ideally retain its gage metadata unless explicitly removed. +1. **Current Behavior (New Rows Required)**: Currently, changing a Location's Kind in ``AT_PHYSICAL_LOCATION`` requires the creation of a new row in the corresponding ``AT_`` table if it doesn't already exist. +2. **Proposed Marker Support**: Under the proposed Marker system, the Kind in ``AT_PHYSICAL_LOCATION`` can be updated independently. If no specialized metadata row exists, the location is considered a "Marker" of that Kind. +3. **Preservation of Existing Data**: Storing a new Kind marker should not automatically delete existing metadata from other kind-specific tables. A location that was a ``STREAM_GAGE`` and is now marked as a ``PROJECT`` should retain its gage metadata unless explicitly removed. API Endpoint Expectations ------------------------- @@ -321,6 +324,11 @@ Decision Status (Status: proposed) +Notes on Current State +====================== + +The current behavior of the CWMS Data API and the underlying database procedures is that a location's Kind is tightly coupled with its specialized metadata. If a user attempts to change the Kind to ``PROJECT`` via the location endpoint, but no row exists in ``AT_PROJECT``, the system may revert to ``SITE`` or fail to update as expected. This ADR serves as a blueprint for decoupling these concepts to support "Marker Kinds". + References ========== From e12344a884cc3e87543e4a69258cecb1b3dd835d Mon Sep 17 00:00:00 2001 From: Bryson Spilman Date: Thu, 28 May 2026 12:13:32 -0700 Subject: [PATCH 05/12] CDA-103 - updates to draft ADR --- docs/source/decisions/0009-location-kind-persistence.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/decisions/0009-location-kind-persistence.rst b/docs/source/decisions/0009-location-kind-persistence.rst index 2052fb3af3..5691d33430 100644 --- a/docs/source/decisions/0009-location-kind-persistence.rst +++ b/docs/source/decisions/0009-location-kind-persistence.rst @@ -10,7 +10,7 @@ This ADR defines the relationship between the general Location identity and spec Problem Statement ================= -CWMS locations can embody multiple roles (e.g., a physical site that is both a Stream Gage and a Weather Gage). Currently, changing a location's Kind in ``AT_PHYSICAL_LOCATION`` generally requires a corresponding row in the specialized ``AT_`` table. If the row does not exist, the operation may fail or the Kind may not be properly updated. +CWMS locations can embody multiple roles (e.g., a physical site that is both a Stream Gage and a Stream Location). Currently, changing a location's Kind in ``AT_PHYSICAL_LOCATION`` generally requires a corresponding row in the specialized ``AT_`` table. If the row does not exist, the operation may fail or the Kind may not be properly updated. The concept of "Marker Kinds"—where a Kind is set in ``AT_PHYSICAL_LOCATION`` as a functional indicator without requiring immediate population of specialized metadata—is not currently supported. This ADR addresses how such a system would work, allowing for more flexible location management and preventing data orphans or loss of specialized metadata during transitions. From 6238e02475d9cf066d87f7875c31ac1ff57b331a Mon Sep 17 00:00:00 2001 From: Bryson Spilman Date: Thu, 28 May 2026 12:14:46 -0700 Subject: [PATCH 06/12] CDA-103 - updates to draft ADR --- docs/source/decisions/0009-location-kind-persistence.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/decisions/0009-location-kind-persistence.rst b/docs/source/decisions/0009-location-kind-persistence.rst index 5691d33430..0bff437647 100644 --- a/docs/source/decisions/0009-location-kind-persistence.rst +++ b/docs/source/decisions/0009-location-kind-persistence.rst @@ -10,7 +10,7 @@ This ADR defines the relationship between the general Location identity and spec Problem Statement ================= -CWMS locations can embody multiple roles (e.g., a physical site that is both a Stream Gage and a Stream Location). Currently, changing a location's Kind in ``AT_PHYSICAL_LOCATION`` generally requires a corresponding row in the specialized ``AT_`` table. If the row does not exist, the operation may fail or the Kind may not be properly updated. +CWMS locations can embody multiple roles (e.g., a physical site that is both an Embankment and a Stream Location). Currently, changing a location's Kind in ``AT_PHYSICAL_LOCATION`` generally requires a corresponding row in the specialized ``AT_`` table. If the row does not exist, the operation may fail or the Kind may not be properly updated. The concept of "Marker Kinds"—where a Kind is set in ``AT_PHYSICAL_LOCATION`` as a functional indicator without requiring immediate population of specialized metadata—is not currently supported. This ADR addresses how such a system would work, allowing for more flexible location management and preventing data orphans or loss of specialized metadata during transitions. From 12c3ff88c15dbb1d89a204e3aec4b33b93c8f561 Mon Sep 17 00:00:00 2001 From: Bryson Spilman Date: Thu, 28 May 2026 12:15:52 -0700 Subject: [PATCH 07/12] CDA-103 - updates to draft ADR --- docs/source/decisions/0009-location-kind-persistence.rst | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/source/decisions/0009-location-kind-persistence.rst b/docs/source/decisions/0009-location-kind-persistence.rst index 0bff437647..9b29d47b68 100644 --- a/docs/source/decisions/0009-location-kind-persistence.rst +++ b/docs/source/decisions/0009-location-kind-persistence.rst @@ -290,10 +290,6 @@ Marker ------ A location is "marked" as a specific Kind in the ``AT_PHYSICAL_LOCATION`` table, but may or may not have the corresponding metadata rows in specialized tables yet. The Kind in ``AT_PHYSICAL_LOCATION`` serves as the primary functional role indicator. -Orphan ------- -An "orphan" occurs when a location's Kind is designated (e.g., as a ``PROJECT``), but no corresponding row exists in the kind-specific metadata table (e.g., ``AT_PROJECT``). While functionally a "marker," this state may be considered incomplete for certain API operations. - Behavioral Rules ================ From 822a189a812980591f31b83489174d097b2bdbb9 Mon Sep 17 00:00:00 2001 From: Bryson Spilman Date: Thu, 28 May 2026 12:19:51 -0700 Subject: [PATCH 08/12] CDA-103 - updates to draft ADR --- .../0009-location-kind-persistence.rst | 53 ++++++++++--------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/docs/source/decisions/0009-location-kind-persistence.rst b/docs/source/decisions/0009-location-kind-persistence.rst index 9b29d47b68..f47d0a6b51 100644 --- a/docs/source/decisions/0009-location-kind-persistence.rst +++ b/docs/source/decisions/0009-location-kind-persistence.rst @@ -12,7 +12,7 @@ Problem Statement CWMS locations can embody multiple roles (e.g., a physical site that is both an Embankment and a Stream Location). Currently, changing a location's Kind in ``AT_PHYSICAL_LOCATION`` generally requires a corresponding row in the specialized ``AT_`` table. If the row does not exist, the operation may fail or the Kind may not be properly updated. -The concept of "Marker Kinds"—where a Kind is set in ``AT_PHYSICAL_LOCATION`` as a functional indicator without requiring immediate population of specialized metadata—is not currently supported. This ADR addresses how such a system would work, allowing for more flexible location management and preventing data orphans or loss of specialized metadata during transitions. +The concept of "Marker Kinds"—where a Kind is set in ``AT_PHYSICAL_LOCATION`` as a functional indicator without requiring immediate population of specialized metadata—is not currently supported. This ADR addresses how such a system would work, allowing for more flexible location management and preventing loss of specialized metadata during transitions. Location Kind and Table Mapping =============================== @@ -87,14 +87,14 @@ The following table defines the required and allowed associations between Locati - X - - - - - - + - A + - A - X - - - - - - + - A - - - @@ -102,14 +102,14 @@ The following table defines the required and allowed associations between Locati - X - - - - + - A - - - X - - - - - + - A - - - @@ -124,7 +124,7 @@ The following table defines the required and allowed associations between Locati - X - - - - + - A - - - @@ -139,7 +139,7 @@ The following table defines the required and allowed associations between Locati - - X - - - + - A - - - @@ -147,23 +147,23 @@ The following table defines the required and allowed associations between Locati - X - - - - - - + - A + - A - - - - - X + - A - - - - - - + - A * - STREAM_LOCATION - X - - - - - - + - A + - A - - - @@ -183,8 +183,8 @@ The following table defines the required and allowed associations between Locati - - X - - - - - + - A + - A - - - @@ -200,7 +200,7 @@ The following table defines the required and allowed associations between Locati - - - X - - + - A - - * - STREAM_GAGE @@ -217,7 +217,7 @@ The following table defines the required and allowed associations between Locati - - X - - - + - A * - STREAM_REACH - X - @@ -237,13 +237,13 @@ The following table defines the required and allowed associations between Locati - X - - + - A + - A - + - A - - - - - - - - - - + - A - - X - @@ -253,7 +253,7 @@ The following table defines the required and allowed associations between Locati - - - X - - + - A - - - @@ -267,7 +267,7 @@ The following table defines the required and allowed associations between Locati - X - - - - + - A - X - - @@ -281,7 +281,8 @@ The following table defines the required and allowed associations between Locati **Legend:** - **X**: Required in the current system. Under the proposed Marker system, this indicates the table where metadata *would* reside if the Kind is more than just a marker. -- (Blank): Not Allowed or Not Applicable for the primary definition of the Kind. +- **A**: Allowed. +- (Blank): Not Allowed. Terminology =========== @@ -302,7 +303,7 @@ Kind Transitions API Endpoint Expectations ------------------------- 1. **Filtering by Kind**: The general Location endpoint (getAll) should filter based on the Kind marker in ``AT_PHYSICAL_LOCATION``. -2. **Specialized Endpoints**: Kind-specific endpoints (e.g., ``/projects``, ``/streams``) must decide whether to return "marker-only" (orphan) locations. +2. **Specialized Endpoints**: Kind-specific endpoints (e.g., ``/projects``, ``/streams``) must decide whether to return "marker-only" locations. - *Proposed*: A "marker-project" should be visible to the project endpoint, but may return null or default values for specialized fields if the ``AT_PROJECT`` row is missing. 3. **Workflow**: Defining a complex Kind (like a Project) involves two steps: - Establishing the identity and Marker via the Location endpoint. From a21a0b3b02387cb7b9a4b60b22a8b197ecdf705a Mon Sep 17 00:00:00 2001 From: Bryson Spilman Date: Fri, 29 May 2026 09:57:12 -0700 Subject: [PATCH 09/12] CDA-103 - updates to draft ADR --- .../0009-location-kind-persistence.rst | 287 +++++++++++++++++- 1 file changed, 281 insertions(+), 6 deletions(-) diff --git a/docs/source/decisions/0009-location-kind-persistence.rst b/docs/source/decisions/0009-location-kind-persistence.rst index f47d0a6b51..390a670771 100644 --- a/docs/source/decisions/0009-location-kind-persistence.rst +++ b/docs/source/decisions/0009-location-kind-persistence.rst @@ -10,14 +10,19 @@ This ADR defines the relationship between the general Location identity and spec Problem Statement ================= -CWMS locations can embody multiple roles (e.g., a physical site that is both an Embankment and a Stream Location). Currently, changing a location's Kind in ``AT_PHYSICAL_LOCATION`` generally requires a corresponding row in the specialized ``AT_`` table. If the row does not exist, the operation may fail or the Kind may not be properly updated. +CWMS locations can embody multiple roles (e.g., a physical site that is both an Embankment and a Stream Location). Currently, changing a location's Kind in ``AT_PHYSICAL_LOCATION`` generally requires a corresponding row in the specialized ``AT_`` table. If the row does not exist, the operation may fail or the Kind may not be properly updated. The concept of "Marker Kinds"—where a Kind is set in ``AT_PHYSICAL_LOCATION`` as a functional indicator without requiring immediate population of specialized metadata—is not currently supported. This ADR addresses how such a system would work, allowing for more flexible location management and preventing loss of specialized metadata during transitions. Location Kind and Table Mapping =============================== -The following table defines the required and allowed associations between Location Kinds and database tables. +The following tables define the relationship between Location Kinds and database tables under the current and proposed systems. + +Current System Mapping (Physical Coupling) +------------------------------------------ + +In the current system, a location's Kind is tightly coupled with its specialized metadata. The following table defines the required and allowed associations. .. list-table:: Location Kind to Table Mapping :header-rows: 1 @@ -279,9 +284,279 @@ The following table defines the required and allowed associations between Locati - - -**Legend:** -- **X**: Required in the current system. Under the proposed Marker system, this indicates the table where metadata *would* reside if the Kind is more than just a marker. -- **A**: Allowed. +**Legend (Current System):** +- **X**: Required. The specialized metadata row must exist for this Kind to be valid. +- **A**: Allowed. Optional metadata row. +- (Blank): Not Allowed. + +Proposed Marker System Mapping (Decoupled Labeling) +--------------------------------------------------- + +Under the proposed Marker system, the Kind in ``AT_PHYSICAL_LOCATION`` acts as a label. The presence of specialized metadata in ``AT_`` tables is optional (Allowed) for all Kinds, as the "Marker" itself is sufficient for the identity. + +.. list-table:: Proposed Marker System Mapping + :header-rows: 1 + :stub-columns: 1 + + * - Location Kind + - AT_PHYSICAL_LOCATION + - AT_STREAM + - AT_BASIN + - AT_GAGE + - AT_ENTITY + - AT_PROJECT + - AT_EMBANKMENT + - AT_OUTLET + - AT_TURBINE + - AT_LOCK + - AT_OVERFLOW + - AT_STREAM_LOCATION + - AT_STREAM_REACH + - AT_PUMP + * - SITE + - X + - + - + - + - + - + - + - + - + - + - + - + - + - + * - STREAM + - X + - A + - + - + - + - + - + - + - + - + - + - + - + - + * - BASIN + - X + - + - A + - + - + - + - + - + - + - + - + - + - + - + * - PROJECT + - X + - + - + - A + - A + - A + - + - + - + - + - A + - + - + - + * - EMBANKMENT + - X + - + - + - A + - + - + - A + - + - + - + - A + - + - + - + * - OUTLET + - X + - + - + - + - + - + - + - A + - + - + - A + - + - + - + * - TURBINE + - X + - + - + - + - + - + - + - + - A + - + - A + - + - + - + * - LOCK + - X + - + - + - A + - A + - + - + - + - + - A + - A + - + - + - A + * - STREAM_LOCATION + - X + - + - + - A + - A + - + - + - + - + - + - + - A + - + - + * - GATE + - X + - + - + - + - + - + - + - A + - + - A + - A + - + - + - + * - OVERFLOW + - X + - + - + - + - + - + - + - A + - + - + - A + - A + - + - + * - STREAM_GAGE + - X + - + - + - A + - + - + - + - + - + - + - + - A + - + - A + * - STREAM_REACH + - X + - + - + - + - + - + - + - + - + - + - + - + - A + - + * - PUMP + - X + - + - + - A + - A + - + - A + - + - + - A + - + - A + - + - A + * - WEATHER_GAGE + - X + - + - + - A + - A + - + - + - + - + - + - + - + - + - + * - ENTITY + - X + - + - + - A + - A + - + - + - + - + - + - + - + - + - + +**Legend (Marker System):** +- **X**: Required. The location must exist in ``AT_PHYSICAL_LOCATION``. +- **A**: Allowed. The metadata row is optional; its absence results in a "Marker-only" location. - (Blank): Not Allowed. Terminology @@ -296,7 +571,7 @@ Behavioral Rules Kind Transitions ---------------- -1. **Current Behavior (New Rows Required)**: Currently, changing a Location's Kind in ``AT_PHYSICAL_LOCATION`` requires the creation of a new row in the corresponding ``AT_`` table if it doesn't already exist. +1. **Current Behavior (New Rows Required)**: Currently, changing a Location's Kind in ``AT_PHYSICAL_LOCATION`` requires the creation of a new row in the corresponding ``AT_`` table if it doesn't already exist. 2. **Proposed Marker Support**: Under the proposed Marker system, the Kind in ``AT_PHYSICAL_LOCATION`` can be updated independently. If no specialized metadata row exists, the location is considered a "Marker" of that Kind. 3. **Preservation of Existing Data**: Storing a new Kind marker should not automatically delete existing metadata from other kind-specific tables. A location that was a ``STREAM_GAGE`` and is now marked as a ``PROJECT`` should retain its gage metadata unless explicitly removed. From e01c1fe211e3c4d1a40d0e164c88c48e9bf12d57 Mon Sep 17 00:00:00 2001 From: Bryson Spilman Date: Fri, 29 May 2026 10:10:10 -0700 Subject: [PATCH 10/12] CDA-103 - updates to draft ADR --- .../decisions/0009-location-kind-persistence.rst | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/docs/source/decisions/0009-location-kind-persistence.rst b/docs/source/decisions/0009-location-kind-persistence.rst index 390a670771..c3cfe3b0f1 100644 --- a/docs/source/decisions/0009-location-kind-persistence.rst +++ b/docs/source/decisions/0009-location-kind-persistence.rst @@ -579,17 +579,15 @@ API Endpoint Expectations ------------------------- 1. **Filtering by Kind**: The general Location endpoint (getAll) should filter based on the Kind marker in ``AT_PHYSICAL_LOCATION``. 2. **Specialized Endpoints**: Kind-specific endpoints (e.g., ``/projects``, ``/streams``) must decide whether to return "marker-only" locations. - - *Proposed*: A "marker-project" should be visible to the project endpoint, but may return null or default values for specialized fields if the ``AT_PROJECT`` row is missing. -3. **Workflow**: Defining a complex Kind (like a Project) involves two steps: - - Establishing the identity and Marker via the Location endpoint. - - Populating specialized metadata via the Kind-specific endpoint. + - *Proposed*: A "marker-project" should: Implementation Strategy ======================= -1. **Database Procedures**: Leverage existing CWMS database procedures for storing locations and kinds, ensuring they handle the cross-table logic correctly. -2. **CDA Endpoints**: Update CDA controllers to respect the marker-based filtering and handle "sparse" metadata gracefully. -3. **Risk Mitigation**: Ensure that existing applications expecting "complete" rows in specialized tables are not broken by the introduction of marker-only entries. +Risks +======================= +1. **Data Integrity**: Allowing Kinds to exist without corresponding metadata rows may lead to confusion or misuse if not properly documented and handled in the API. +2. **Existing Clients**: Changes to the behavior of Kind updates may impact existing clients that expect the current coupling of Kind and metadata. Clear communication and versioning will be necessary. Decision Status =============== From 822390d47282f27a3284181f43f572729c040331 Mon Sep 17 00:00:00 2001 From: Bryson Spilman Date: Fri, 29 May 2026 15:24:33 -0700 Subject: [PATCH 11/12] CDA-103 - updates to draft ADR --- .../0009-location-kind-persistence.rst | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/docs/source/decisions/0009-location-kind-persistence.rst b/docs/source/decisions/0009-location-kind-persistence.rst index c3cfe3b0f1..3d51f80c27 100644 --- a/docs/source/decisions/0009-location-kind-persistence.rst +++ b/docs/source/decisions/0009-location-kind-persistence.rst @@ -562,9 +562,31 @@ Under the proposed Marker system, the Kind in ``AT_PHYSICAL_LOCATION`` acts as a Terminology =========== +Location Kind Hierarchy +----------------------- + +.. code-block:: text + + SITE + ├── BASIN + ├── STREAM + ├── STREAM_REACH + ├── STREAM_LOCATION + │ ├── STREAM_GAGE + │ └── PUMP + ├── WEATHER_GAGE + ├── PROJECT + ├── EMBANKMENT + ├── ENTITY + ├── LOCK + ├── TURBINE + └── OUTLET + ├── GATE + └── OVERFLOW + Marker ------ -A location is "marked" as a specific Kind in the ``AT_PHYSICAL_LOCATION`` table, but may or may not have the corresponding metadata rows in specialized tables yet. The Kind in ``AT_PHYSICAL_LOCATION`` serves as the primary functional role indicator. +A location is "marked" as a specific Kind in the ``AT_PHYSICAL_LOCATION`` table, but does not have the corresponding metadata rows in specialized tables yet. The Kind in ``AT_PHYSICAL_LOCATION`` serves as the primary functional role indicator. It is no longer considered a marker-kind once the specialized kind-metadata is added to the corresponding kind table. Behavioral Rules ================ @@ -573,11 +595,11 @@ Kind Transitions ---------------- 1. **Current Behavior (New Rows Required)**: Currently, changing a Location's Kind in ``AT_PHYSICAL_LOCATION`` requires the creation of a new row in the corresponding ``AT_`` table if it doesn't already exist. 2. **Proposed Marker Support**: Under the proposed Marker system, the Kind in ``AT_PHYSICAL_LOCATION`` can be updated independently. If no specialized metadata row exists, the location is considered a "Marker" of that Kind. -3. **Preservation of Existing Data**: Storing a new Kind marker should not automatically delete existing metadata from other kind-specific tables. A location that was a ``STREAM_GAGE`` and is now marked as a ``PROJECT`` should retain its gage metadata unless explicitly removed. +3. **Preservation of Existing Data**: Storing a new Kind marker should not automatically delete existing metadata from other kind-specific tables. A location that was a ``STREAM_GAGE`` and is now marked as a ``PROJECT`` should retain its gage metadata unless explicitly removed. If transitioned to a ``SITE`` does this mean all metadata is lost? API Endpoint Expectations ------------------------- -1. **Filtering by Kind**: The general Location endpoint (getAll) should filter based on the Kind marker in ``AT_PHYSICAL_LOCATION``. +1. **Filtering by Kind**: The general Location endpoint (getAll) should filter based on the Kind marker in ``AT_PHYSICAL_LOCATION``. This will not query against any at_ tables (This should be handled by kind-specified endpoints). 2. **Specialized Endpoints**: Kind-specific endpoints (e.g., ``/projects``, ``/streams``) must decide whether to return "marker-only" locations. - *Proposed*: A "marker-project" should: From a60af6ae488b17dfc38dadacf92497c88e23c51c Mon Sep 17 00:00:00 2001 From: Bryson Spilman Date: Fri, 29 May 2026 15:33:32 -0700 Subject: [PATCH 12/12] CDA-103 - updates to draft ADR --- docs/source/decisions/0009-location-kind-persistence.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/source/decisions/0009-location-kind-persistence.rst b/docs/source/decisions/0009-location-kind-persistence.rst index 3d51f80c27..2ebf95a8d6 100644 --- a/docs/source/decisions/0009-location-kind-persistence.rst +++ b/docs/source/decisions/0009-location-kind-persistence.rst @@ -24,6 +24,11 @@ Current System Mapping (Physical Coupling) In the current system, a location's Kind is tightly coupled with its specialized metadata. The following table defines the required and allowed associations. +Database Mapping: +^^^^^^^^^^^^^^^^^ + +The kind of a location is determined by the ``LOCATION_KIND`` column in the ``AT_PHYSICAL_LOCATION`` table. This column contains a numeric code that maps to the ``LOCATION_KIND_CODE`` column in the ``CWMS_LOCATION_KIND`` table. The ``CWMS_LOCATION_KIND`` table also contains a ``LOCATION_KIND_ID`` column, which provides the human-readable string representation of the location kind (e.g., "PROJECT", "STREAM_GAGE"). + .. list-table:: Location Kind to Table Mapping :header-rows: 1 :stub-columns: 1