Turfi Platform Documentation
Official Turfi documentation portal for users, admins, and developers.
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
| column | type | nullable | default | notes | |
|---|---|---|---|---|---|
| address_line1 | string \ | null | yes | null | Base table field. |
| address_line2 | string \ | null | yes | null | Base table field. |
| city | string \ | null | yes | null | Base table field. |
| country | string \ | null | yes | null | Base table field. |
| created_at | string | no | database default or generated | Base table field. | |
| id | string | no | generated UUID default | Base table field. | |
| label | string \ | null | yes | null | Base table field. |
| latitude | number \ | null | yes | null | Base table field. |
| longitude | number \ | null | yes | null | Base table field. |
| normalized_label | string \ | null | yes | null | Base table field. |
| notes | string \ | null | yes | null | Base table field. |
| postal_code | string \ | null | yes | null | Base table field. |
| province | string \ | null | yes | null | Base table field. |
| status | string | no | database default or generated | Lifecycle field when present. | |
| updated_at | string | no | database default or generated | Base 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)
| name | purpose |
|---|---|
| api_addresses | Shared-data read model for address registry operations. |
3. Import Contract
Accepted Columns
labeladdress_line1address_line2cityprovincepostal_codecountrylatitudelongitude
Resolution Rules
- Address imports are direct-field imports into the shared address record contract.
Required Fields
label
Optional Fields
address_line1address_line2cityprovincepostal_codecountrylatitudelongitude
Failure Rules
- Missing
labelfails immediately. - Invalid coordinates or malformed address fields fail validation rather than mismatch handling.
4. Frontend Registry Mapping
Grid Columns
| label | field | source |
|---|---|---|
| Name | name | api_addresses.name / addresses.name |
| Label | label | addresses.label |
| Address Line 1 | address_line1 | addresses.address_line1 |
| City | city | addresses.city |
| Province | province | addresses.province |
| Country | country | addresses.country |
| Linked Entities | linked_entity_count | relationship summary |
| Status | status | normalized row.status |
Filters
| filter | field | type |
|---|---|---|
| Search | name, label, address_line1, city, province, country | text substring |
| Province | province | select |
| City | city | select |
| Status | status | select |
Display Logic
- Linked entity count is a derived relationship summary, not a base column on every source.
- Status defaults to
activein 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.idwithON DELETE SET NULL.leagues.address_id -> addresses.idwithON DELETE SET NULL.clubs.address_id -> addresses.idwithON DELETE SET NULL.entity_addresses.address_id -> addresses.idenables reusable shared links forclub,organization,venue,business, anduserentity types.entity_addresses.address_role_id -> address_roles.idassigns an optional semantic role to each link.- Direct
address_idbehaves like a single primary-slot reference on the parent record.entity_addressesis 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_uniqueplustrg_entity_addresses_single_primary. - When the final
entity_addresseslink is removed,trg_entity_addresses_cleanup_orphandeletes 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, andcountry. - 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_idto the parent entity. - If no address matches, the system creates a new
addressesrow and assigns the newaddress_idto 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, explicitlabel,address_line1, thenPrimary. - Venues, businesses, and users do not use this inline
address_idimport adapter path; they are managed through the reusableentity_addressesbundle flow in admin services.
Views / Joins
api_addressesreads directly fromaddressesand addslinked_entity_countplusprimary_entity_countfromentity_addresses.- Association, league, and club grids resolve location display by joining the parent row's
address_idtoaddresses, then flatteningcity,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_idcolumn on every table. - Address registry filters operate on the address row itself:
city,province,country, and status are read fromapi_addresses/addresses.
Usage Across Entities
- Current direct
address_idconsumers: 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_idconsumers, the UI primarily relies on address joins to displaycity,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.