The Simulation page creates a brand-new event in the Customer Representation model. Use it to probe model behaviour without affecting real data. The route /simulation is gated by Permissions.simulation.

What you’ll build

  • A form for the event fields (name, description, category, venue, capacity, date/time, price, lineups, setlists, optional special-ad category).
  • Multi-date support — but only in event mode (see below).
  • A submit handler that POSTs to the CR API (one POST per date entry).

Prerequisites

  • An authenticated user with Permissions.simulation.
  • X-Preferred-Partner-Id set.

Gating and mode selection

Mode is not driven by Permissions.prisma / Permissions.fdlive. The reference FE selects based on:
  • hasPartialServiceAccessTier() — partner product PRISMA or FD_FULL_SERVICE (read from partnerDetails.product in browser storage)
  • location.state?.from === 'wave'
  • the current category (product vs non-product)

The call chain

On mount: nothing — the form is client-side until submit. On submit (one call per date entry):
MethodURLHost
POST/events/?event_type={prisma|fdlive}CR API
event_type is derived from hasPartialServiceAccessTier() / wave-origin plus the event category — not from a UI toggle. There is also a separate submit branch for Wave scenarios.

Multi-date behaviour

  • Event mode (SimulationFormDefault) supports “Add dates and venues” — multiple entries, one POST each.
  • Prisma / product mode (SimulationFormPrisma) renders only a single date block; there is no “add dates” action. The submit loop exists, but in product mode users typically submit a single entry.

Payload shape

{
  "name": "Probe — Test Concert",
  "description": "...",
  "venue": "Olympiahalle",
  "capacity": 12000,
  "city": "München",
  "category": "concert",
  "hall": "Main Hall",
  "price": 75,
  "lineups": [
    { "artist_name": "Headliner", "artist_type": "main" }
  ],
  "setlists": [
    { "artist_name": "Headliner", "track": "Opener" }
  ],
  "status": "RUNNING",
  "special_ad_category": []
}
FieldShape
Lineups[{ artist_name, artist_type }] (not { name, starts_at })
Setlists[{ artist_name, track }]
Pricescalar number (not nested { min, max })
statusalways "RUNNING"
special_ad_category[] by default; on the special tab, an array of the selected value(s)
Date format needs contract confirmation. The reference FE formats dates with moment(date).format('DD.MM.YYYY') (e.g. 15.09.2026), not ISO YYYY-MM-DD. Validate the expected format against the backend before relying on either — this is a known doc/API mismatch risk.

Reference implementation

import { fdCr } from "./fd-cr";

export async function createSimulationEvent(
  payload: SimulationPayload,
  eventType: "prisma" | "fdlive",
) {
  return fdCr.post(`/events/?event_type=${eventType}`, payload);
}

// Multi-date submit (event mode)
export async function submitSimulationForm(
  rows: SimulationPayload[],
  eventType: "prisma" | "fdlive",
) {
  const results = await Promise.allSettled(
    rows.map((r) => createSimulationEvent(r, eventType)),
  );
  const failed = results.filter((r) => r.status === "rejected");
  if (failed.length) {
    throw new Error(`${failed.length} of ${rows.length} entries failed`);
  }
  return results;
}
After a successful submit, the reference FE navigates to /.

Gotchas

Not prisma/fdlive permission enums.
POST /events/?event_type=... on the CR API — different host.
Prisma/product mode is single-date in the UI.
Lineups artist_name/artist_type, setlists artist_name/track, scalar price, status: "RUNNING" always, special_ad_category is an array.
Confirm the backend contract — possible mismatch with ISO dates used elsewhere.