Ballina Athletics Club

Processor Guide โ€” 2026 Season

Step-by-step reference for the race coordinator. Covers pre-season setup, race day processing, and season management.

๐Ÿ“‹ App Guide ๐Ÿ“‹ Processor Guide ๐Ÿ“ Logic Reference
๐Ÿ†•

What's New in Version 3

Version 3 introduces Supabase as a read-first data layer, clarifies the early runner dual-role rule, and confirms the Wrong Hcp DOS-parity formula is active.

Supabase reads Results and handicaps now read from Supabase first with Google Sheets as an automatic fallback. The public results page is faster as a result.
Supabase mirror Results are mirrored to Supabase automatically after every Confirm & Save, via supabase-mirror.js. No manual action needed.
Early runner + volunteer If an early runner also volunteers in the same week, they receive the higher of their position points or the volunteer floor of 8 points. This rule is now formally documented.
Wrong Hcp formula confirmed The DOS-parity formula for Wrong Hcp handicap adjustment is applied โ€” this was previously misunderstood. Both early-start and late-start Wrong Hcp runners have their handicap adjusted using the effective finish time formula.

๐Ÿ—๏ธ

System Overview

The BAC Handicap App manages 24 weeks of cross-country handicap racing. Runners receive staggered start times based on their handicap. Placings are determined by clock finish time within each distance ร— gender ร— age group.

Key terms

TermMeaning
HandicapYour personal start time advantage. Updated after each race based on how your run time compared to the target finish time.
Clock finishThe actual time you crossed the line from the stopwatch. Used to determine your placing.
Run timeClock finish minus your handicap. Used to compute your next handicap adjustment.
PlacingYour rank within your distance ร— gender ร— age group for the week. Based on clock finish time โ€” earliest finisher wins.
Season24-week series, split into 6 monthly blocks of 4 weeks each.

Data storage

Google Sheets Primary write destination for results, runners, and volunteers. The BAC Handicap 2026 spreadsheet holds all live data.
Supabase Project lrfhvesylfwbabzxbqhr. Read-first source for results, handicaps, and result-weeks. Results are mirrored here after every save. Handicaps are derived from the latest results.handicap per (name, distance) โ€” there is no separate handicaps table.
๐Ÿ’ก
When you click Confirm & Save, results go to Google Sheets first. The system then mirrors them to Supabase automatically. No separate action needed.

Target finish times

DistanceTarget finish time
1K26:00
3K38:00
6K44:00

๐Ÿ“…

Before Race Day

Complete these steps before the season opens. Most are one-off tasks โ€” once done, weekly processing follows the Race Day workflow.

  1. Set up the Google Sheet Confirm the BAC Handicap 2026 sheet is in place. Run the Setup script if starting fresh โ€” it creates all required tabs and seeds the config.
  2. Assign bib numbers Check that all registered runners have bib numbers. Use Admin โ†’ Assign Bibs for any PENDING runners who registered without an auto-assigned bib.
  3. Set opening handicaps Load each runner's opening handicap from the DOS master list. Handicaps are set per runner per distance.
  4. Apply the season reset Subtract 2 minutes from every runner's handicap at season start. This levels the field relative to the prior season's finishing handicaps.
  5. Test mode verification Run the full race-day workflow against the test sheet before the first live race. Confirm standings, handicap updates, and monthly prize computation all work correctly.
  6. Distribute the App Guide Share the App Guide link (/guide) with the committee and regular volunteers so they know how to use the stopwatch and volunteer portal.
โš ๏ธ
Season reset removes 2 minutes from every runner's handicap. Confirm this has been applied before Week 1 results are processed.

๐Ÿƒ

Race Day Processing

Follow these steps in order every race week. Each step builds on the previous โ€” don't skip ahead to Confirm & Save before reviewing.

Step 1 โ€” Enter the stopwatch times

The finish line volunteer uses /stopwatch to record a lap time for each finisher. After the race, they tap Sync to Sheet, which pushes the laps to the Week N Stopwatch tab in Google Sheets. In the main app (Timesheet), click Import Stopwatch to pull those times in.

