Snapshot · · read this page to catch up

CURRENT
PROGRESS

One map. A tracker, a real booking office, and a real-time taxi empire.

The live site is the Linux box: office says Real data, empire is the same desk with simulated rows. The API is health 0.1.26. Fares are the North Tyneside hackney tariff from 11 November 2024. The map centre is Grey's Monument. The depot is Shiremoor. The circle is 50 miles.

API Linux box · 0.1.26
Site Linux box · 100.65.94.5
Map Waypoints + OSRM · ready to demo
Phone Emulator POST 200 · Datastore

24 October 2026

Where we are

This is the page to read. The September notes further down are history.

The three products

  1. Tracker. Many phones, children, cars, and other things, linked to many people. The model is agreed. Issues 22 and 29 stay blocked, so the live database is not migrated. Until a later read rule, the map shows every device. Game taxis are never rows in devices.
  2. Booking office. Software to sell. office.html is the real company. The banner is exactly Real data. The panels are Quote, Bookings, and Ledger. The company ledger never shows driver share, fuel, standing, or −£11.20.
  3. Empire. The game to play is the map, the same page as the buses. The account form comes first. Create account, Sign in, and Sign out are on it, and the page does not start T1, T2, and T3 by itself. One real second is one game second. When OSRM returns a duration, the car drives that route for that many seconds. When OSRM does not answer, the car goes straight at 30 mph and the page says OSRM unavailable. They are not devices. game.html is the simulated desk. Its banner is Simulated data. The checked game day stays −£11.20. That ledger never shows the company totals £28.60, £11.30, or £12.40.

Locked figures

On main today

The office desk has the Real data banner, the three panels, the sentence No bookings yet, an Empire link, shared booking rows, and a receipt in the ledger for the £11.30 hiring. The banner still says Real data after a reload. One control shows the £28.60 day and another shows the empty day at £0.00. Switching them does not make £57.20. The ledger shows £28.60, and £0.00 for the empty day. Clearing the book returns No bookings yet and a total of £0.00. Restore brings the three bookings and £28.60. An offered £12.40 stays out of the total until it is completed, so the desk can show £16.20 and then £28.60. Sunday at 15:00 quotes tariff two. A guide or hearing dog on the £11.30 row adds £0.00, and the row stays £11.30. The help line states flag falls of £2.40 and £3.15. The £11.30 row can read cash or account, and the fare stays £11.30.

The account map is the current game on this site. Create account, Sign in, and Sign out are on the form, and the cars do not start by themselves. The fleet that keeps running on the Linux box is not deployed yet.

The simulated desk still draws the 50-mile circle and the Shiremoor depot. Live trips start from the depot at 2, 4, or 6 miles and stay inside eight miles. They are not Berwick. A 3-mile tariff-one fare with no waiting and no extras is £10.40. Offers arrive every 20 seconds and stop at 3. The page says 3 fares waiting at the cap, and Next fare in with the seconds left. At 0 the offer appears and the count starts again from 20 unless 3 are already waiting. A car at the depot accepts the oldest offer. If T1 is already out, T2 takes the next one. Two accepted offers move T1 and T2 at the same time. The third car can stay at the depot. Three cars, T1, T2, and T3, can move at once. None of them is a device. A waiting fare puts a customer pin on its pickup. After the drop-off the car drives home and becomes at_depot. A moving row shows the seconds remaining. Completing a live trip posts one fare line and one fuel line. Three miles of live fuel are −£0.60, once. The checked day stays −£11.20. Phones and buses stay on the map.

The tracker model is agreed: a person can watch many things, and a thing can be linked to many people. Kinds are phone, child, car, and other. Issues 22 and 29 stay blocked, so the live database is not migrated. Until a later read rule, the map shows every device. The API on the box is still 0.1.26. The phone android-c55e59830b71ba38 stays.

Live on this site

A push to main rebuilds hackathon.tyneside.software through GitHub Pages. The build takes under a minute. The network can keep the previous copy for about 10 minutes, so a normal refresh can look late. The map on this site is the map from that push.

The Linux box at 100.65.94.5 is a second copy. A push does not move it. The integrator runs scripts/box.ps1, then scripts/check.ps1 must print CHECK-OK. Pages cannot call the API, because the page is HTTPS and the API is HTTP. The box can, once it has the same map.

Earlier today the box moved from 8bd97bb through 90ce420 and 823f1ed to 6d38ca0, and then to 1a4c065. Each printed CHECK-OK. Health stayed 0.1.26. The board stayed 50 cards: 9 to do, 2 ready, 39 done. A later check, 50bb982, also printed CHECK-OK. The map fleet then went live on the box. check.ps1 printed CHECK-OK at 79c0c10. Health stayed 0.1.26. The board stayed 50 cards. Buses were 14. The API stayed 0.1.26 at 2602d02. That is the last box check. The public site has moved on since that check. The office still opens on an empty day: Restore day shows the £28.60 book.

How the day is run

