Skip to content

Domain Relationships

This page records the reusable relationship architecture that emerged from the artist/event work. It should guide future events, venues, event series, users, admin tables, and relationship-management surfaces without forcing every page to copy the artist implementation exactly.

Large relationship surfaces may also need the query-control, URL-state, and saved-view patterns described in Query Controls And Browsing State.

High-cardinality relationships should be treated as collections, not as ordinary form fields.

Use normal form controls for scalar entity fields such as name, description, profile image, and external links. Use a collection-management surface for associated events, venues, artists, event-series membership, and similar relationship sets once the count can become medium or large.

Parent create/edit forms should stay lightweight:

  • Show a compact relationship summary near the relevant section.
  • Include a count badge or accessible count label.
  • Provide an explicit management action such as Manage Artist Events.
  • Avoid rendering a large removable-card list inline with scalar fields.

The dedicated relationship surface should own the collection workflow:

  • Title and count summary.
  • Typeahead or search-driven assignment flow.
  • Current association dataset.
  • Search, filter, sort, and pagination controls when the dataset needs them.
  • Assign and unassign actions.
  • Optional navigation into related entities.

Prefer a reusable relationship-management shell with entity-specific row or column rendering. The reusable contract should own the sheet frame, shared controls, assignment boundaries, and state choreography. It should not become one rigid universal table that erases domain differences.

Two-sided relationship management is acceptable for trusted admin surfaces when authorization and audit posture support it. For example, the platform may eventually allow editing artist-event associations from an artist page, an event page, or a venue/event-series page. The important part is that each entry point uses the same relationship-management mental model.

Keep relationship-management permission separate from profile editing. Artists are the first worked example: manage-artist-event-relationships allows artist-event association management without implying control over artist profile copy or artist media.

Domain join tables should be modeled so they can grow into first-class association entities.

The current durable schema pattern is:

  • A surrogate ID UUID primary key for the association row itself.
  • Foreign keys for the participating entities.
  • A separate uniqueness constraint that expresses the current business rule.

Current examples include:

artists_events: unique(artistID, eventID)
events_venues: unique(eventID, venueID)
events_event_series: unique(eventID, eventSeriesID)
users_roles: unique(userID, roleID)
roles_permissions: unique(roleID, permissionID)

Do not use composite primary keys such as (artistID, eventID) for domain association tables. Row identity should stay separate from business uniqueness so the row can later carry metadata without a conceptual reset.

Keep the current pairwise uniqueness rule until the domain introduces a real discriminator. A UUID primary key does not mean duplicate association pairs should be allowed by default. Relax uniqueness only when the application can explain and render the difference, such as:

  • roleType
  • billingOrder
  • appearanceType
  • setNumber
  • Active-row uniqueness after soft delete

Relationship metadata belongs on the association row, not on either parent entity. If artist appearances at events later need billing order, appearance role, notes, provenance, or workflow flags, those fields should live on artists_events.

Domain association rows are the likeliest to grow richer over time. Authorization joins such as users_roles and roles_permissions can stay lean unless auditing, temporal history, or permission-management workflows require more.

The most likely additive lifecycle fields are:

  • createdAt
  • updatedAt
  • createdByUserID
  • updatedByUserID

Soft delete is the main future schema fork. If reversible unassignment becomes important, relationship tables may need removedAt and removedByUserID, plus a uniqueness rule that applies only to active rows. Treat that as a deliberate migration and product decision, not a default table shape.

The following items are intentionally not treated as settled architecture yet:

  • The exact reusable prop/component contract for EntityRelationshipSheet.
  • Which association tables should receive lifecycle or provenance fields first.
  • Whether relationship removal should stay hard-delete plus audit log or support soft-delete/restore.
  • Which relationship metadata appears first, especially for artist appearances at events.