๐Ÿ’ก
If Sync to Sheet fails (no internet at the course), the volunteer can use Download CSV or Copy to Clipboard as a backup. Import from the main app later using the single-file CSV option.

Step 2 โ€” Enter Early Runners

Early runners started ahead of the main field with a watch timer. Enter each one manually on the Timesheet: enter their bib, start time (their handicap), clock finish time, distance, and mark the entry as Early runner.

๐Ÿ’ก
An early runner can also volunteer in the same week. If they do both, they receive the higher of their position points or the volunteer floor of 8 points. Example: finishing 4th earns 8 pts โ€” same as volunteering, so they get 8. Finishing 3rd earns 10 pts, so they get 10.

Step 3 โ€” Mark Wrong Hcp and Time Trial entries

Wrong Hcp The runner started at the wrong time. Mark the entry and enter the time they actually started. The system applies the DOS-parity formula to compute their correct new handicap.
Time Trial Runner ran for personal time, not placing. Mark as Time Trial โ€” they receive 5 points and their handicap adjusts normally using the standard formula.

Step 4 โ€” Enter DNFs

Mark any runner who did not finish as DNF. Their handicap is NOT adjusted โ€” the stored value is kept unchanged. A start time of 0:00 and a finish time of 99:00 are placeholder values stored for DNF entries; they are not real times and are not used in any calculation.

Step 5 โ€” Review Results

Click Review Results. The app runs sanity checks covering duplicates, suspicious times, missing entries, and age group issues. Fix anything flagged before proceeding to save.

Step 6 โ€” Confirm & Save

Click Confirm & Save. The system:

  1. Writes to Google Sheets Results go to the current week tab and the main Results tab.
  2. Updates each runner's handicap Applies the standard adjustment formula (or DOS-parity formula for Wrong Hcp entries).
  3. Recalculates standings Season standings are rebuilt from all saved weeks.
  4. Creates per-week backup tabs Week N Results and Week N Handicaps tabs are created automatically for audit purposes.
  5. Mirrors results to Supabase All results are written to the Supabase database so the public results page can serve them quickly.

๐Ÿ•

Handicaps

A runner's handicap is their personal start time advantage. It is updated after every race they complete (excluding DNF). There is no separate handicaps table โ€” handicaps are derived from the most recent saved result per (name, distance).

Where to see handicaps

Current Handicaps tab In the main app โ€” shows each runner's latest handicap per distance. Updates immediately after Confirm & Save.
/results The public results page has a Handicaps tab โ€” a public view of the current handicap list. Reads from Supabase first.
Handicap Preload On the Stopwatch/Timesheet โ€” pre-fills each runner's start time for the upcoming week based on their current handicap.

Standard adjustment rules

How you ran vs targetHandicap change
Finished early (faster than target)+seconds early, rounded UP to nearest 10s
0โ€“60 seconds lateNo change
61โ€“120 seconds lateโˆ’10 seconds
More than 120 seconds lateโˆ’20 seconds

Wrong Hcp formula

When a runner starts at the wrong time, the system computes an effective finish time as: storedHandicap + (clockFinish โˆ’ actualStart). The standard adjustment formula is then applied to that effective finish time. Both early-start and late-start Wrong Hcp runners have their handicap adjusted this way.

DNF

No handicap adjustment is made for DNF entries. The stored handicap is kept unchanged regardless of what time appears on the Timesheet.


๐Ÿ‘Ÿ

Managing Runners & Registrations

Runners register via the Google Form and appear in the Runners tab as PENDING until a bib is assigned. Walk-up entrants need to be added manually before their results can be saved.

  1. New registrations via Google Form Runners who complete the registration form appear in the Runners tab with PENDING status. Sync the form responses using Admin โ†’ Sync Registrations to pull in the latest entries.
  2. Assign bib numbers Go to Admin โ†’ Assign Bibs, or use the Register tab. Bib numbers are permanent within a season โ€” do not reassign a bib that has already been used in a result.
  3. Walk-up entrants Use Admin โ†’ Register a Runner to add anyone who didn't fill in the form before race day. Assign them a bib before entering their result on the Timesheet.
  4. Name resolution Long hyphenated names may truncate in source data. If a runner's name doesn't match, add the variant to data/name-aliases.csv rather than editing result rows directly.
