Reference

The database schema

One pipeline, four layers: a jurisdiction is identified, its adopted code is retrieved chapter by chapter, each chapter is read into rules, and each rule yields discrete requirements — every layer keeping the citation back to the text. The row counts below are live.
state_zoning_statuteone row per state enabling act50delegates the power to zonezoning_localityone row per jurisdiction on the roster17,523ordinance retrieved as chapterszoning_ordinance_contentone row per chapter — OCR text + markdown3,931read into structured ruleszoning_ordinance_rulesone row per district or citywide provision42,251each rule yields discrete requirementszoning_ordinance_standardone row per requirement, with its sentence170,998zoning_ordinance_sourcecandidate code URLs found in discovery18,119zoning_standard_defvocabulary of standard keys195,908

zoning_locality

17,523 rows · one zoning jurisdiction each

The national roster. A row is created when a jurisdiction is identified, long before its ordinance is retrieved — which is what lets the site distinguish no rules exist from not read yet. TIGER FIPS columns join it to Census geometry; the nza_* columns carry National Zoning Atlas figures verbatim for the 118 jurisdictions the Atlas has read.

ColumnTypeMeaning
locality_idbigintPrimary key, used in every /localities URL
locality_name · locality_typetextName and kind — municipality, county unincorporated, township…
state_abbr · state_fipscharState, as postal code and FIPS
placefp · cousubfp · fips_countycharTIGER joins to Census place / county-subdivision / county geometry
discovery_statustextpending → found → acquired; or no_code / unavailable / error
has_zoningbooleanNULL = unknown; FALSE = confirmed to have no zoning code
ordinance_urltextWhere the adopted code was located
population · housing_unitsintegerCensus figures, where joined
nza_*numeric…National Zoning Atlas statistics, in acres — kept verbatim and shown separately

Exposed atLocalitiesZoning overviewAPI

zoning_ordinance_content

3,931 rows · one retrieved chapter each

The full text. Each chapter of an adopted code is retrieved from its host, OCR’d, and structured into markdown; both forms are kept. A functional GIN index over the text is what answers full-text search, and structured_markdown is what the chapter pages render — with extracted standards highlighted in place.

ColumnTypeMeaning
content_idbigintPrimary key, used in every /chapters URL
locality_idbigint→ zoning_locality
source · source_url · document_urltextWhich host the chapter came from, and where
chapter · document_titletextThe chapter heading as published
ocr_texttextRaw OCR output
structured_markdowntextThe same text, structured — headings, tables, emphasis
char_countintegerGenerated column over the OCR text; chapters average 67 KB, the largest is 3 MB
statustextpending → ocr_done → markdown_done → rules_extracted

Exposed atChaptersText searchAPI

zoning_ordinance_rules

42,251 rows · one extracted rule each

The heart of the database. A rule with a zone_code is a district — R-1, B-2 — carrying the ordinance’s dimensional standards for that zone across roughly fifty typed columns. A rule with rule_scope = ‘general’ is a citywide provision: most of a code’s volume. Every rule keeps the section and excerpt it was read from.

ColumnTypeMeaning
rule_idbigintPrimary key, used in every /districts URL
content_id · locality_idbigint→ the chapter it was read from, and the jurisdiction
rule_scopetextdistrict · general · overlay
zone_code · zone_name · zone_categorytextThe district identity; category drives the site-wide legend
min_lot_area_sqft … max_farnumeric ×50Dimensional standards: lot, density, setbacks, height, bulk, parking
permitted/conditional/accessory/prohibited_usestext[]The use lists, as the ordinance names them
sf/mf2/mf3/mf4plus_treatmenttextHow 1–4+ family housing is treated: by_right · conditional · prohibited
adu_allowedbooleanAccessory dwelling units; NULL = the ordinance does not say
source_section · source_excerpttextThe citation: where in the code this was read, and its language
confidence · needs_reviewreal · booleanExtractor self-assessment, surfaced on the page when flagged

Exposed atDistrict pagesDistrict searchAPI

zoning_ordinance_standard

170,998 rows · one discrete requirement each

Requirements lifted out of the prose, one per row — a maximum sign area, a fence setback, a riparian buffer — each typed by value_kind and each carrying raw_text, the sentence it was read from. That sentence is what the chapter pages locate and highlight.

ColumnTypeMeaning
standard_idbigintPrimary key; the #standard-N anchors on chapter pages
rule_id · content_id · locality_idbigint→ the rule, chapter and jurisdiction it belongs to
categorytextOne of 28 checked values — signage, parking, height, floodplain…
standard_key · labeltextMachine-generated key and human label
numeric_value · numeric_value_max · unitnumeric · textThe value, or a range, with its unit
bool_value · text_value · enum_valuevariousNon-numeric values, per value_kind
raw_texttextThe exact sentence the requirement was read from
applies_whenjsonbConditions scoping the requirement, where stated

Exposed atStandardsAPI

zoning_standard_def

195,908 rows · one standard key each

The vocabulary of standard_keys with default units and value kinds. Machine-generated and definition-free — which is why the site’s glossary is authored rather than derived from it.

ColumnTypeMeaning
standard_keytextPrimary key
category · label · default_unittextGrouping, display label, unit
value_kindtextnumeric · range · boolean · text · enum

state_zoning_statute

50 rows · one state enabling act each

The state law behind every local ordinance: the authority model (who may zone), the primary citation, the delegating text and a plain summary, with a verification flag.

ColumnTypeMeaning
state_abbr · state_nametextOne row per state
authority_modeltextcounty_and_municipal · municipal_delegation · state_level, with local nuance
primary_citation · statute_title · source_urltextThe citation and where to read it
statute_text · summarytextThe delegating language and a plain-English summary
verified · confidenceboolean · textWhether the record was checked against the source

Exposed atStatutesAPI

zoning_ordinance_source

18,119 rows · one candidate source each

Discovery bookkeeping: every candidate URL found while hunting for a jurisdiction’s adopted code, with its kind and status. Feeds the pipeline; not exposed on the site directly.

ColumnTypeMeaning
locality_idbigint→ zoning_locality
source · url · kind · titletextWhere a code might live, and what kind of host it is
statustextWhether the candidate panned out

Database notes

NULL means silence, not no. Every extracted column distinguishes what the ordinance does not say from what it forbids — adu_allowed is NULL where the code never addresses it, and the site renders that as “not stated” throughout.

On the roster ≠ read. A locality row exists as soon as a jurisdiction is identified; only districts extracted from its chapters make it searchable. And a locality with rules is not necessarily one with districts — a retrieved subdivision chapter yields general provisions and nothing else.

Numerics travel as strings. Postgres numeric preserves precision, so the JSON API returns dimensional values as strings — parse them, don’t assume numbers.

The read-only grants the site runs under are documented in .env.example; the optional text-search migration ships as sql/search_index.sql and belongs to the pipeline, not the site.