Skip to content
Profiles & cities

cities

Cities — canonical, Google-Places-backed (migration 0024). One row per Google place: `name` is the English name ("Munich"), `local_name` the name in the country's language ("München"), `alt_names` every other spelling we have resolved or seen typed ("Мюнхен", "Munique", "munchen"). The CityCombobox only ever saves one of these rows, so "München", "Мюнхен" and "munich" all end up as the same city. Free-text `city` columns elsewhere are migrated to a `city_id` FK later — plan: docs/research/2026-10-12-city-canonicalisation.md.

Columns

ColumnTypeNullDefaultKeys
iduuid nogen_random_uuid()
PK
google_place_idtext no—
slugtext no—
nametext no—
local_nametext yes—
countrytext yes—
country_codetext yes—
regiontext yes—
latdouble precision yes—
lngdouble precision yes—
alt_namesjsonb no[]
created_attimestamp nonow()
updated_attimestamp nonow()

Value lists come from .$type<'a' | 'b'>() in the schema — enforced in TypeScript only, not by the database.

Keys, constraints & indexes

Unique

None besides the primary key.

Indexes

  • (google_place_id)unique
    cities_google_place_id_uidx
  • (slug)unique
    cities_slug_uidx
  • (lower("cities"."name"))
    cities_name_lower_idx
  • (lower("cities"."local_name"))
    cities_local_name_lower_idx
  • (alt_names)gin
    cities_alt_names_gin_idx

Foreign keys

None.

Used by

Code that reads or writes this table, found by static analysis of the tRPC routers and API handlers (including helpers they call).

Relations

Rendering diagram…

Diagram source
erDiagram
  cities {
    uuid id PK
  }

Defined at server/database/schema.ts:1047 as cities.