Four sessions share GitHub main. There is no master branch. The word in every tab is continue. The checkout decides the role. Orders are docs/radio/integrator.md. Each lane writes only its own radio file. Lanes do not deploy. The integrator deploys with scripts/box.ps1 and then scripts/check.ps1 must print CHECK-OK. Each lane keeps at least 12 unfinished slices. A note that says the queue is low is stale while those slices are still listed.

Next

The moving detail is docs/radio/integrator.md on main. This page is the briefing. The September snapshot below is not the current product.

11 September 2026

September snapshot

Kept so the earlier catch-up is still here. It is not the live product.

  1. 01
    Three repos, two hosts. hackathon-site is HTML on GitHub Pages. hackathon-api is FastAPI on Cloud Run. hackathon-android is the tracker APK. Clone site and API as siblings. .\start.ps1 starts both.
  2. 02
    Waypoint routing does not call our API. Leaflet + OSM tiles + public OSRM, with a straight-line fallback. You can still demo routing if Cloud Run is quiet. Live phones do call it: GET /v1/devices every 8s.
  3. 03
    Cloud Run is 0.1.8. GitHub → Cloud Run uses buildpacks (pack on ubuntu2404), not the Dockerfile. Pin is 3.13. Datastore writes work: fields and GPS pings.
  4. 04
    The phone path works end to end. Pixel 6a posted /v1/locations, HTTP 200 stored=datastore, device android-c55e59830b71ba38, marker on the map. Cards 32–34 are done. A physical phone is card 35.
  5. 05
    Noah took live phones forward. Device drawer, phone cards, ping history on the map (36–38). API history reads Firestore with a Datastore fallback. Michael: live buses you can read (39, 43, 44). Next product slices are still the map: job list, demo seed, localStorage.
  6. 06
    New JavaScript is Alpine.js 3. CDN, defer, no npm. This page pings /health that way. Docs live at /docs/. Board source of truth is scripts/cards.json, not hand-edited HTML.

Board, distilled

Now, next, later

The kanban has the briefs. This is the order that matters if you just walked in.

In flight

Now

Empty · pull a card

48 · 🏗️ Michael · done Just landed: trails follow the streets Same public OSRM as Calculate route. Straight first, then snaps. In-view buses only, queued. 47 · 🔧 Noah · done Show / hide phones, remembered f35b560. Preference in localStorage. 46 · 🏗️ Michael · done 10-minute bus trail Fades to invisible at 10 minutes. Stored on the Firestore snapshot. Leave Show buses on for a minute to see it grow. 45 · 🏗️ Michael · done Bus cache Map calls GET /v1/buses. Firestore BusCache/newcastle, TTL 15s. Nobody looking: no bustimes.org hit. 41 · 🔧 Noah · done Register / login / Fetch me Noah’s last push. Account: POST /register, /login, /token, GET /users/me. Phone, map, and buses stay open.
Ready + product

Next

Demo the map, then fill it

44 · 🏗️ Michael · done Buses you can actually read Viewport only. Dots at city zoom (12–13), line chips at 14+. Newest ping age on the status line. Clicking a bus does not add a waypoint. Hard-refresh /app/ or open ?buses=1. 04 · 🧭 Reeve · Ready Clickable / draggable waypoints Live on app/. Polish and a teammate can add two pins without a briefing. 05 · ⚡ Connor · Ready Route calculation OSRM driving, haversine fallback. Sidebar shows distance, time, and engine. 07 · ⚡ Connor Job list beside the map Five Howden-shaped seed jobs. Click a job, something visible happens. 08 · 🧭 Reeve Demo seed: five Tyneside stops One button loads a named run so nobody clicks the map five times in a demo. 06 · 🌱 Lewis Save routes in localStorage Refresh must not wipe a demo. Fallback until the API can persist routes.
Waiting or onboarding

Later

7 open · 13h

35 · 🏗️ Michael Sideload APK on a physical phone Same tracker as card 32, on a real device. Emulator is already proven. 11 · 🏗️ Michael Persist routes on the API Replace browser-only storage so two machines share a run. Card 31 is done; this can start when someone picks it up. 09 · 🌱 Lewis Local “who am I” Display name in the browser. No real auth. 13 · 🌱 Lewis Back end running locally /health on :8080. Onboarding, not Cloud Run.

The room

Who is on what

Hours are the board totals. Focus is what to pick up tonight.

While you were away

What already shipped