โš ๏ธ
The system flags duplicate bibs โ€” if the same bib appears twice in one week, remove the duplicate from the Timesheet before saving. Do not reassign bibs that have been used.

๐Ÿงช

Using Test Mode

Test mode lets you run the full processing workflow against a test dataset without affecting any live data. Use it before the first race week and whenever you want to verify a change.

Enabling test mode

Add ?test=1 to the main app URL. The app switches to the test Google Sheet and displays a TEST MODE banner at the top of the page.

Pre-season checklist in test mode

  1. Set up the test sheet Populate the test sheet with sample runners and opening handicaps.
  2. Import a sample stopwatch CSV Use a CSV with realistic lap times to simulate a full race day import.
  3. Process a full week Run through the complete workflow โ€” import, mark specials, review, save. Verify placings, handicap changes, and standings all look correct.
  4. Verify monthly prize calculation Use Admin โ†’ Monthly Prizes in test mode to confirm the computation and tie-break logic works as expected.
  5. Return to live Remove ?test=1 from the URL to return to the live sheet. Confirm the TEST MODE banner is gone before processing any live race.
โš ๏ธ
Confirm the TEST MODE banner is visible before saving during a test run. Saving to the live sheet by mistake is difficult to undo.

๐Ÿ™‹

Volunteer Management

Volunteers sign up via /volunteer (no PIN required). Their signup is written directly to the Google Sheet roster. Viewing the roster and cancelling signups is also handled from that page.

Points

Volunteers who don't run earn 8 points for that week, assigned to their preferred distance. If a runner does an early start AND volunteers in the same week, they earn the higher of their position points or 8 โ€” whichever is greater.

๐Ÿ†
Early runner + volunteer in the same week: if they finish 4th (8 pts) they get 8. If they finish 3rd (10 pts) they get 10. The volunteer floor never reduces points already earned by racing.

Viewing the roster

The volunteer page shows current week assignments and the next three upcoming weeks. Use this to see where help is still needed before race day.

Volunteer roles

RoleDescription
FinishRecord finish order and confirm runners through the line.
MarshalGuide runners safely around the course and key turn points.
Numbers / TokensHand out tokens or record bib numbers at the finish.
GeneralFlexible help โ€” setup, pack-up, or wherever needed on the day.

๐ŸŽ

Monthly Prizes

The season is split into 6 monthly blocks of 4 weeks each. A prize winner is determined per age group ร— gender ร— distance for each block.

Prize rules

Winner Most points accumulated in the block within the runner's age group ร— gender ร— distance category.
Tie-break Most weeks run in the block. If still tied, the system preserves the current order โ€” flag for manual review.
One-win rule Once a runner wins a monthly prize, they are excluded from winning again in future months that season. They still accumulate points and appear in standings normally.
Volunteers Volunteers who don't run accumulate volunteer points towards their preferred distance. These count towards the monthly prize for that distance.

How to compute prizes

Go to Admin panel โ†’ Monthly Prizes โ†’ select the block weeks (e.g. weeks 1โ€“4) โ†’ click Compute. Review the results before publishing. The system enforces the one-win-per-season rule automatically.


๐Ÿ”„

Season Rollover

At the end of the 24-week season, follow these steps in order. The season reset must happen after final processing and before new handicaps are distributed.

  1. Run final monthly prize computation Compute prizes for the last block (weeks 21โ€“24). Publish and record results.
  2. Export standings and results Download season standings and results as PDF/CSV for club records before archiving.
  3. Apply the season reset Subtract 2 minutes from every runner's handicap. This is their opening handicap for the next season. Use Admin โ†’ Season Rollover or the setup script.
  4. Archive the Google Sheet Rename the current sheet to "BAC Handicap 2026 Archive" so it's preserved but not used for live processing.
  5. Set up the new season sheet Run the setup script to create a fresh sheet with all required tabs and config for the new season.
  6. Update season constants in code Update the SEASON constant in src/lib/supabase-reads.js and src/lib/sheets.js to the new season year/config.
