# `GeoGenius.Providers.SimpleMaps.Validation`
[🔗](https://github.com/agoodway/geo_genius/blob/main/lib/geo_genius/providers/simplemaps/validation.ex#L1)

Row-scoped consistency checks for SimpleMaps' denormalised county columns.

Neither `uscities` nor `uszips` carries a county as a row of its own; each
row denormalises the counties it touches into `county_fips`,
`county_fips_all`, and a counties-name column -- `county_name_all` on
`uscities`, `county_names_all` on `uszips` -- and `uszips` additionally
carries `county_weights`. Those columns can disagree with each other
inside one row, and GeoGenius accepts multiple official names for one
area, so a source that contradicts itself would otherwise be reconciled by
picking a name lexically rather than by authority -- a coin toss, not
reconciliation. `check/1` fails the row instead, before
`GeoGenius.Providers.SimpleMaps.Rows.areas/1` builds anything from it.

One rule reads a single column rather than a pair of them: a `uscities`
row naming no county at all. Two blank columns agree with each other, so
that is the one self-contradiction the pairing rules cannot see, and the
row it would otherwise let through publishes a city with nothing above it
but a state.

That rule is `uscities`-only, and its absence from `uszips` is measured
rather than overlooked. Every city sits in a county, so a `uscities` row
naming none is corruption. A ZIP need not: military APO/FPO ZIPs deliver
to overseas addresses that sit in no US county, and they are a sizeable
minority of the file rather than a curiosity. So a `uszips` row with no
county and no `county_weights` is valid, while one that names counties and
carries no weights for them is the corruption case.

**Only what one row can prove.** Every rule here reads a single staged row
and never compares across rows or across `uscities`/`uszips`. Cross-file
agreement -- one FIPS mapping to two different states, or `uscities` and
`uszips` spelling one county's name two different ways -- cannot be seen
from a single row and is not checked here. That agreement is left to the
host's own import verification.

# `check`

```elixir
@spec check(GeoGenius.Staging.Row.t()) :: :ok | {:error, String.t()}
```

Checks a staged SimpleMaps row's county columns for self-contradiction.

Returns `:ok` for an artifact other than `uscities` or `uszips` --
`GeoGenius.Providers.SimpleMaps.Rows.areas/1` is what rejects an unknown
artifact, so this does not duplicate that error.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
