Skip to content

Venue Module Backend

Related documentation: Backend Modules · Venue Module Backend API · Data ownership · Access Control · Frontend Venues

  • Backend-Kisum-Venues now exists as a real Go/Fiber service with PostgreSQL DI, JWT + x-org access enforcement, internal API-key routes, repository-backed MVP handlers, and a production-intended legacy sleeping-venue importer.
  • The current runtime already implements venues, spaces, availability blocks, bookings, customer overlays, and internal Base-facing venue reads.
  • The current runtime also exposes Admin-facing internal venue CRUD, venue-type, sleeping-inventory, takeover-approval, takeover-audit, reconciliation, and activation endpoints so Admin can use Venue as source of truth without direct DB access.
  • Phase 7 (reporting) is live. Four /api/v1/reports/* endpoints back the same query contract (fromAt, toAt, bucket, venueId, spaceId, businessUnitId, marketCompanyId, marketPersonId): utilization (pure Venue truth), revenue (Venue deposits merged with Finance-derived invoiced/paid), profitability (Finance income − Finance bills), customers (Venue bookings grouped by Artists party id, optionally enriched with Finance totals). When the Finance HTTP client is unconfigured, reports return financeLinked = false with an explicit financeMessage — never silent zeros. Aggregations live in internal/venue/repositories/reports_postgres.go (ad-hoc SQL, no materialized views).
  • Phase 6 (events + operations) is live on the Venue side. Events are persisted as references to the canonical Promoter-owned event (promoterEventId) or as placeholders for off-platform promoters (isPlaceholder = true) with a reconciliation path via POST /api/v1/events/:id/link-promoter. Operations checklists, reusable templates, readiness state, and event/space assignment are all persisted.
  • Phase 4 commercial routes (deals, contracts, deposits, event finance-visibility) are repository-backed on the Venue side. Real external Adobe Sign upstream sync and the deeper Finance handoff (booking obligations, settlements, profitability source of truth) are still pending. Deposit invoice sync is live through Finance income machine mode; reporting read-path is live through GET /api/income and GET /api/bills.
  • Pending: real Adobe Sign upstream, deeper Finance handoff beyond deposit invoices + reports read-path, Venue HTTP client to call Promoters GET /internal/events/:id (resolver live on Promoters since 2026-05-27), Finance-side aggregation endpoints so reports don’t have to pull every row.
  • This page documents the enforced module boundary plus the current runtime direction.

Backend-Kisum-Venues is the domain backend for the venue module.

It exists so Kisum can manage a venue as an operating business, not only list venues or expose legacy CRUD.

Venue module responsibilities include:

  • venue master records
  • space records
  • space-scoped availability and booking workflows
  • multi-space booking support
  • venue-side customer overlays on top of Market parties
  • venue-rental contract lifecycle state
  • Adobe signature orchestration state
  • deposit workflow metadata
  • venue operational readiness
  • venue and per-space reporting
  • imported sleeping venue inventory

Current v1 product rules that the backend must support:

  • 1 company = 1 venue
  • 1 venue = many spaces
  • a space behaves like a lightweight BU-style operational scope
  • one booking may include one or many spaces
  • whole-venue rentals are valid
  • managers can edit operational details
  • admin / tenant superadmin finalize approval-sensitive actions
  • Finance remains the source of truth for financial persistence

Future multi-venue ownership must stay possible, but it is not the current tenant contract.

  • venue records
  • imported sleeping venue inventory before takeover
  • space records
  • venue type catalog imported from legacy Mongo
  • availability blocks
  • booking records (incl. optional eventId / promoterEventId linkage carried from creation through confirmation)
  • venue-side event references / placeholders (NOT the canonical promoter event — see Promoter ↔ Venue event linkage below)
  • venue-side deal structures
  • contract workflow state
  • signature orchestration state
  • venue-side deposit metadata
  • customer overlay data
  • operational templates, checklists, tasks, and readiness state
  • venue reporting views
  • user identity
  • sessions / JWT issuance
  • memberships
  • company / business-unit master data
  • package / entitlement truth
  • canonical Artists party master data
  • canonical geo master data
  • invoice / settlement / ledger truth
  • canonical event records — those live in the Promoter module; Venue stores only references or placeholders for off-platform promoters

Canonical event truth lives in the Promoter module. Venue stores only a reference row in venue_events so finance-status, operations checklists, and reporting can hang off something local without forcing every event consumer to round-trip through Promoter.

Every venue_events row is exactly one of:

  • Real promoter referencepromoter_event_id is set, is_placeholder = false. The Venue row mirrors a canonical promoter event.
  • Placeholder for off-platform promoteris_placeholder = true, promoter_event_id is null, plus placeholder_promoter_name (and optionally placeholder_promoter_email, placeholder_notes). The promoter has not joined Kisum yet; this row holds the venue-side operational state until reconciled.

Three creation paths populate venue_events:

  1. Explicit POST /api/v1/events — strict: must carry exactly one of promoterEventId or placeholder=true plus placeholder promoter context.
  2. Booking confirmation sync (SyncBookingEvent) — resolves in order booking.eventId (existing linked row) → booking.promoterEventId (upsert by (company_id, promoter_event_id)) → placeholder shadow keyed on booking_id. The resolved id is back-linked onto the booking row.
  3. Placeholder reconciliation (POST /api/v1/events/{id}/link-promoter) — promotes a placeholder to a canonical promoter reference once the previously off-platform promoter joins Kisum, mirroring the sleeping-venue takeover pattern.

Rules:

  • PATCH /api/v1/events/{id} may update venue-side operational fields (title, description, status, start/end, spaceIds, placeholder context on placeholder rows) but never mutates promoter_event_id or is_placeholder. Promotion only happens via link-promoter.
  • The (company_id, promoter_event_id) pair is unique when promoter_event_id is non-null — a real promoter event can be referenced by at most one Venue row per company.
  • Promoters exposes GET /internal/events/:eventId (machine key) since 2026-05-27 — accepts publicEventId UUID or Mongo _id. Venue Phase 3 will call it before persist; until then Venue trusts caller format for promoterEventId.
  • identity
  • sessions
  • JWTs
  • company memberships
  • business-unit memberships
  • effective module / permission resolution
  • companies
  • business units
  • commercial catalog
  • subscriptions
  • entitlements
  • canonical counterparties
  • canonical contacts / people
  • country master data
  • city master data
  • obligations
  • invoices
  • payments
  • settlements
  • accounting integration truth

Practical rule:

  • Venue orchestrates venue workflows
  • Finance persists finance truth

Admin venue management must flow through:

  1. Frontend-Kisum-Admin
  2. Backend-Kisum-Admin
  3. Backend-Kisum-Venues

Rules:

  • Backend-Kisum-Admin stays the browser-facing BFF
  • Backend-Kisum-Venues stays the runtime source of truth
  • Admin must not read Venue Postgres directly
  • numeric venue_id is the canonical Admin-facing venue identity
  • sleeping venue takeover approval, audit, reconciliation, and activation are Venue-owned workflow state surfaced through Admin

Venue must not duplicate party master data.

Recommended and current target rule:

  • bookings, contracts, and overlays reference Market company/person ids when possible
  • Venue stores only local overlay data such as:
    • notes
    • preferred terms
    • risk
    • relationship history
    • venue-specific performance context
    • local operational contacts

Venue depends operationally on Finance and should be treated as finance-linked.

At the product level:

  • a company using Venue Management should also have Finance enabled
  • venue-management users should get the Finance visibility required for deposit and settlement workflows

At the persistence level:

  • Venue may own deposit expectations and operational status
  • Finance owns invoice/payment/settlement/accounting truth
  • Current runtime detail: Venue deposit create/update now calls Finance POST|PATCH /api/income in machine source=venue_deposit mode, stores the returned Finance id locally, and should read paid-state back from Finance

Venue owns the canonical venue-rental contract record and its operational lifecycle:

  • draft creation
  • template selection
  • placeholder resolution
  • signer assignment
  • send for signature
  • signature progress
  • signed / declined / expired state
  • attachments and addenda

Adobe Sign is backend-only.

The frontend must never hold Adobe credentials or call Adobe directly.

Tenant-scoped requests require:

  1. Authorization: Bearer <JWT>
  2. x-org: <company_id>

Internal service-to-service routes may use:

  1. X-Internal-API-Key: <VENUE_INTERNAL_API_KEY>

Required fail-closed direction:

  • JWT validation
  • company context enforcement
  • venue module gate
  • granular venue.* permission checks
  • scoped visibility for space-level operations

Current stack:

  • Go
  • Fiber
  • PostgreSQL
  • pgxpool
  • migration-driven schema

Current route namespaces:

  • /api/v1/* for tenant/user routes
  • /internal/* for service-to-service reads

Current implemented route families:

  • venues
  • spaces
  • availability blocks
  • bookings (with optional eventId / promoterEventId linkage)
  • customer overlays
  • deals, contracts (with local signature adapter), deposits (with Finance income sync), event finance-status
  • events (incl. POST /api/v1/events/:id/link-promoter for placeholder reconciliation)
  • operations checklists + reusable templates (incl. event/space assignment and readiness state)
  • reports (utilization / revenue / profitability / customers — Venue aggregations + optional Finance HTTP enrichment via GET /api/income and GET /api/bills)
  • internal venue list/detail/inquiry
  • internal Admin venue CRUD, venue-types, sleeping-inventory, takeover-approvals/audit/reconciliation, activation

Current pending route families:

  • (none for v1; pending work is upstream — real Adobe Sign, deeper Finance handoff, optional Finance-side aggregation endpoints)

The current migration direction includes a hard import path from legacy Mongo.

Imported collections:

  • kisum_data.venues_type
  • kisum_data.venues

Legacy venue types import into the singular Postgres table:

  • venue_type

Key model:

  • venue_type.venue_type_id
    • numeric type id from Mongo
    • primary key

Venue rows link through:

  • venues.venue_type_id
    • FK to venue_type(venue_type_id)

Imported venue inventory lands under one Kisum-owned holding company, not a tenant-owned company.

Imported records are marked:

  • ownership_status = sleeping
  • is_sleeping = true
  • is_claimable = true

Compatibility keys preserved on venues:

  • Mongo _id -> source_mongo_object_id
  • Mongo numeric venue id -> venue_id
  • Mongo unique_id -> unique_id when present

Current DB uniqueness rules:

  • venue_id is enforced unique
  • source_mongo_object_id is enforced unique
  • unique_id is not enforced unique

Imported venue rows should keep raw compatibility values:

  • country
  • city
  • country_iso2

and also resolve canonical Market references when possible:

  • country_id
  • city_id

Important rule:

  • city and city_id may remain NULL
  • unresolved geo ids must remain NULL rather than guessed

This phase is import-only.

Takeover approval and activation are later workflow phases and are not part of the import command itself.

When working in Backend-Kisum-Venues:

  • do not duplicate canonical Artists party records
  • do not redefine Finance truth in Venue
  • do not weaken auth or x-org rules
  • keep /internal/* internal-only
  • treat sleeping-venue import compatibility as real product behavior, not throwaway migration code
  • keep docs explicit about what is live versus still target-state