Skip to content

Migrated from Notion Test approach — https://app.notion.com/p/3d31f8eaa3ad816d9068e64e2118c759

Test approach

Callout Who should read: anyone designing SYS-005 tests (oracle / Karate / Playwright). Callout As of 2026-09-24 IST (re-verified tips unchanged from Sep 23 audit): - API develop tip 94f64f5 (PR #1019). Browser main tip 4a53eab (2026-09-08 IST) — no new commits since. - Oracle = tests/sys005_oracle/ booking-math fixtures (#925) — not a separate product. - Karate API + k6 1VU landed via #974; manual workflow sys005-karate-k6-manual.yml on develop (Epic H packs). Board cards #166–#169 still Backlog pending operator evidence. - CI hard gates: ruff / syntax / pytest tests/unit/ + oracle. Soft: bench || true (#153), coverage not enforced (#154). tests/security/ (S-IDOR #163) is not in ci-quality path yet. - Playwright nightly schedule runs suite=admin + business_admin only; BA Midway often red (outlet “Select location”). Buyout / pay-later / slot-full specs exist but are not on the nightly schedule. - Full board + gap map: TEST coverage recommendations (2026-09-24). How to use: plan only — do not execute bookings or charge Datacap here. Three layers: knowledge base + unit oracle + BDD journeys. Next: Scenario matrix · E2E features · GrokBot role · TEST coverage recommendations (2026-09-24) (latest develop/main coverage audit). Callout Preference order: class-bound unit/oracle + read-only DEV smokes first; UI leftovers in Playwright (reservation-browser-tests). New Outlets of a known class do not expand the matrix.

Knowledge base + test approach (plan only)

Goal: prove a Booking was created and that every dynamic field matches this Business + ServiceItem + BZSchedule — without a new test per SKU.

Do not execute bookings in this phase. Do not charge Datacap (payment_environment=production on DEV).

Why the last pack will lie

Artifact What it is Drift
At The Pier checklist (2026-08-08) Manual PWA/admin script with baked prices Pier deposit listed $15.11 vs Midway/Boardwalk $25; DEV Midway/Boardwalk/Pier deposit is 15.11, Buyout 25. Item min 1–100 vs schedule 8–25. Mixes prod PWA URL with later DEV IDs.
DEV Test Scenarios Smoke lists for ATP + US US Business ID bz-a91424de-… is not Test Seaford bz-977016bb-… or PWA bz-f23c7944-….
Booking Scenarios taxonomy Useful type catalog (plan vs package, deposit vs full, PWA vs desk) Not 80 tests. Dimensions for pairwise.
karate-tests/*.feature API BDD, ATP outlet hardcoded outletId frozen; selectablePackages[1]; 100OFF; Mac .env path; picks first schedule not a live one; no class fingerprint; no DocType assert on duration vs 30-min slot grid.

ATP and United Skates are different classes, not different copies of the same checklist.

The actual problem

Parameters are not in the test. They live on doctypes:

  • item: type, planType, duration, buffer, min/max, buyout, PWA, provider
  • BZSchedule: days, date range, min/max (overrides item), deposit, reservation_slot_type, venue_details, slot start grid
  • venue / resources: which pool, from_number/to_number, buffer_time
  • outlet: tz, payment, advance window
  • pricing_engine: total / deposit / promo

A test that says “8 kids = $79.92” is a snapshot of one Tuesday. A test that says “guestCount = schedule.minGuest; total = oracle.total; end = start + item.bookingDuration” survives both businesses.

Three layers (do all three; they are not alternatives)

┌─────────────────────────────────────────┐
│ 1. Knowledge base (config oracle)       │  class fingerprint + golden SKU
│    read doctypes at run (or daily dump) │  expected snapshot JSON
├─────────────────────────────────────────┤
│ 2. Unit tests (TDD)                     │  classifier + expected math
│    no HTTP, no Datacap                  │  duration, buffer, guest clamp
├─────────────────────────────────────────┤
│ 3. BDD journeys (few, by class)         │  Karate API + thin PWA later
│    Given oracle snapshot                │  When book
│    Then BZBooking matches snapshot      │  not toast, not hardcoded $
└─────────────────────────────────────────┘

1. Knowledge base (this folder + ../ecosystem/)

One class row, one golden live SKU, not 97 United Skates items.

Fingerprint fields we already have: backend, item shape, venue model, buffer, timeslot source, payment, live schedule census.

Expected snapshot (generated, never hand-typed amounts):

class_id
outlet_id / business_id / tz
golden_service_item_id
shape: plan | package | buyout
duration_minutes          ← item.bookingDuration (ATP) or schedule (US if item duration=0)
buffer_minutes
guest_min / guest_max     ← schedule wins over item
slot_grid_minutes         ← BZScheduleSlot.duration_minutes (ATP=30). NOT party length
deposit                   ← schedule upfront
venue_id + resource_from/to
live_days + date_window
addons[] / promos[] that apply
pwa_path                  ← /plans-and-games vs /plans

Oracle rules we already observed:

  • Slot row 10:30–11:00 is a start tile. Booking end = start + package duration (Karate already does this for ATP).
  • US item bookingDuration=0 → duration lives on the session schedule. Different rule than ATP.
  • Filter endDate >= today. Saturday 10am public skate is in the catalog and is dead.
  • Buyout / $0 / immediate_pay=no is a different journey, not packages[1].
  • Never collapse Test Seaford and PWA Seaford Outlets.

Daily job: refresh dump, fail if class fingerprint shape changed (new buffer, new payment gateway). New Outlet of same class = zero new tests (SYS-005).

2. Unit tests — yes. TDD — yes, here only.

Unit-test the oracle, not the rink:

  • classify(service_item) → plan vs package vs buyout
  • expected_end(start, item, schedule)
  • clamp_guests(requested, item, schedule)
  • hold_window(start, end, buffer)
  • live?(schedule, as_of)
  • class_id(outlet, item) → fingerprint row

TDD these with fixtures copied from DEV (Midway 120m + 30 buffer; Super Pass duration 0; Buyout Sunday row monday=1). Fast, no Frappe.

Do not TDD the 20-minute PWA checkout. That is the wrong loop.

reservation-api-server unit tests (pytest on pricing, lock confirm, guest clamp) are the highest leverage for code quality — SYS-005 #849/#850 territory. E2E cannot replace them.

3. BDD — yes, for journeys. Not 97 features.

Keep Karate for API (you already speak it). Rewrite Background:

  • Load datasets/{class}.json (golden ids), not a literal outlet in every feature
  • Call oracle → snapshot
  • One @smoke Scenario Outline: Examples: | class_id |
  • Then GET BZBooking + BZBookingAvailability and match snapshot (status, guests, start, end, amount or deposit, venue, lock window)

Playwright/UI only for what API cannot see: greyed slot, email body, timezone string on calendar. Not the daily gate.

BDD Given/When/Then maps cleanly onto “Given Midway on Arnot, When guest books minGuest, Then booking end is start+120 and deposit is schedule.deposit”. The data comes from the oracle, the story stays in Gherkin.

What to assert (the dynamic contract)

After create+finalize (when a write pass is approved):

Parameter Source of expected On BZBooking
status journey (full vs deposit) booking_status
start chosen live slot start item start (outlet tz)
end oracle duration rule item end ≠ slot 30-min end
guests schedule min (or chosen in range) guest count
amount / deposit pricing_engine.calculate_total and schedule deposit payment fields; they must not disagree with doctypes
venue/resources schedule venue_details availability / resource rows
buffer item + venue lock window = guest ± buffer (ATP 30; US 0)
promo only if oracle says code is live for this outlet discount line

If pricing_engine total ≠ item.basePrice × guests (ATP PerPerson), that is a bug, not a reason to trust the API blindly. Dual oracle: doctypes vs pricing RPC.

Code quality (Karate + apps)

  • Kill hardcoded outletId / packages[1] / Mac .env path
  • Features call karate.call('oracle.feature') or a small JS/Java oracle
  • Do not SKIPPED cart failures as a green run
  • Cancel only bookings this run created
  • No PAN in logs; no production Datacap until sandbox is proven
  • Pairwise (PICT) on the taxonomy dimensions later — not cartesian catalog × day × pay
  • New Outlet of existing class = 0 tests

Explicitly not the plan

  • One test per United Skates public-skate SKU
  • TDD of the PWA
  • Replacing Karate with a new framework this month
  • Running create/pay on DEV until you approve a write pass
  • Using the prod ATP checklist amounts as expected values

Phases

  1. This doc + freeze golden SKUs (Midway, Super Pass, ULTIMATE). Done enough to start oracle fixtures.
  2. Oracle library + unit tests from ecosystem dumps (no HTTP write).
  3. Rebind Karate to oracle + class Examples; assert DocTypes.
  4. Translate the 2026-08-08 ATP checklist into class-parameterized stories (child-count clamp, add-on reprice, deposit vs total, buyout call-only as N/A/xfail).
  5. PICT pairwise on Booking Scenarios taxonomy (channel × pay × extras) once goldens are green.
  6. Thin UI layer for email / greyed slots.

How I help from here (still no execution)

  • Keep the ecosystem dump + fingerprint honest (live vs expired, two US Outlets).
  • Author oracle fixtures and the expected-snapshot schema.
  • Map each old scenario to a class + assert list (or drop it as “same class, zero extra”).
  • Review Karate PRs for hardcoded IDs and 30-min vs duration bugs.
  • Not: 97 new features, GitHub writes, or Datacap charges until you say so.

Phase 0 catalog — Test At The Pier - Arnot Mall (DEV)

Read-only fill from https://bz-api.dev.bookingzone.com on 2026-09-02 00:00 IST, schedules+other doctypes extended 2026-09-02 00:10 IST. Class: VP-FRAPPE-PACKAGE-VENUE-DATACAP-PWA. PWA: https://venuplus.dev.bookingzone.com/booking/bz-4f8920e9-9644-4169-acb4-ba3193083ee7/plans-and-games

Did not fetch BZBooking or BZBookingAvailability. No secrets (API keys, Authorization, jotform_api_key, datacap_tag_config values) are stored.

Counts

Thing Count
Service items (all PartyEvent packages, PWA on) 4
Venues 4 (2 duplicate name-pairs)
Venue resources 6
Schedules (2 per package) 8
Active addons (PWA) 3, none required
Inactive addons on outlet 5
Active promo codes 2 (TEST100, 100OFF)
BZResourceBlock for this outlet 0
Digital waivers 0
Deals 1 bundle

Business

  • Test At The Pier bz-7c4f4061-5ad1-4d1b-a4a8-37cbfd1ced2d
  • Domain atthepierarcade-test, website https://www.atthepierarcade.com
  • Status Active. HQ listed as Myrtle Beach, SC (outlet is Horseheads, NY).
  • Currency USD. tax_enabled=0, tax_rate=0. enable_datacap_preauth=0.
  • LogRocket mzfyro/venuplus-app.

Outlet

  • Test At The Pier - Arnot Mall bz-4f8920e9-9644-4169-acb4-ba3193083ee7
  • Address: 3300 Chambers Road, Suite 5115 Unit J-15, Horseheads, NY 14845. Phone (607) 669-2111.
  • Timezone US/Eastern. Currency USD.
  • Payment: gateway Datacap, payment_environment=production (DEV box — smell).
  • RC/CE/SM: all off (enable_rc_integration=0, enable_ce_integration=0).
  • PWA/online: is_online_booking_enabled=1, is_walk_in_enabled=1.
  • Advance: min 1 hour, max 90 days. Confirmation email / notifications off.
  • operating_hours child on the outlet doc is empty. BZOutletOperatingHours get_list → 403 (child doctype).
  • No blackout doctype exists. Holiday List: empty.

Catalog (4 packages)

All item_type=PartyEvent, package_status=1, session_status=0, pwa_status=1, provider=APP, buffer 30, category Birthday Parties bz-cba80657-415d-4108-917d-76da1b384104. Item date range 2026-04-29 → 2027-04-29.

Package id duration min/max base price buyout immediate pay
Birthday Buyout bz-f9450e32-66b8-41ab-8b1d-59aae29abc6d 120 1 / 100 0.00 (call for scheduling) yes no
The Boardwalk Bash bz-af4c47d4-6b1c-48df-9b42-f293d3901e6a 150 8 / 25 24.99 no yes
The Midway Play bz-3702289d-3778-4d61-9181-28120d5ec1aa 120 8 / 25 17.99 no yes
The Pier Package bz-c971ac8e-27bd-4067-bd97-88f87786ce2b 90 8 / 25 9.99 no yes

Venue on the service-item doc is not a field. Mapping is via BZSchedule.venue_details: all four point at Party Area bz-7fce0186-b3c1-4c76-80ac-2495ea509ed3 (Room). BZServiceItemVenue get_list → 403.

Addon links (same three on every package, is_mandatory=0): Power Up 9.99, Party Supplies 4.25, Super Power 14.99.

Pricing child rows for Pier / Midway / Boardwalk store currency=INR while outlet is USD.

Venue / resource tree

Live category (Active Birthday Parties bz-cba80657):

Outlet Test At The Pier - Arnot Mall
├── Party Area  bz-7fce0186  Room  cap 30  buffer 30   ← used by all schedules
│   ├── Party Room 1  bz-88dccde0
│   └── Party Room 2  bz-508ffbb4
└── Arcade Floor  bz-29539ada  Other  cap 100  buffer 60   ← unused by schedules
    └── Full Arcade (Private Buyout)  bz-4e5229bc

Duplicate / orphan category (Inactive Birthday Parties bz-e1827315 — no packages):

├── Party Area  bz-77d2201b  Room  cap 30  buffer 30
│   ├── Party Room 1  bz-4c8ff221
│   └── Party Room 2  bz-78b1cb96
└── Arcade Floor  bz-5fa371c4  Other  cap 100  buffer 60
    └── Full Arcade (Private Buyout)  bz-fb32761f

All resources is_active=1, status=Available. Schedule venue_details from_number=2 to_number=2 on the live Party Area (both rooms).

Schedules

get_list BZSchedule filtered by outlet is not permitted. Used bookingzone.api.pwa.get_schedules?service_item_id= then GET /api/resource/BZSchedule/{id} for all 8. Slot times are US/Eastern local, not UTC. pwa.get_schedules returns slots: []; slot rows exist on the BZSchedule doc.

No buffer field on BZSchedule. Buffer lives on the service item (buffer_minutes=30) and live Party Area venue (buffer_time=30). per_game_duration=10 is present on every schedule and is not a booking buffer.

All 8: is_active=1, schedule_scope=Date Range, 2026-04-29 → 2027-12-31, reservation_slot_type=session, venue Party Area bz-7fce0186-b3c1-4c76-80ac-2495ea509ed3 Room, from_number=2 to_number=2, booking_type=Reservation, slot increment 30 min, slot duration_minutes=30 (start grid, not package length), slot capacity 25. 16-row and 10-row grids are identical-shape; not dumped row-by-row.

# name schedule_name service_item days dates default active min/max slot_type venue_details slots (first→last) deposit
1 bz-69af4ced-7c8b-4850-af3c-4ec81c125e2f Birthday Buyout — Monday Slots Birthday Buyout bz-f9450e32 Mon only 2026-04-29 → 2027-12-31 1 1 8 / 25 session Party Area bz-7fce0186 2–2 16 · 10:30–11:00 → 18:00–18:30 25 flat upfront
2 bz-25018667-160e-4956-8727-fe3f61562848 Birthday Buyout — Sunday Slots Birthday Buyout bz-f9450e32 Mon only (sunday=0) 2026-04-29 → 2027-12-31 0 1 8 / 25 session Party Area bz-7fce0186 2–2 10 · 11:30–12:00 → 16:00–16:30 25 flat upfront
3 bz-0e2a26dc-5963-4eff-83c1-70f13012737e The Boardwalk Bash — Monday Slots Boardwalk Bash bz-af4c47d4 Mon–Sat 2026-04-29 → 2027-12-31 1 1 8 / 25 session Party Area bz-7fce0186 2–2 16 · 10:30–11:00 → 18:00–18:30 15.11 flat upfront
4 bz-1e37fe84-d324-41a3-8bb8-563775ce55f8 The Boardwalk Bash — Sunday Slots Boardwalk Bash bz-af4c47d4 Sun 2026-04-29 → 2027-12-31 1 1 8 / 25 session Party Area bz-7fce0186 2–2 10 · 11:30–12:00 → 16:00–16:30 15.11 flat upfront
5 bz-326962ca-a3ea-4c95-b40f-d4eead65d844 The Midway Play — Monday Slots Midway Play bz-3702289d Mon–Sat 2026-04-29 → 2027-12-31 1 1 8 / 25 session Party Area bz-7fce0186 2–2 16 · 10:30–11:00 → 18:00–18:30 15.11 flat upfront
6 bz-98dfa75b-baa6-46a7-8fc6-cc2ebeb7d7ae The Midway Play — Sunday Slots Midway Play bz-3702289d Sun 2026-04-29 → 2027-12-31 1 1 8 / 25 session Party Area bz-7fce0186 2–2 10 · 11:30–12:00 → 16:00–16:30 15.11 flat upfront
7 bz-98d0c376-77f6-45ea-b893-856e715af546 The Pier Package — Monday Slots Pier Package bz-c971ac8e Mon–Sat 2026-04-29 → 2027-12-31 1 1 8 / 25 session Party Area bz-7fce0186 2–2 16 · 10:30–11:00 → 18:00–18:30 15.11 flat upfront
8 bz-4335c6a5-1807-4475-aa3d-a704d4eef226 The Pier Package — Sunday Slots Pier Package bz-c971ac8e Sun 2026-04-29 → 2027-12-31 1 1 8 / 25 session Party Area bz-7fce0186 2–2 10 · 11:30–12:00 → 16:00–16:30 15.11 flat upfront

Pattern for Midway / Boardwalk / Pier (healthy): Monday Slots = Mon–Sat 16 starts 10:30…18:00; Sunday Slots = Sunday 10 starts 11:30…16:00; both is_default=1; deposit 15.11 flat upfront.

Birthday Buyout is broken vs that pattern:

  • Both schedules are Monday only.
  • “Sunday Slots” has sunday=0, monday=1, is_default=0.
  • Schedule minGuest 8 / max 25 (item is min 1 / max 100).
  • Deposit 25 flat. Venue still Party Area, not Arcade Floor.
  • single_party_booking=0 on Buyout vs 1 on the other six.

Promos

Method that actually exists: bookingzone.api.promocode.get_active_promo_codes?outlet_id=&business_id=. pwa.get_active_promo_codes and customer.get_active_promo_codes → 417 (no attribute). Missing business_id → 400.

code discountType status value window min purchase
TEST100 Percentage Active 100% (cap 1000) 2026-08-26 → 2026-09-30 50
100OFF Percentage Active 100% (cap 1000) 2026-08-27 → 2026-09-30 80

Both Coupon, outlet-scoped (enableForAllOutlets=0), this Arnot outlet only, not restricted to service items.

Addons

bookingzone.api.customer.get_addons and pwa.get_addons_by_outlet return the same 3 active addons. pwa.get_addons → 417.

name type price required PWA
Party Supplies Add-On Accessory 4.25 / guest no yes
Power Up Add-on Service 9.99 / guest no yes
Super Power Add-On Service 14.99 / guest no yes
Pizza Party Package Food & Beverage 5.99 — inactive
Extra $10 Play Cards Accessory 8.99 — inactive
Extra 30 Min Party Time Service 49.99 — inactive
Ice Cream Cake Food & Beverage 29.99 — inactive
Goodie Bags Accessory 4.99 — inactive

Other doctypes

frappe.client.get_list DocType [["name","like","BZ%"]] limit 200 + page 2 → 250 BZ* names (56 child/istable, 1 single BZSettings). Did not fetch BZBooking / BZBookingAvailability. Child get_list is typically 403. outlet_id / business_id filters are typically 417 Field not permitted (use outlet / business).

Has data for this outlet or business

Doctype What Filter n Rows
BZServiceCategory Catalog grouping business 2 Birthday Parties Active bz-cba80657; duplicate Inactive bz-e1827315. outlet filter = 0.
BZDeal PWA bundle outlet 1 bz-73b49bf3 “At The Pier Party Packages — Arnot Mall”, Bundle, Active, 2026-04-29→2027-04-29, 9.99 / orig 24.99, minQty 8 max 100. Items: Pier 9.99, Midway 17.99, Boardwalk 24.99. Buyout not in the bundle.
BZAddon Add-on SKUs outlet 8 3 active PWA + 5 inactive (see Addons).
BZPromoCode Discount codes business 2 TEST100, 100OFF. outlet filter 417.
BZTag Service tags business 6 3 unique names duplicated: Arcade, Kids, Birthday Parties (ServiceTag, Active). outlet = 0.
BZManager Desk users business 6 test/test1/test2/test3 arnot + ATP Test + testatp admin; 3 are business admin.
BZManagerOutlet Manager↔outlet outlet 3 mgr-983d9eb3, mgr-85774403, mgr-7ab2f7ec. can_view_bookings=1, create/edit/cancel=0.
BZAdminOutletMapping Admin↔outlet outlet 3 all is_primary=1 is_active=1.

Unscoped (no outlet/business field; not proven for this outlet)

Doctype What n (unfiltered sample) Notes
BZGameCardType Game-card product types 5 ATP Play Card (ATP-GCT-PLAY) + clone bz-bdaeea42 (same At The Pier description). Gold Membership / Standard Prepaid / VIP Member look like global seed.
BZTopupPackage Top-up SKUs 5 Quick $10 … Mega $200. Likely global seed.
BZBookingForm Jotform-style forms 5 Names BKFRM-JF-*. Docs not fetched (jotform).
BZPromoCodeUsage Redemption log 5 Sample names only; not fetched.

Empty for this outlet/business (get_list 200, count 0)

BZResourceBlock (outlet), BZDigitalWaiver (outlet+business), BZService, BZPluginConfig, BZEmailTemplate, BZMembershipPlan, BZMembership, BZGiftCard, BZKiosk, BZEvent, BZCommunicationWorkflow, BZDailyReportConfig, BZMailchimpOutletMapping, BZKitchenStation, BZPageBlock, BZBookingPage, BZVirtualQueue, BZRentalAssetPool, BZRentalAssetCategory, BZMovie, BZHotelRoomType, BZLockerBank, BZLockerType, BZServiceAccounting, BZCRMPipeline, BZWebhookConfig, BZTicketType, BZMultiDayPricing (unscoped 0), Holiday List (0), Item Tax Template (0), Sales Taxes and Charges Template (0), Tax Category (0), Tax Rule (0).

Taxes: all zeros on business/outlet. No waiver docs. No holiday calendar. No operating hours child on the outlet doc.

403 — child / istable get_list not permitted

BZOutletOperatingHours, BZScheduleSlot, BZScheduleVenueDetail, BZScheduleSingleDate, BZSchedulePurchaseItem, BZScheduleKioskGameCard, BZServiceItemAddon, BZServiceItemPricing, BZServiceItemPriceDayTime, BZServiceItemVenue, BZServiceItemQuestion, BZServiceItemWaiver, BZServiceItemRule, BZServiceItemProcessingFee, BZServiceItemGameCard, BZServiceItemImage, BZServiceItemTag, BZServiceItemKioskGameCard, BZServiceItemKitchenTag, BZSlotPricing, BZAddonTag, BZDealItem, BZPromoCodeOutlet, BZPromoCodeServiceItem, BZVenueBookingRule, BZOutletPaymentTag, BZCenterEdgeMapping, BZReserveCloudMapping, Holiday (child).

Slot / venue_details / addon / pricing children were read from the parent docs (BZSchedule, BZServiceItem, BZDeal), not via child get_list.

404 — doctype does not exist

BZServiceConfig, BZBlackout, BZWaiver (actual is BZDigitalWaiver), BZTax (use ERPNext tax templates, all empty).

417 / other

  • BZSettings (Single): outlet/business 417; unfiltered get_list 500.
  • Field not permitted outlet on BZPromoCode, BZGameCardType, BZTopupPackage, BZBookingForm, BZPromoCodeUsage, BZMultiDayPricing, BZManager.
  • Field not permitted venue / outlet_id on BZResourceBlock (outlet works, count 0).

Gaps / smells

  1. Duplicate venues — two Arcade Floors and two Party Areas with identical names/caps/types. One pair is tied to an Inactive duplicate “Birthday Parties” category and is unused.
  2. Buyout does not use Arcade Floor — is_buyout=1 and max 100 sit on a Party Area (cap 30) schedule. Full Arcade resources never appear in venue_details.
  3. Buyout days broken — Monday-only; the “Sunday Slots” row is also Monday. Tue–Sun have no Buyout schedule.
  4. min/max mismatch — Buyout item 1–100 vs schedule 8–25.
  5. reservationSlotType=session on package items. Slot duration_minutes=30 is a start grid, not the 90/120/150 package length.
  6. Pricing currency INR on three packages vs USD outlet/business.
  7. payment_environment=production on DEV Datacap outlet.
  8. Empty outlet hours; item end date 2027-04-29 vs schedule end 2027-12-31.
  9. Five inactive addons configured but hidden from PWA.
  10. Deal omits Buyout — bundle items are Pier / Midway / Boardwalk only.
  11. Duplicate tags — Arcade / Kids / Birthday Parties each exist twice on the business.
  12. All three BZAdminOutletMapping rows are is_primary=1.

Endpoint errors (skipped, not guessed)

  • 417 bookingzone.api.pwa.get_addons — no attribute
  • 417 bookingzone.api.pwa.get_active_promo_codes / customer.get_active_promo_codes — no attribute (working path is bookingzone.api.promocode.get_active_promo_codes)
  • 400 promocode method without business_id
  • 403 child get_list: BZServiceItemVenue, BZOutletOperatingHours, BZPromoCodeOutlet, BZOutletPaymentTag, BZScheduleSlot, BZServiceItemAddon, BZServiceItemPricing, and other istable children listed above
  • Field not permitted: BZResourceBlock.venue, BZResourceBlock.outlet_id; BZPromoCode.outlet; GameCardType/Topup/BookingForm/PromoCodeUsage outlet+business
  • 404 doctypes: BZServiceConfig, BZBlackout, BZWaiver, BZTax
  • 500 BZSettings unfiltered get_list (Single)