Skip to content
jackrabbit-projectPublic

About

Offline-first race secretary app for AOK9 sprint meets — entries to results, entirely in the browser.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

AOK9 Race Secretary

Free, offline web app that runs an official R.A.C.E. AOK9 Sprint Racing meet per Rule Book v3.0: entries → divisions → three programs of racing (draws, post positions, results) → final standings, championship points and the official NRD report — and, if you want it, a live results page that anyone at the meet can follow from a QR code.

Official program site: https://www.aok9racing.com/ — the rule book, entry forms and the current Grading Guide are on its Documents & Forms page.

Using it

https://aok9rms.gazehound.io — nothing to download, no account, and free, always. There is no paid version, no subscription and nothing to unlock, and the same goes for every tool the Jackrabbit Project publishes.

Open it once with a signal and press Install AOK9 on the home screen. It gets its own icon and opens without the browser bar, like any other app. On an iPhone or iPad there is no install button, so use Share → Add to Home Screen.

Installing matters because meets happen in fields. Once installed, the whole app is stored on the device and opens with no internet at all — draws, scoring, the report, everything. A phone hotspot for the first load is enough; after that you can be out of signal all day.

When a new version is published the app offers it as "A new version of AOK9 is ready" with a Reload button. It never reloads on its own, so it cannot restart under you part-way through scoring a meet.

Your meet is saved as you go

The meet is autosaved to the browser's local storage after every change — closing the laptop or losing power does not lose it. The home page shows which meet is loaded (club, meet ID, entries, programs run).

Under Downloads (shown once a meet has something in it):

  • Save Meet to File (.json) — the whole meet as a file, named with the date and time, e.g. aok9-meet-backup-2026-A01-20260802-143207.json, so repeated saves during a meet never overwrite each other and the newest is obvious. Use it as a spare copy or to move a meet to another machine, and reopen it with Open Meet from File.
  • Meet Report (.xlsx) — the official NRD report.
  • Print results — opens the Export screen, where the printable results live.

Under Try it out, Load example meet 1 or 2 fills the app with a finished meet to explore without entering anything — 19 dogs in 4 divisions, or 29 in 6.

Results online

On the Setup screen, Publish this meet creates a page at aok9rms.gazehound.io/r/<key> that anyone can open from the link or the QR code. The QR code goes on the printed divisions sheet and in the corner of every program sheet, so people scan it once and follow the meet from there: divisions now, each program's draw when it is locked, results as they are saved, final standings. No more crowding the board or photographing the sheets. The app pushes an update a few seconds after each change, whenever it has signal, and queues one while it does not. Stop publishing takes the page down. The Results screen repeats the address in one line, with the button to turn publishing on for a meet that was scored without it.

What goes on the page is what the paddock board shows: call names, breeds, posts, results and points. Owners, registration numbers, WAVEs, sex and notes are never sent. The page needs internet to open; the app itself still works with none.

Workflow (matches the rule book)

  1. Setup — club, meet ID, date. Upload a newer official Grading Guide xlsx at any time (the current guide is bundled). The ungraded threshold defaults to ¾ FTE per rule 4.4. Results online is here too: publish before printing anything and every sheet carries the QR code.
  2. Entries — search the guide by call name / reg# / breed / owner and enter with one click (WAVEs, grades and championship titles come along). Add FTE dogs with the form (initial grade D, or C/B per 4.3.1.3). Record each dog's sex for High Score Opposite Sex.
  3. Divisions — Auto-suggest builds breed divisions (2+ same breed; mix types are their own "breed") and pools the rest as mixed. Move dogs between divisions, mark a dog Leftover in a breed division (competes for MRC only, per 4.1.7), or flip a division to ungraded. Print divisions makes the first sheet for the board.
  4. Program 1 — draw per Figure 8.1 (graded: WAVE order; ungraded: random). Review, swap dogs (click two) if the committee adjusts groups, redraw posts, then Lock and print the program sheet. Enter each race's result with the big buttons: places 1–4 (tap the same place on two dogs for a dead heat), OC, DNF, DQ, SCR. A DQ'd dog is left out of the placements — place the others as if it had not run (6.1.3).
  5. Programs 2–3 — one click regroups by points per 4.3.4 with every tie decision explained on screen (audit trail for protests), new random posts.
  6. Results — final standings per 4.3.5, trophies (5.1), BRC/MRC/National/TRC points (Chapter V) with the full calculation shown, projected new WAVEs. Championship point cells are editable if the secretary needs to override a corner case. The results page's address is repeated here.
  7. Report — Download AOK9 Race Meet Report (.xlsx) produces the official template layout (Summary + race-by-race + an unofficial WAVE-projection sheet) for emailing to the NRD within 48 hours (2.2). Print buttons produce paddock-ready program sheets and results.

