From 301d828ee3f246533043333d7adbd29101c7893a Mon Sep 17 00:00:00 2001 From: ksmuczynski Date: Sun, 14 Dec 2025 19:41:14 -0700 Subject: [PATCH 1/5] feat: add PublicRelease feature covering schema and public visibility Adds a new Gherkin feature file that defines the legacy PublicRelease field behavior, including valid bit values, default handling, and rejection of invalid inputs, along with business-level scenarios for public visibility in reports and web maps. --- legacy/field_public_release.feature | 98 +++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 legacy/field_public_release.feature diff --git a/legacy/field_public_release.feature b/legacy/field_public_release.feature new file mode 100644 index 0000000..84c5474 --- /dev/null +++ b/legacy/field_public_release.feature @@ -0,0 +1,98 @@ +@legacy-db @field_PublicRelease +Feature: PublicRelease controls public visibility of sites + PublicRelease is a legacy BIT field used to determine whether a site is ready for release + to the public via reports and web maps. + Interpretation: 0 = false (not released to public), 1 = true (released to public). + Default: No / false (not released to public). + + Background: + # Target field: PublicRelease + + + # --------------------------------------------------------------------------- + # Storage-layer / data integrity behavior + # These scenarios validate accepted inputs and default behavior for the legacy field. + # --------------------------------------------------------------------------- + + @schema @storage + Scenario Outline: Accept valid bit values for PublicRelease + When I insert a site record with PublicRelease set to + Then the record is accepted + And PublicRelease is interpreted as + And the site is + + Examples: + | input_value | boolean_value | release_state | + | 0 | false | not publicly released | + | 1 | true | publicly released | + + @schema @storage + Scenario: Apply default value when PublicRelease is not provided + When I insert a new site record without specifying PublicRelease + Then the record is accepted + And PublicRelease defaults to false + + @schema @storage @characterization + Scenario: Define behavior when PublicRelease is explicitly NULL + When I attempt to insert a site record with PublicRelease set to NULL + Then the record is rejected + + @schema @storage @characterization + Scenario Outline: Reject non-bit values for PublicRelease + When I attempt to insert a site record with PublicRelease set to + Then the record is rejected + And an error indicates PublicRelease must be 0 or 1 + + Examples: + | invalid_input | + | 2 | + | -1 | + | "Yes" | + | "True" | + + + # --------------------------------------------------------------------------- + # Business-level / public-facing behavior + # These scenarios validate what a public user can observe in reports and web maps. + # --------------------------------------------------------------------------- + + @business @public @reports @webmaps + Scenario Outline: PublicRelease determines whether a site is visible to the public + Given a site exists with PublicRelease set to + When a public user views sites in public reports + Then the site is + When a public user views sites in public web maps + Then the site is + + Examples: + | input_value | report_visibility | map_visibility | + | 0 | not shown | not shown | + | 1 | shown | shown | + + @business @public @reports @webmaps + Scenario: Sites are not publicly visible by default + Given a site exists with PublicRelease not set + When a public user views sites in public reports + Then the site is not shown + When a public user views sites in public web maps + Then the site is not shown + + @business @public @reports @webmaps + Scenario: Updating PublicRelease to true makes a site publicly visible + Given a site exists with PublicRelease set to 0 + When the site's PublicRelease is updated to 1 + Then PublicRelease is interpreted as true + When a public user views sites in public reports + Then the site is shown + When a public user views sites in public web maps + Then the site is shown + + @business @public @reports @webmaps + Scenario: Updating PublicRelease to false removes a site from public visibility + Given a site exists with PublicRelease set to 1 + When the site's PublicRelease is updated to 0 + Then PublicRelease is interpreted as false + When a public user views sites in public reports + Then the site is not shown + When a public user views sites in public web maps + Then the site is not shown \ No newline at end of file From 8261dbf23b4c41dc6031ae7c6c893eb9912fa970 Mon Sep 17 00:00:00 2001 From: ksmuczynski Date: Sun, 14 Dec 2025 20:03:24 -0700 Subject: [PATCH 2/5] refactor: refactor PublicRelease business scenario to check state vs origin --- legacy/field_public_release.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/legacy/field_public_release.feature b/legacy/field_public_release.feature index 84c5474..41c1cd9 100644 --- a/legacy/field_public_release.feature +++ b/legacy/field_public_release.feature @@ -71,7 +71,7 @@ Feature: PublicRelease controls public visibility of sites @business @public @reports @webmaps Scenario: Sites are not publicly visible by default - Given a site exists with PublicRelease not set + Given a site exists where PubliRelease is false When a public user views sites in public reports Then the site is not shown When a public user views sites in public web maps From 634555789f1973b10e191b341a41330bc3ff684c Mon Sep 17 00:00:00 2001 From: ksmuczynski Date: Sun, 14 Dec 2025 20:11:29 -0700 Subject: [PATCH 3/5] refactor: fix typo Error: Given a site exists where PubliRelease is false Correction: PublicRelease (missing the 'c'). --- legacy/field_public_release.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/legacy/field_public_release.feature b/legacy/field_public_release.feature index 41c1cd9..6893887 100644 --- a/legacy/field_public_release.feature +++ b/legacy/field_public_release.feature @@ -71,7 +71,7 @@ Feature: PublicRelease controls public visibility of sites @business @public @reports @webmaps Scenario: Sites are not publicly visible by default - Given a site exists where PubliRelease is false + Given a site exists where PublicRelease is false When a public user views sites in public reports Then the site is not shown When a public user views sites in public web maps From cbcecd4b356662310ef5cb69719c697778844245 Mon Sep 17 00:00:00 2001 From: ksmuczynski Date: Sun, 14 Dec 2025 21:28:04 -0700 Subject: [PATCH 4/5] refactor: consolidate PublicRelease behavior into single feature file Refactors PublicRelease Gherkin tests into one consolidated feature using Scenario Outlines as a configuration matrix to cover all legacy tables. Captures shared BIT semantics alongside table-specific nullability, default, and public visibility behavior in a single, maintainable specification. --- legacy/field_public_release.feature | 174 ++++++++++++++++------------ 1 file changed, 102 insertions(+), 72 deletions(-) diff --git a/legacy/field_public_release.feature b/legacy/field_public_release.feature index 6893887..7731c1e 100644 --- a/legacy/field_public_release.feature +++ b/legacy/field_public_release.feature @@ -1,98 +1,128 @@ -@legacy-db @field_PublicRelease -Feature: PublicRelease controls public visibility of sites - PublicRelease is a legacy BIT field used to determine whether a site is ready for release - to the public via reports and web maps. - Interpretation: 0 = false (not released to public), 1 = true (released to public). - Default: No / false (not released to public). +@legacy-db @field_PublicRelease @cross_functional +Feature: PublicRelease global field behavior + The PublicRelease bit field exists across multiple legacy tables. + Data type is consistent (BIT), but constraints (nullability, defaults) vary by table. Background: - # Target field: PublicRelease - + Given the target field is "PublicRelease" # --------------------------------------------------------------------------- - # Storage-layer / data integrity behavior - # These scenarios validate accepted inputs and default behavior for the legacy field. + # 1. CORE DATA TYPE CHECK (Applies to ALL tables) # --------------------------------------------------------------------------- @schema @storage - Scenario Outline: Accept valid bit values for PublicRelease - When I insert a site record with PublicRelease set to + Scenario Outline: All tables accept valid bit values (0 and 1) + Given I am targeting the "" table + When I insert a record with PublicRelease set to Then the record is accepted - And PublicRelease is interpreted as - And the site is + And the stored value is Examples: - | input_value | boolean_value | release_state | - | 0 | false | not publicly released | - | 1 | true | publicly released | + | table | input_value | + | Location | 0 | + | Location | 1 | + | WaterLevels | 0 | + | WaterLevels | 1 | + | WaterLevelsContinuous_Acoustic | 0 | + | WaterLevelsContinuous_Acoustic | 1 | + | ChemistrySampleInfo | 0 | + | ChemistrySampleInfo | 1 | - @schema @storage - Scenario: Apply default value when PublicRelease is not provided - When I insert a new site record without specifying PublicRelease - Then the record is accepted - And PublicRelease defaults to false + # --------------------------------------------------------------------------- + # 2. NULLABILITY CHECK (Varies by table) + # - Strict: NOT NULL (Location) + # - Hybrid: NULL allowed (WaterLevels, WaterLevelsContinuous_Acoustic) + # - Loose: NULL allowed (ChemistrySampleInfo) + # --------------------------------------------------------------------------- - @schema @storage @characterization - Scenario: Define behavior when PublicRelease is explicitly NULL - When I attempt to insert a site record with PublicRelease set to NULL - Then the record is rejected + @schema @storage @edge_case + Scenario Outline: Verify NULL acceptance policy per table + Given I am targeting the "
" table + When I attempt to insert a record with PublicRelease set to NULL + Then the system should the record - @schema @storage @characterization - Scenario Outline: Reject non-bit values for PublicRelease - When I attempt to insert a site record with PublicRelease set to - Then the record is rejected - And an error indicates PublicRelease must be 0 or 1 + Examples: Strict constraints (NOT NULL) + | table | outcome | + | Location | reject | - Examples: - | invalid_input | - | 2 | - | -1 | - | "Yes" | - | "True" | + Examples: Hybrid constraints (NULL allowed, default exists) + | table | outcome | + | WaterLevels | accept | + | WaterLevelsContinuous_Acoustic | accept | + Examples: Loose constraints (NULL allowed, no default) + | table | outcome | + | ChemistrySampleInfo | accept | # --------------------------------------------------------------------------- - # Business-level / public-facing behavior - # These scenarios validate what a public user can observe in reports and web maps. + # 3. DEFAULT VALUE CHECK (Varies by table) + # - Default 0: Location, WaterLevels, WaterLevelsContinuous_Acoustic + # - No default: ChemistrySampleInfo (remains NULL) + # --------------------------------------------------------------------------- + + @schema @storage @defaults + Scenario Outline: Verify default value when field is omitted + Given I am targeting the "
" table + When I insert a record without specifying PublicRelease + Then the record is accepted + And the PublicRelease field should be set to + + Examples: Tables with default ((0)) + | table | expected_default | + | Location | 0 | + | WaterLevels | 0 | + | WaterLevelsContinuous_Acoustic | 0 | + + Examples: Tables with no default (NULL) + | table | expected_default | + | ChemistrySampleInfo | NULL | + + # --------------------------------------------------------------------------- + # 4. BUSINESS LOGIC (Public visibility by data type) + # PublicRelease indicates whether the data from the table is visible to the public. # --------------------------------------------------------------------------- @business @public @reports @webmaps - Scenario Outline: PublicRelease determines whether a site is visible to the public - Given a site exists with PublicRelease set to - When a public user views sites in public reports - Then the site is - When a public user views sites in public web maps - Then the site is + Scenario Outline: PublicRelease = 1 makes data visible to the public + Given I am targeting the "
" table + And I have a record with PublicRelease set to 1 + When a public user views the in public reports + Then the is visible + When a public user views the in public web maps + Then the is visible Examples: - | input_value | report_visibility | map_visibility | - | 0 | not shown | not shown | - | 1 | shown | shown | + | table | data_description | + | Location | location information | + | WaterLevels | water level measurement information | + | WaterLevelsContinuous_Acoustic | water level measurement information | + | ChemistrySampleInfo | chemistry data | @business @public @reports @webmaps - Scenario: Sites are not publicly visible by default - Given a site exists where PublicRelease is false - When a public user views sites in public reports - Then the site is not shown - When a public user views sites in public web maps - Then the site is not shown + Scenario Outline: PublicRelease = 0 makes data not visible to the public + Given I am targeting the "
" table + And I have a record with PublicRelease set to 0 + When a public user views the in public reports + Then the is not visible + When a public user views the in public web maps + Then the is not visible - @business @public @reports @webmaps - Scenario: Updating PublicRelease to true makes a site publicly visible - Given a site exists with PublicRelease set to 0 - When the site's PublicRelease is updated to 1 - Then PublicRelease is interpreted as true - When a public user views sites in public reports - Then the site is shown - When a public user views sites in public web maps - Then the site is shown + Examples: + | table | data_description | + | Location | location information | + | WaterLevels | water level measurement information | + | WaterLevelsContinuous_Acoustic | water level measurement information | + | ChemistrySampleInfo | chemistry data | + + @business @public @reports @webmaps @edge_case + Scenario Outline: PublicRelease = NULL makes data not visible to the public + Given I am targeting the "
" table + And I have a record with PublicRelease set to NULL + When a public user views the in public reports + Then the is not visible + When a public user views the in public web maps + Then the is not visible - @business @public @reports @webmaps - Scenario: Updating PublicRelease to false removes a site from public visibility - Given a site exists with PublicRelease set to 1 - When the site's PublicRelease is updated to 0 - Then PublicRelease is interpreted as false - When a public user views sites in public reports - Then the site is not shown - When a public user views sites in public web maps - Then the site is not shown \ No newline at end of file + Examples: + | table | data_description | + | ChemistrySampleInfo | chemistry data | From eeb76f632d95845ae7f6685d441a0c7a7c5e0bd2 Mon Sep 17 00:00:00 2001 From: ksmuczynski Date: Fri, 19 Dec 2025 11:04:49 -0700 Subject: [PATCH 5/5] feat: new feature file to document chemistry business rules --- legacy/chemistry_structure.feature | 129 +++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 legacy/chemistry_structure.feature diff --git a/legacy/chemistry_structure.feature b/legacy/chemistry_structure.feature new file mode 100644 index 0000000..5563efd --- /dev/null +++ b/legacy/chemistry_structure.feature @@ -0,0 +1,129 @@ +@legacy-db @chemistry_domain @business-rules +Feature: Chemistry sampling events provide the organizing context for field and laboratory results + Chemistry data is organized around a sampling event. + Each sampling event represents one collection occurrence and provides the context needed + to interpret field measurements and laboratory analytical results. + + Background: + Given a sampling location exists + + # --------------------------------------------------------------------------- + # 1) Sampling event meaning (Chemistry SampleInfo) + # --------------------------------------------------------------------------- + + @business-meaning + Scenario: A sampling event is the authoritative parent record for chemistry results + When a chemistry sampling event is recorded + Then the event is assigned a system identifier used to link chemistry results + And the event is assigned a required tracking identifier used by people to reference the sample + And the event captures sampling context such as methods and tracking information + + @data-quality + Scenario: A sampling event must include basic classification information + When a chemistry sampling event is recorded without a sample type + Then the sampling event is not considered valid for downstream use + When a chemistry sampling event is recorded without a collection method + Then the sampling event is not considered valid for downstream use + + @identity + Scenario: The sample tracking identifier uniquely identifies a sampling event + When a chemistry sampling event is recorded with tracking identifier "SAMP000001" + Then the sampling event is accepted + When another chemistry sampling event is recorded with tracking identifier "SAMP000001" + Then the sampling event is not accepted because the tracking identifier must be unique + + @legacy-behavior + Scenario: Legacy sampling events may exist without a location link + When a chemistry sampling event is recorded without a location link + Then the event is stored + And the event is treated as incomplete for location-based reporting + + # --------------------------------------------------------------------------- + # 2) Laboratory & Field Results + # --------------------------------------------------------------------------- + + @business-meaning @relationships + Scenario Outline: All analytical results must be attributable to a specific sampling event + Given a chemistry sampling event exists + When results are recorded for the event + Then the results are linked to that specific sampling event + And multiple records may exist for the same event + + Examples: + | result_type | + | Field Parameter | + | Major Ion Chemistry | + | Minor, Trace, Isotope, and Age-Related | + | Radionuclide | + + @data-quality @integrity + Scenario Outline: Analytical results cannot exist without a parent sampling event + When results are submitted without a reference to a sampling event + Then the system prevents the results from being stored + And orphaned analytical data is not retained + + Examples: + | result_type | + | Field Parameter | + | Major Ion Chemistry | + | Minor, Trace, Isotope, and Age-Related | + | Radionuclide | + + # --------------------------------------------------------------------------- + # 3) Interpreting repeated measurements (legacy looseness / real-world workflows) + # --------------------------------------------------------------------------- + + @legacy-behavior + Scenario Outline: Repeated measurements may exist for the same sample and measurement type + Given a chemistry sampling event exists + When a "" result is recorded for "" + And another "" result is recorded for the same "" under the same event + Then both results are retained + And consumers treat them as multiple measurements (e.g., repeats, reruns, corrections, or parallel reporting) + + Examples: + | result_type | measurement_identifier | + | Major Ion Chemistry | Calcium | + | Minor, Trace, Isotope, and Age-Related | Arsenic | + | Field Parameter | Temperature | + | Radionuclide | Uranium | + + # --------------------------------------------------------------------------- + # 4) Data stewardship expectations for removals (danger zone) + # --------------------------------------------------------------------------- + + @stewardship @danger_zone + Scenario: Removing a sampling event removes associated results to avoid stranded data + Given a chemistry sampling event exists + And analytical results exist under that event + When the sampling event is removed + Then associated field and laboratory results are also removed + And the system does not retain unattached result records + + @stewardship @danger_zone + Scenario: Removing a location can remove all chemistry collected at that location + Given a location exists with one or more chemistry sampling events + And analytical results exist under those sampling events + When the location is removed + Then the sampling events and their associated results are also removed + And this behavior is treated as a high-impact data stewardship operation + + # --------------------------------------------------------------------------- + # 5) Retrieval expectations (how the data is consumed) + # --------------------------------------------------------------------------- + + @reporting + Scenario: A complete chemistry record can be assembled for a sampling event + Given a chemistry sampling event exists + And any combination of field and laboratory results exist for the event + When a user requests chemistry data for the sampling event + Then the response includes the sampling event context + And includes all available field measurements recorded under the event + And includes all available laboratory results recorded under the event + + @reporting + Scenario: Chemistry data can be retrieved for a location across sampling events + Given a location has multiple chemistry sampling events + When a user requests chemistry data for the location + Then the response includes all sampling events linked to that location + And each sampling event includes its associated field and laboratory results