โš ๏ธ
The season reset (โˆ’2 min) must be applied AFTER the final week is processed, and BEFORE the opening handicaps for the new season are distributed to runners.

๐Ÿ“„

PDF Reports

The main app can generate PDF reports for weekly results, full season standings, and monthly prize summaries. These are suitable for printing or distributing to committee members.

Available reports

๐Ÿ“‹ Weekly results

Placings, times, points, and handicap changes for one race week. Grouped by distance, gender, and age group.

๐Ÿ… Season standings

Full accumulated standings table, broken down by distance ร— gender ร— age group. Shows all runners and total points.

๐ŸŽ Monthly prize summary

Prize winners for each block, with points totals and the weeks run used for tie-breaking.

To generate: go to the Results or Standings tab in the main app โ†’ click Download PDF. The report opens in a new browser tab โ€” print or save from there.


๐Ÿ”ง

Other Tools

Admin Panel

Available at /admin (separate admin password, not the main app PIN). Use for coordinator-level corrections and maintenance outside the normal weekly workflow.

โœ๏ธ Correct results

Fix an individual result after a week has been saved โ€” change a time, swap a bib, or adjust a flag. Always run Recalculate Standings after any correction.

๐Ÿ”„ Recalculate standings

Rebuild the full season standings from scratch after corrections. Standings do not update automatically from admin edits.

๐Ÿ‘Ÿ Register a runner

Add a walk-up entrant who didn't fill in the Google Form before race day. Assign a bib before entering their result.

๐Ÿท๏ธ Assign bibs

Assign bib numbers to PENDING runners who registered but didn't receive an auto-assigned bib.

๐Ÿงน Clean blank rows

Remove empty rows from the Google Sheet that can appear after bulk operations.

๐Ÿ† Monthly prizes

Compute and publish monthly prize winners for a given block of weeks.

Archive tab

Historical results from the 2025 season are available in the Archive tab of the main app. For reference only โ€” not used in 2026 processing.

Legacy Verify

Available at /legacy-verification. Checks 2025 season data against the DOS scoring engine for consistency. Not used in normal weekly processing.


โ“

Troubleshooting

ProblemSolution
Results showing stale data The app reads from Supabase first. If Supabase data looks stale, check whether the mirror ran after the last save. The app falls back to Google Sheets automatically if Supabase is unavailable.
Wrong week shown The main app derives the current week from the season start date. Check the seasonStart config in the Google Sheet config tab.
Runner missing from results Check the bib is registered. Walk-up runners need to be added in Admin first before their bib will be recognised on the Timesheet.
Duplicate bib flagged Two entries in the same week share a bib number. Remove the duplicate from the Timesheet before saving.
Standings not updated After any admin correction to a result, run Admin โ†’ Recalculate Standings. Standings don't update automatically from admin edits.
Handicap looks wrong Check whether the runner was flagged as Wrong Hcp or DNF. DNF entries keep the stored handicap unchanged. Wrong Hcp applies the DOS-parity formula โ€” confirm the actual start time entered is correct.
OCR extracted wrong value Review the OCR output against the original paper sheet. Correct on the Timesheet before importing. Ambiguous handwriting is the most common cause.
Can't sync stopwatch No internet at the course. Use Download CSV or Copy to Clipboard as backup, then import from the main app later using the single-file CSV option.

โšก

Quick Reference Card

ItemValue
Season weeks24 (6 monthly blocks of 4)
Target finish โ€” 1K26:00
Target finish โ€” 3K38:00
Target finish โ€” 6K44:00
Volunteer points8 (assigned to preferred distance)
DNF handicap changeNone (stored value unchanged)
Early finish adjustment+seconds early, rounded UP to nearest 10s
Late 61โ€“120sโˆ’10s
Late >120sโˆ’20s
Season resetโˆ’2 minutes from all handicaps
Data storageGoogle Sheets (primary write) + Supabase (read-first, mirrored)
Main app PINShared โ€” ask the committee secretary
Admin passwordSeparate from PIN โ€” ask the committee secretary