Rule interpretations encoded

  • Figure 8.1 is encoded verbatim, including the rows that do not divide evenly and would be wrong if the split were worked out arithmetically (9 dogs → 4/2/3; 5 dogs → a 3-dog HP race).
  • Ungraded trigger is ¾ FTE per rule 4.4 (a 2/3 option exists in Setup).
  • Award slots: titled champions above the line don't consume High-Score slots (per the 5.2/5.7 worked examples); ordinary ineligible dogs do. Dogs tied on race points split award values.
  • A leftover dog's MRC award corresponds to its actual placement among the whole division.
  • Dogs running alone: single non-HP race, no championship points, WAVE unchanged (4.2.2.4).
  • Beating a scratched dog counts as defeating a dog for Chapter V eligibility. A dog that finished ahead of a no-show (ABS) has defeated someone; only a DQ is scored as if the dog had never run (6.1.3).
  • Point totals are held to three decimals. A three-way dead heat splits 5 points as 1.666…, which no computer stores exactly; without rounding, two dogs who are level on paper can differ by a fifteenth decimal place and fail to split an award value they are both entitled to.

Reporting a problem

Open an issue — there are templates for a bug and for a scoring or rule question, both of which ask for the version and build shown at the bottom of the app, so a report can be traced to the exact code that produced it. If you do not have a GitHub account, email info@gazehound.io instead.

Attaching the .json from Save Meet to File makes a problem reproducible, but note that issues are public and the file contains the dog and owner names from your meet.

Developing it

The rest of this file is for whoever runs the app from source, changes it or deploys it.

Running it from source

npm install        # first time only
npm run dev        # development server at http://localhost:5173
npm run build      # production build into dist/
npm run preview    # serves dist/ at http://localhost:4173

The service worker that makes the app work offline is only generated by npm run build, so test offline behaviour against npm run preview, never npm run dev.

Look and feel

Warm paper, one accent colour, Fraunces for titles and IBM Plex Mono for labels and numbers. Both fonts are self-hosted under the SIL Open Font License (see LICENSE) so they are in the offline precache and the app looks the same with no signal. Everything is built for a phone at a field first — big targets for entering results, tables that scroll inside their own box, numbers rounded for reading. There is no dark theme; the tokens at the top of src/styles.css are laid out so one can be added by redefining them.

Updating the bundled Grading Guide

npm run refresh-guide

Downloads the guide currently published on the AOK9 documents page and converts it. A weekly GitHub Action does the same and opens a pull request when the published edition has changed, so the bundled copy does not quietly fall behind. To convert a file you already have:

npm run convert-guide -- "C:\path\to\new grading guide.xlsx"

Either way the columns are read by position, so both check the spreadsheet's headings first and refuse a guide whose layout has moved rather than misreading every WAVE. Run npm run build afterwards, or just upload the xlsx in the app's Setup screen — no rebuild needed.

Serving the results page

The page is served by two Cloudflare Pages Functions in functions/ (same project, same domain) backed by a KV namespace. One-time setup in the Cloudflare dashboard:

  1. Workers & Pages → KV → Create a namespace, e.g. aok9-meets.
  2. The Pages project → Settings → Bindings → Add → KV namespace: variable name MEETS, pointing at that namespace. Add it for Production and for Preview.
  3. Redeploy. Until the binding exists, publishing fails with a server error and the app shows not published — retrying; nothing else is affected.

