Skip to content

Venue Authoring

Use this page when changing the Venue column across contracts, persistence, API handlers, or the Add/Edit and public page flows. Venue follows the established Event invariants for public identity, strict DTOs, revisions, focused relationship management, server hydration, and recoverable media writes. It deliberately diverges around one current address snapshot, location TBA, provider-neutral resolution, and Venue-owned public map-location policy.

LayerOwnerResponsibility
Shared contractspackages/api-contracts/src/types/venues/Strict public, authoring, mutation, relationship, location, and media DTOs.
Persistencepackages/data-access/src/schema/venues.tsVenue identity, current address, publication policy, links, media, receipts, revisions, and audits.
Shared readspackages/data-access/src/reads/venues/Injected Venue summary and ready-media projections shared by the servers.
Backend readsapps/wavemap-back-end/src/queries/venues/App query orchestration, map/detail and protected projections, and runtime-context adapters.
Backend writesapps/wavemap-back-end/src/handlers/venues/Authorization, revision/idempotency rules, relationships, compensated media, and stable errors.
Shared formapps/wavemap-front-end/src/components/Forms/AddOrEditVenueForm/Scalar/location draft, focused Event sheet, media draft, validation, and serialization.
Page workflowsapps/wavemap-front-end/src/app/[locale]/(venues)/add-venue/ and edit-venue/[venueID]/Auth restoration, protected hydration, conflict/media recovery, cache refresh, and navigation.
Public compositionapps/wavemap-front-end/src/app/[locale]/(venues)/venues/Index/Details hydration, canonical identity, compact context, media, map data, and placeholders.
Operator diagnosticsapps/wavemap-back-end/src/scripts/reportMediaDiscrepancies.tsRead-only DB/provider drift reporting; never cleanup authority.

VenueSummaryDTO serves the Index at card/list density. VenueDetailsDTO adds contact, links, ordered ready media, and related Event composition. VenuePublicReferenceDTO is the compact provider-neutral identity used by Event and Artist contexts; it carries canonical public identity, location presentation, and profile media without protected authoring fields.

VenueAuthoringDTO is a separate protected projection. The Edit page enables its client query only after the in-memory session has restored authorization; it is intentionally not server-prefetched. Public reads never expose revision, request receipts, raw address components, provider provenance, or non-ready media state.

VenueDetailsDTO.publishedCoordinates is nullable and fails closed unless the Venue policy is exact with a complete persisted coordinate pair. The focused POST /venues/map/query route returns the complete active, exactly published collection for the durable Venue filter identity. It has no pagination or presentation sort, returns a stable 422 above 2,000 matches, and never calls the address-resolution or map provider. Its frontend client parses the strict response before a map-only, lazily enabled query hook may cache it.

Create/update accept public IDs and stable codes, validate strict request envelopes, and use revision-aware transactions. The mutation request ID makes a completed create or update replayable without duplicating the parent. Receipts are short-lived safety state rather than historical product content; the on-demand cleanup path deletes only receipts older than its explicit retention cutoff. A future scheduler may invoke the same logic, but scheduling remains operations work.

Location search discovers candidates; resolution turns one selected candidate into a complete snapshot suitable for review. Neither operation writes the Venue. The final mutation persists only the accepted provider-neutral snapshot or a manual/TBA choice. Corrections and relocations retain private transition evidence for future audit verification while ordinary reads remain current-state queries.

locationPublicationCode remains Venue-owned when an address is corrected, re-resolved, or relocated. New resolved locations with both coordinates default to exact; TBA and coordinate-incomplete locations default to hidden. Explicitly hidden locations remain supported for secret, private, or otherwise unsuitable public points. The database column retains an unconditional hidden default as a fail-closed low-level backstop because it cannot validate the referenced address row, while the create handler selects the meaningful conditional default explicitly.

The Add form begins with exact publication selected, moves to hidden when the editor chooses TBA, and returns to the public default when an address is deliberately confirmed. Edit hydration preserves the stored choice until the editor changes it or moves from TBA into the confirmed-address workflow. Both the form and backend reject an exact draft without complete coordinates. Actual policy transitions retain actor/request/revision context but no coordinate history.

Migration 0048_publish_resolved_venue_locations applies the changed policy once to existing data: every Venue whose current address has both coordinates becomes exact, while TBA and coordinate-incomplete rows remain hidden. The development seed follows the same complete-versus-incomplete rule. The migration does not invent coordinates or create human-action audit rows for the repository-wide policy rollout.

Venue/Event management follows the established separate-sheet pattern. Add mode keeps selections in the parent create draft. Edit mode applies public-ID deltas through the Venue-owned relationship capability, checks the expected Venue revision, records write provenance, and invalidates protected hydration plus Venue-scoped Event/public Details queries. Compact previews stay in the parent form; the sheet owns discovery, pagination, removal, and focus restoration.

Venue media remains entity-owned rather than entering a universal media API. Parent persistence finishes first, uploads retain successful public identities, and final sync establishes purpose, order, and alt text. Storage failure is compensated where possible. Retry resumes unfinished uploads or final sync without recreating the Venue. Public adapters return ready-only render URLs and never publish provider, bucket, location, or object-key fields.

The discrepancy reporter supports --entity venue and optional --venue-id. Its output compares Venue media rows with provider objects and reports drift kinds. It is evidence-only: no report authorizes row or object deletion.

The shared form memoizes its initial Edit snapshot because link drafts receive client-only keys and must not be rebuilt on every render. The Event relationship drawer explicitly focuses its close action on open and restores focus to Manage Events on close. Browser proof exercises this contract against the populated seeded Substation relationship set at 375px without mutating it.

Use the narrowest verification layer:

  • Contract and mocked-request tests for strict shapes, permissions, envelopes, and stable errors.
  • DB-backed tests for idempotency, revision conflicts, address replacement/audit evidence, relationship deltas, receipt cleanup, media compensation, and public projection batching.
  • Frontend integration tests for clients, query identity, protected hydration, draft/retry behavior, cache invalidation, canonical navigation, and responsive composition.
  • Focused browser proof for real auth navigation, sheet focus, narrow containment, provider-candidate confirmation, and public media choreography.
  • Connected-provider attribution, quota, origin-restriction, privacy/CSP, performance, and representative-device proof remain in the map roadmap’s M4 pass.
  • Event Series membership, recurrence, editions, and containment remain absent from Venue contracts.
  • A human-readable consequential-write audit trail remains a later cross-entity capability; receipts and private transition rows are supporting data-safety evidence, not its UI or final schema.