38 cards · 70h on Done. Do not redo these.

  1. 11 September · card 46

    Fading 10-minute trail behind each bus

    Firestore keeps where each vehicle has been for 10 minutes. The map draws it in the bus colour, fading to nothing at 10 minutes. Trails only grow while a tab is looking.

  2. 11 September · card 45

    Buses from a shared Firestore cache

    The map no longer calls bustimes.org. GET /v1/buses serves BusCache/newcastle if it is under 15s old; otherwise the API fetches once and writes. No looking tabs, no upstream hit. API 0.1.7.

  3. 11 September · card 41

    Noah: register, login, Fetch me

    Accounts landed on API 0.1.6. Account creates a user, logs in, and calls GET /users/me with a bearer token. GPS and map reads stay open. Set JWT_SECRET_KEY on Cloud Run so tokens survive a new revision.

  4. 11 September · card 44

    Buses you can actually read

    About 300 live vehicles in 30 miles. Drawn at every zoom: coloured dots until 14, then upright line chips. Status shows newest ping age. Stale pings hidden. A bus click does not drop a waypoint. Wiki: Buses.

  5. 11 September · cards 43 · 42 · 40 · 39

    Michael: buses, heartbeat, Newcastle. Noah: API routers

    Show buses fetches (first request was aborting). Ghost buttons hover. Tracker POSTs every minute; map age is last communication; debug pin on the Tyne. Noah split app/main.py into app/routers/.

  6. 11 September · card 39

    Live buses, off until you ask

    First buses toggle. The map now reads GET /v1/buses (card 45) instead of calling bustimes.org from the browser. Wiki: Buses.

  7. 11 September · cards 36 · 37 · 38

    Noah: device drawer and ping history

    Phone list cards, a slide-over drawer, Show history plots unique LocationPings. API history reads Firestore with a Datastore fallback.

  8. 11 September · cards 32 · 33 · 34

    Live phones work end to end

    Android tracker POSTs GPS. API stores last-known in Datastore. Map polls devices and draws amber markers. Proven on the Pixel 6a emulator: HTTP 200 stored=datastore, device android-c55e59830b71ba38. All three cards done. Physical phone is card 35.

  9. Card 31

    API talks to Datastore / Firestore

    Noah’s persistence card is done. POST /create_field and GET /view_field/{key} round-trip. GPS pings use the same client. /health stays cheap.

  10. 3 September · card 30

    Cloud Run builds on Python 3.13 pack

    ubuntu2404 has 3.13 and 3.14 only. A 3.12 pin failed Cloud Build. Root main.py, Procfile, and .python-version 3.13 make pack succeed. Code VERSION is 0.1.8.

  11. 3 September · card 29

    Docs wiki, including architecture

    Docs is in the nav. Markdown in docs/, sidebar from pages.json, Alpine + marked. If you do not know how the three repos fit, open Architecture.

  12. 3 September · card 28

    Alpine API test page

    api-test.html calls GET /test_field on Cloud Run. First Alpine island. New UI behaviour goes here, not React/Vue/npm.

  13. Cards 04 · 05 · onboarding loops

    Map + routing are demoable

    Click to pin, drag to move, calculate a driving route. GitHub loops and local FE/BE are done for Reeve, Connor, Michael, Noah; Lewis still has local API on the to-do list. Reeve’s API-repo git loop (card 17) is now done.

How it is wired

The stack in one glance

The hosts never import each other. HTTP is the join.

hackathon-site

GitHub Pages

Static HTML, styles.css, Alpine, Leaflet. Live at hackathon.tyneside.software. Local: :5500.

  • Home, this page, map, board, wiki
  • config.js sets window.HACKATHON_API
  • Waypoints: OSM + public OSRM. Phones: GET /v1/devices. Buses: GET /v1/buses (Firestore cache), off by default

hackathon-api

Cloud Run · europe-west2

FastAPI + Uvicorn. Code 0.1.8. Local: :8080. Buildpacks, not the Dockerfile, on GitHub CD. Buses: GET /v1/buses from Firestore cache with a 10-minute trail. Accounts: /register /login /users/me.

  • GET / · /health · /test_field
  • POST /create_field · GET /view_field/{key}
  • POST /v1/locations · GET /v1/devices · GET /v1/buses
  • Python 3.13 · do not pin 3.12

Do not spend the session on these

  • Do not pin Python 3.12 for pack — ubuntu2404 cannot resolve it.
  • Do not open HTML as file:// — the browser will block the API and the wiki.
  • Do not hand-edit <!-- BOARD:… --> HTML. Change scripts/cards.json and run python scripts/update_board.py.
  • Do not import the Datastore/Firestore client at module top on Cloud Run — lazy import or 503.
  • Do not wait for the API to demo waypoint routing. OSRM is public. Do wait for it to see live phones.
  • Do not use Android Studio’s bundled JBR (Java 25) for Gradle. AGP 8.7 wants JDK 17. Set JAVA_HOME to Microsoft OpenJDK 17.

Your next hour

Pick up from here

Choose a length. Then open the matching surface — do not start a third plan.

Ten minutes

See it working

Open the map, drop two pins, calculate a route. Toggle Show buses (comes from our cache). Try Account register/login. If a phone is pinging, an amber marker should appear. Skim architecture if the three-repo split is fuzzy.

Thirty minutes

Cold machine

Follow onboarding: clone site and API as siblings, run .\start.ps1, pull main. Home, map, and board must load on http://127.0.0.1:5500/. Android is a third clone: hackathon-android.

A session

Ship a slice

Open the map: waypoints, phones, buses from GET /v1/buses. Reeve: demo seed (08). Connor: job list (07). Lewis: localStorage or local /health. Michael: physical phone (35) or persist routes (11). Push origin/main — that deploys site and API.