Data & reset testing tool
Shows every event currently stored on the BFE Worker (D1), with row counts, so you can see exactly what's there before testing or retesting Setup or Close Round — instead of guessing whether earlier testing left records behind. Delete wipes that event completely: its rounds, roster, and any saved round results/skins. Cannot be undone. This does NOT touch Jotform — a round's scorecard test submissions live there, not here, and aren't affected by anything on this page. It also doesn't touch player profiles or venue tee catalogs, which are meant to persist across events.
Click Refresh to see what's currently stored.
Membership HCP review & sync admin tool
One screen to review and fix EVERY member's HCP in bf_players (the central, D1-native HCP record — separate from any single event's roster) — not just whoever GHIN matches. Paste the whole GHIN roster page below (Ctrl+A, Ctrl+C on ghin.com is fine — this searches the whole pasted blob, same matching approach as the per-event GHIN paste in Setup) and click Preview: every active BF member is listed with whatever GHIN match was found AND their current bf_players value/source, side by side. A GHIN match pre-fills the row with ghin_import (gospel — always applied, never flagged, clears any self-report lock). A member with no GHIN profile (someone who tracks their own HCP another way) is listed too, showing their last known D1 value — pick manual or estimated from the row's Source dropdown and enter their number yourself; nothing is written for a row you leave unchecked. Requires the commissioner PIN below (same as other write actions on this page) for every source except player self-report, which isn't available from this admin screen.
Generate test scorecards testing tool
Writes REAL submissions to the Scorecard Jotform form — one per player currently in section 3's roster — so Close Round has something to score without hand-keying 16 scorecards. Per-hole points are drawn from your actual 3-year field distribution (Series Stats thru Event 9: ~22% bogey-or-worse, ~38% bogey, ~35% par, ~5% birdie, eagles ~1-in-1100 holes), shifted per player toward their own computed quota rather than one flat average — so results should experientially read like real Wally golf, not just legal point values. Still random, not a real round. Pick a 2Man round instead and this generates one scorecard per TEAM (from the saved draft in section 11), skill-centered on the team's average quota — same distribution, same idea, just one submission per pair instead of per player. These submissions show up in Jotform's own dashboard exactly like real ones and are NOT touched by Data & Reset above — delete them there yourself once you're done testing a round.
Uses the SAME round selected above, plus that round's venue's CTP holes (Section 5 — leave that blank and this has nothing to claim). Writes REAL claims to the CTP Jotform form: a realistic 2-4 claim progression per hole (mostly improving, like groups leapfrogging each other through the day), PLUS three deliberate canary claims to prove the specific rules Close Round depends on — one hole gets a later claim that's intentionally FARTHER (proves the winner is timestamp-based, not distance-based), one claim is tagged with a wrong/mismatched round name (proves cross-round bleed can't happen), and one claim lands on a hole this round hasn't configured for CTP (proves it's silently ignored, not silently paid). We don't have real tee-time groupings in this model, so this can't replicate WHO would naturally submit when — it replicates the submission PATTERNS (staggered timing, superseding claims, stray/mismatched data) that actually exercise the matching logic, which is what determines correctness.
1. Event basics
Sets the key this config is saved under on the BFE Worker, and how player HCPs behave through the event.
For a multi-day event, use Round 1's date here — this is what drives the historic-event filter in section 3's registration-event dropdown, not a full per-round schedule (not yet built). Event end date is optional and only feeds the results page header's date range (e.g. "Sep 11–13, 2026") — leave it blank for a single-day event.
2. Connections
Where Setup pulls live data from. The BFPortal URL sources venues (and, later, D1-native Gatherings registration); the BFE Worker URL is where this event's config, tee catalogs, and player profiles are saved.
3. Registration & roster
Pulls from the shared BF "Event Registration" Jotform (the same one GS's Pre-Event Setup uses) — load its event names, pick this event, then fetch just its registrants (Register? = Yes/Sub). If this event has its own dedicated form instead, paste that form's ID/URL below and skip the event picker — every submission on a dedicated form belongs to this event. HCP isn't captured at registration — resolve it below in Quick HCP once venues/tee policy are set.
| Name | HCP | Last known (on file) | Withdrew? |
|---|
4. Rounds
Fully host-defined — add as many rounds as this event needs, in play order. Each stableford round's quota automatically chains from the most recent earlier stableford round (skipping non-stableford rounds like a 2Man scramble); mark "Rolls into Overall" off for standalone rounds. Round names can still be typed fresh, but Load round names below pulls real names, dates, and venues from both Jotform Request Event submissions and D1-native Gatherings — pick one from the list a name field offers rather than retyping it, and its tee time is captured automatically (Dev-83 — needed so photo/video timelines can tell "on course" from "before/after" without a host-built schedule). Venue auto-fills too where it can (Dev-84) — reliably for a Gathering (its venue already comes from the real Venue Manager list), best-effort for Jotform (its Location field is freeform text, matched the same way portal.html already matches "Honesdale GC" to "Honesdale Golf Club") — but it only fills a blank Venue dropdown, never overrides one you've already set, so load venues above first if you want this to work.
| Round name | Engine | Venue | Holes | Wally Ball pts | Overall? |
|---|
4b. Team Cup new
Saving: section 7's "Save config" saves the event and this card together, and loading a saved event brings this card back. The button below saves just this card. For a two-sided match-play event (the BF Cup). Name the sides and captains, set the points, and describe each day's segments. Teams, pairs and matches are filled in by the captains' selection tool; this card shows how far along they are. Nothing here is specific to one event: any host can set a team event up the same way.
5. Tee policy
Same tee vs. by-HCP-tier is a one-time, event-wide choice. But different rounds can be at different venues, and different venues have different tee names and slopes — so the actual tee/slope values are captured separately, once per venue, below. A venue's block appears here once a stableford round above has that venue selected.
Add a stableford round above and pick its venue to see a tee policy block for it here.
6. Payout
Uses the same proportional formula as the BFSeries payout: podium 20% of pool (weighted split), CTP 15% spread across the round's CTP holes, remainder to skins. The Overall pot is podium-only (no CTP/skins). Wally Ball is a separate winner-take-all pool, split evenly if more than one player never loses the ball.
7. Save on the Worker
Rebuilds the config from whatever's currently in sections 1–6 and persists it into the Competitive Events tables (bfe_events → bfe_event_rounds → bfe_event_roster), keyed by the event name above — a real parent/child structure, not a single document (and, if checked in Tee policy, updates that venue's saved tee catalog too). You don't need to click "Generate event config" first — Save always regenerates from the current form right before it persists, so it can't send stale data. Generate on its own is still there if you just want to preview the Review tables below without saving. To load an event back, use Load in the Data & reset list at the top of the page — it picks from what's actually stored instead of retyping a name you might get wrong.
11. Player groupings
Assigns players to foursomes for one round. Social actively avoids repeating a pairing from any other round you've already saved groups for (whatever's saved for other rounds becomes its "already played together" history — generate/save rounds in any order, it just reads what's there). By quota flights by each player's entered handicap (Group 1 = lowest handicap). By standings flights by current Overall standing through whatever rounds are already closed — only selectable once a prior round in this event has results saved. Random is a plain shuffle. Generate first — it doesn't save anything by itself — then use each player's "Move to…" picker to hand-adjust before you Save.
After the ranking round closes, the bottom 8 players ("captains") each draft one partner from the top 8, worst rank first — 16th picks first, down through 9th, and whoever's left in the pool when it's 9th's turn is their partner. Fully manual, on purpose — run it live (at the pub, on the course, wherever) and tap picks in as they happen. Use Swap afterward if two teams get traded around informally; nicknames are optional and just for this event, no history kept.
8. Close a round
Pulls that round's scorecards straight from Jotform, computes skins and Closest-to-Pin, and saves the result — round pot payout included (podium, skins, and CTP). "Stableford quota" rounds also run the individual quota engine (including any Wally Ball bonus) and feed Overall Standings. "2-man scramble" rounds close against the teams saved in section 11 (Player groupings → Draft) instead of the individual roster — one scorecard per team, ranked by that team's score against a TEAM quota (the two partners' own current individual quotas averaged — read from the most recent closed stableford round, must be closed first) — and never feed Overall Standings, no matter what this round's "Rolls into Overall" box in section 4 says. CTP always pays the individual who's the most-recent qualifying claimant on each hole configured for this round's venue in section 5 — same rule the live leaderboard uses, even in a team round. Load or Generate the event above first.
10. Publish results page Phase 3
Builds the player-facing results page (round-by-round leaderboards, Skins/CTP, Wally Ball tracker, and Overall standings once every round rolling into it is closed) straight from what's already saved in bfe_round_results/bfe_round_skins/bfe_round_cttp — nothing here re-runs the scoring engine, it only reads back what Close Round already computed and pushes it to docs/<path> via the main Worker's existing /deploy route (same mechanism portal.html uses). Safe to re-run any time a round changes — it always overwrites the same page. Preview first; nothing is published until you click Generate & publish.
🩹 Fix a round's Trip Memories boundary (optional)
Trip Memories normally figures out when a round's "On Course" chapter ends on its own — from Close Round, or from Live Panel photo/note timestamps if you forgot. If neither happened (nobody captured anything through Live Panel that round, or you're fixing the boundary after the fact), photos/notes taken afterward can land in the wrong chapter. Set an exact cutoff time here and it overrides everything else for that round — closed_at included.
🗂️ Trip Memories alignment (review & re-bucket)
Lists every Trip Memories photo, video, and note for this event, grouped by the chapter it's currently landing in — the exact same grouping Preview/Publish above uses, built by the same buildMemoryChapters() function. Use this to spot anything that landed in the wrong chapter and move it. Reassigning an item sets its round_name directly, overriding whatever timestamp-based guess placed it; pick "— Untagged (auto-place by time) —" to clear an override and let it fall back to automatic placement.