Files
suaveplan/openspec/changes/enterprise-r3f-booking/proposal.md
2026-05-27 23:29:53 +01:00

3.1 KiB

OpenSpec Change: enterprise-r3f-booking

  • Change ID: enterprise-r3f-booking
  • Package: @suaveplan/r3f-booking
  • Category: r3f/commerce
  • Target path: r3f/commerce/r3f-booking
  • Status: PROPOSED
  • Date: 2026-04-24
  • Reference spec: /mnt/s/web/suaveplan/enterprise/r3f-booking.md

Summary

Deliver @suaveplan/r3f-booking on the genesis branch from scratch at enterprise quality. The package provides interactive 3D venue maps for seat/space booking — concert halls, stadiums, offices, conference rooms. It ships <VenueMap />, <VenueSeat />, <VenueSection />, <VenueFloorPlan />, and a useVenueSelection hook. Seats have availability states (available/reserved/selected/disabled), animated selection feedback, accessible keyboard navigation, and a JSON venue schema for data-driven layout. Storybook stories for every component; Vitest + @testing-library/react tests.


Current-state audit (genesis)

Does not exist on genesis — fresh build.


Available workspace deps on genesis

Same R3F + React stack as enterprise-r3f-earth, plus no additional deps.


Public API surface

function VenueMap(props: VenueMapProps): JSX.Element
function VenueFloorPlan(props: VenueFloorPlanProps): JSX.Element
function VenueSection(props: VenueSectionProps): JSX.Element
function VenueSeat(props: VenueSeatProps): JSX.Element
function useVenueSelection(options: UseVenueSelectionOptions): VenueSelectionState

interface VenueMapProps {
  venue: VenueDefinition
  selectedSeats?: string[]
  onSeatSelect?: (seatId: string) => void
  onSeatDeselect?: (seatId: string) => void
  maxSelectable?: number
  colorScheme?: VenueColorScheme
  cameraControls?: boolean
}

interface VenueDefinition {
  id: string
  name: string
  sections: SectionDefinition[]
}

interface SectionDefinition {
  id: string
  label: string
  rows: RowDefinition[]
  color?: string
  position: { x: number; y: number; z: number }
  rotation?: number
}

interface RowDefinition {
  id: string
  label: string
  seats: SeatDefinition[]
}

interface SeatDefinition {
  id: string
  label: string
  status: 'available' | 'reserved' | 'disabled'
  category?: string
  price?: number
}

type VenueSelectionState = {
  selected: string[]
  select: (seatId: string) => void
  deselect: (seatId: string) => void
  clear: () => void
  isSelected: (seatId: string) => boolean
}

File layout

r3f/commerce/r3f-booking/
  package.json
  tsconfig.json
  vitest.config.ts
  src/
    index.ts
    error-codes.ts
    types/
      r3f-booking.types.ts
      r3f-booking.types.md
    components/
      venue-map/ (tsx + md + types + test + stories + index)
      venue-floor-plan/ ...
      venue-section/ ...
      venue-seat/ ...
    hooks/
      use-venue-selection/
        use-venue-selection.ts / .md / .test.ts / index.ts
    schemas/
      venue-schema/
        venue-schema.ts / venue-schema.md / venue-schema.test.ts / index.ts

Impact

Downstream: booking UI, event ticketing, office space booking.

Prerequisites on Verdaccio: @suaveplan/error, @suaveplan/types, @suaveplan/logger.