Pages are kept for 400 days from the last update. What is sent is exactly buildSnapshot() in src/publish/snapshot.ts, and snapshot.test.ts checks the published text for every field that must stay out of it. The page lives on the same deployment as the app that made it, so a branch preview publishes to its own preview address and the feature can be tried there before it is merged. The functions do not run under npm run dev; to exercise them locally, build and run npx wrangler pages dev dist --kv MEETS.

Rebuilding example meet 2

npm run build-sample

Two finished meets are bundled for Try it out. sample-meet-1.json is an old capture from the real UI and is left alone; sample-meet-2.json is regenerated by the command above, which runs the real domain engine over a roster of dogs taken from the bundled guide, so its draws, rotations and championship points are the ones the app would actually produce. The roster is at the top of scripts/build-sample-meet.ts, and SAMPLE_SEED rerolls the results. Editing either JSON by hand is how you get a demo that disagrees with the rules it is demonstrating.

Tests

npm test runs the unit tests. They cover Figure 8.1 (all rows), points tables 8.2A/8.2B, dead-heat splitting, DQ redistribution, WAVE formulas, the rotation tie chain, and every worked example in the rule book (TRC examples 5.7 #1–2, the eligible-entry example in 5.2), plus a Grading Guide layout check, a report-export test, assertions run over both bundled example meets, the header's step-progress rules and number formatting, and the results page — what the published snapshot contains, what it must never contain, the publish endpoint's claim-and-update rules, and the address the page is given.

License

MIT — see LICENSE. You may use, modify and redistribute this app freely; it comes with no warranty of any kind. Using the app costs nothing and never will: no fee, no subscription, no paid tier.

Disclaimer

AOK9 Race Secretary app is an independent, free resource created and maintained by dog racing enthusiasts. Its purpose is to give race secretaries and clubs a simple, browser-based tool to help organize and manage AOK9 racing events. It is free to use, and always will be.

This application is not an official AOK9 publication, software product, or service. Its creation and development are independent, and it is not authorized, approved, or endorsed by AOK9 Racing. Official AOK9 rules, requirements, and information are available at https://www.aok9racing.com/.

Rules version. This app implements the AOK9 Sprint Racing Rule Book v3.0. If AOK9 publishes a newer rule book, the app will keep applying v3.0 until it is updated — confirm that version still matches the current official rules before using it to score a meet.

Where the rules required interpretation. In a few places the rule book is ambiguous or self-contradictory, and this app had to choose a reading. Those choices affect results and are listed above under Rule interpretations encoded — most importantly the race set-up chart (Figure 8.1) against the prose in 4.3.3, how championship titles are inferred from the Grading Guide, and how award positions are consumed by titled champions. Please check these against the official rules and your NRD's guidance.

Verify before you file. Users are responsible for verifying all event information, entries, results, and championship records against the official AOK9 rules and requirements. In the event of any discrepancy between information entered, displayed, or generated by this application and official AOK9 rules, forms, or publications, the official AOK9 materials shall govern.

Your data. Everything entered stays in your own browser on your own computer. Nothing is uploaded unless you choose to publish a meet's results page (see Results online above), and then only what the paddock board shows. There is no account or cloud backup, which is also why the app works with no internet. That means nobody can recover a lost meet for you: use Save Meet to File to keep your own copies, and keep one from part-way through a long meet, not just at the end.

No warranty. This software is provided "as is", without warranty of any kind, express or implied. See LICENSE.

This application is a work in progress. Feedback from race secretaries, clubs, and participants is welcomed and encouraged — info@gazehound.io.


Check out The Jackrabbit Project — the other tools and sites built for the sighthound coursing and racing community. All of them are free, always.

About

Offline-first race secretary app for AOK9 sprint meets — entries to results, entirely in the browser.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages