Last deployment:

Turfi Platform Documentation

Official Turfi documentation portal for users, admins, and developers.

Back to support

Documentation Search

Search only within Turfi documentation pages.

C

Addresses

Shared address registry contract.

Entity: Addresses

1. Overview

  • Shared normalized address registry used by organizations, leagues, clubs, venues, and other address-bearing entities.
  • Acts as a reusable shared-data entity.
  • Can be linked through centralized entity-address relationships and direct entity foreign keys.
  • Visible at /admin/data/registries/addresses.

2. Database Schema

Columns

columntypenullabledefaultnotes
address_line1string \nullyesnullBase table field.
address_line2string \nullyesnullBase table field.
citystring \nullyesnullBase table field.
countrystring \nullyesnullBase table field.
created_atstringnodatabase default or generatedBase table field.
idstringnogenerated UUID defaultBase table field.
labelstring \nullyesnullBase table field.
latitudenumber \nullyesnullBase table field.
longitudenumber \nullyesnullBase table field.
normalized_labelstring \nullyesnullBase table field.
notesstring \nullyesnullBase table field.
postal_codestring \nullyesnullBase table field.
provincestring \nullyesnullBase table field.
statusstringnodatabase default or generatedLifecycle field when present.
updated_atstringnodatabase default or generatedBase table field.

Foreign Keys

No foreign keys documented by the generated schema contract.

Indexes

No migration-defined indexes were discovered in the checked-in SQL history for this table.

Constraints

  • Unique: none discovered in checked-in migrations.
  • Check: none discovered in checked-in migrations.

Triggers

No migration-defined triggers were discovered in the checked-in SQL history for this table.

Views (if any)

namepurpose
api_addressesShared-data read model for address registry operations.

3. Import Contract

Accepted Columns

  • label
  • address_line1
  • address_line2
  • city
  • province
  • postal_code
  • country
  • latitude
  • longitude

Resolution Rules

  • Address imports are direct-field imports into the shared address record contract.

Required Fields

  • label

Optional Fields

  • address_line1
  • address_line2
  • city
  • province
  • postal_code
  • country
  • latitude
  • longitude

Failure Rules

  • Missing label fails immediately.
  • Invalid coordinates or malformed address fields fail validation rather than mismatch handling.

4. Frontend Registry Mapping

Grid Columns

labelfieldsource
Namenameapi_addresses.name / addresses.name
Labellabeladdresses.label
Address Line 1address_line1addresses.address_line1
Citycityaddresses.city
Provinceprovinceaddresses.province
Countrycountryaddresses.country
Linked Entitieslinked_entity_countrelationship summary
Statusstatusnormalized row.status

Filters

filterfieldtype
Searchname, label, address_line1, city, province, countrytext substring
Provinceprovinceselect
Citycityselect
Statusstatusselect

Display Logic

  • Linked entity count is a derived relationship summary, not a base column on every source.
  • Status defaults to active in the UI when absent.
  • Add/edit flows rely on address autocomplete rather than expecting operators to key every address fragment manually.

5. Lifecycle Rules

  • Shared addresses should be reused or inactivated rather than duplicated or hard-deleted when linked entities exist.
  • Location edits should preserve geocoded coordinates and dependent entity references.

Relationships

  • organizations.address_id -> addresses.id with ON DELETE SET NULL.
  • leagues.address_id -> addresses.id with ON DELETE SET NULL.
  • clubs.address_id -> addresses.id with ON DELETE SET NULL.
  • entity_addresses.address_id -> addresses.id enables reusable shared links for club, organization, venue, business, and user entity types.
  • entity_addresses.address_role_id -> address_roles.id assigns an optional semantic role to each link.
  • Direct address_id behaves like a single primary-slot reference on the parent record. entity_addresses is reusable and many-to-many: one entity can hold multiple addresses, and one address can be linked to multiple entities.
  • Primary-link behavior is enforced by idx_entity_addresses_primary_unique plus trg_entity_addresses_single_primary.
  • When the final entity_addresses link is removed, trg_entity_addresses_cleanup_orphan deletes the orphaned address record automatically.

Import Contract Detail

  • Parent-entity imports for organizations, leagues, and clubs accept inline address fields: address_line1, address_line2, city, province, postal_code, and country.
  • During import, ensureImportedEntityAddressId() first attempts an exact match on those six normalized address fields.
  • If exactly one existing address matches, the system reuses that record and assigns its address_id to the parent entity.
  • If no address matches, the system creates a new addresses row and assigns the new address_id to the parent entity.
  • If more than one existing address matches, the row fails with Ambiguous address match for imported row. rather than guessing.
  • The inserted label falls back in this order: parent name, explicit label, address_line1, then Primary.
  • Venues, businesses, and users do not use this inline address_id import adapter path; they are managed through the reusable entity_addresses bundle flow in admin services.

Views / Joins

  • api_addresses reads directly from addresses and adds linked_entity_count plus primary_entity_count from entity_addresses.
  • Association, league, and club grids resolve location display by joining the parent row's address_id to addresses, then flattening city, province, and full-address text into registry rows.
  • Venue, turf, and business UIs rely on shared bundle/address-link data and registry views rather than a direct address_id column on every table.
  • Address registry filters operate on the address row itself: city, province, country, and status are read from api_addresses / addresses.

Usage Across Entities

  • Current direct address_id consumers: organizations, leagues, and clubs.
  • Current shared-link consumers in entity_addresses: clubs, organizations, venues, businesses, and users.
  • Updating an address row propagates to linked primary shared-link dependents through trg_addresses_refresh_dependents, which refreshes summary fields for clubs, organizations, venues, businesses, and users.
  • For direct address_id consumers, the UI primarily relies on address joins to display city, province, and full-address values, so the joined address record is the operative source of truth for registry display.
  • Because addresses are shared, editing one address record affects every entity linked to that same record.