Private
Public Access
1
0

static site details

This commit is contained in:
2026-03-16 15:19:55 +01:00
parent 6cd6e72753
commit bd562768ef

View File

@@ -264,20 +264,31 @@ POST /rowers/courses/{id}/unfollow/
```
Add or remove a course ID from the `liked:{athlete_id}` KV entry. Return 200 on success.
### 1.7 Course map browser (GitHub Pages)
```
GET /api/me
```
Returns `{athleteId, liked: [...]}` if a valid `rn_session` cookie is present, otherwise 401. Used by the GitHub Pages browser on load to determine login state and populate like buttons. Also used to verify session liveness without a full page reload.
A single-page Leaflet application served from the `site/` directory. Features:
### 1.7 Course map browser (GitHub Pages + Worker)
The map browser is a single-page Leaflet application served as static files from the `site/` directory via GitHub Pages. DNS routes `rownative.icu/*` to GitHub Pages and `rownative.icu/api/*` to the Cloudflare Worker. Static assets (HTML, JS, CSS, `index.json`, KML files) are served for free with no compute; the Worker only wakes up for API calls.
**Static features (no Worker involved):**
- Map centred on user geolocation on first load, falling back to world view.
- Loads `courses/index.json` on init; renders a marker per course.
- Clicking a marker shows course name, distance, country, status badge, and a link to the course detail page.
- Course detail page fetches the full JSON and renders the polygon chain on the map.
- Loads `index.json` on init (raw GitHub URL); renders a marker per course.
- Clicking a marker shows course name, distance, country, status badge.
- Course detail view fetches the full course JSON and renders the polygon chain on the map.
- Filter controls: country dropdown, distance range slider, status toggle (provisional / established / both).
- Search by name (client-side, against the index).
- "Submit a course" link leading to the submission form.
- KML download button per course (links to `kml/{id}.kml`).
- KML download button per course (links to static `kml/{id}.kml`).
No backend calls needed for browsing — entirely static.
**Dynamic features (require Worker + login):**
- On page load, the browser calls `GET /api/me`. If a valid session cookie is present the Worker returns `{athleteId, liked: [...]}` and the page renders like/unlike buttons accordingly. If not, a "Sign in with intervals.icu" button is shown instead.
- Like/unlike buttons POST to `/api/rowers/courses/{id}/follow/` and `/unfollow/`. The page updates optimistically; the Worker updates KV.
- "Submit a course" form POSTs to `POST /api/courses/submit` (KML upload → GitHub PR). Requires login.
- ZIP import form POSTs to `POST /api/courses/import-zip`. Requires login.
**CORS:** Worker responses for `/api/*` include `Access-Control-Allow-Origin: https://rownative.icu` and `Access-Control-Allow-Credentials: true` so the GitHub Pages origin can make credentialed `fetch()` calls carrying the session cookie.
### 1.8 Infrastructure setup (Stage 1)
@@ -373,25 +384,31 @@ Users are notified of this migration path via the Rowsandall shutdown announceme
**Cloudflare Worker:**
- [ ] `wrangler.toml` with KV binding and secrets
- [ ] CORS headers on all `/api/*` responses (`Allow-Origin: https://rownative.icu`, `Allow-Credentials: true`)
- [ ] intervals.icu OAuth login flow (`GET /oauth/authorize`, `GET /oauth/callback`)
- [ ] Encrypted HTTP-only cookie (`rn_session`) — AES-GCM encrypt/decrypt of `{athleteId, accessToken, refreshToken, expiresAt}`
- [ ] HMAC-derived CrewNerd API key (`apiKeyForAthlete()`)shown on user profile page
- [ ] Platform API key verification on incoming CrewNerd requests
- [ ] Token refresh on expired `expiresAt`rewrite cookie with fresh tokens
- [ ] HMAC-derived CrewNerd API key (`apiKeyForAthlete()`) — format `{athleteId}.{mac}`
- [ ] API key verification on incoming CrewNerd requests (split, recompute, constant-time compare)
- [ ] `GET /api/me` — return `{athleteId, liked}` from session cookie or 401
- [ ] `GET /api/courses/` — course index with geo filtering
- [ ] `GET /api/courses/{id}/` — single course KML
- [ ] `GET /api/courses/kml/liked/` — liked courses KML bundle
- [ ] `GET /api/courses/kml/` — multi-course KML bundle
- [ ] `POST /rowers/courses/{id}/follow/` and `/unfollow/`
- [ ] `POST /api/auth/crewnerd` — bearer token exchange for API key
- [ ] `POST /api/courses/submit` — KML upload → GitHub PR
- [ ] `POST /api/courses/import-zip` — ZIP import: check each owned ID against `index.json`, open PR only for IDs not already present; restore liked list in KV unconditionally; return summary to user
- [ ] KML generation logic (port of `courses.py`: `coursetokml`, `getcoursefolder`, `crewnerdify`, `sort_coordinates_ccw`)
**GitHub Pages site:**
- [ ] Leaflet map browser with course markers and detail view
- [ ] Filter controls (country, distance, status)
- [ ] Course submission form (KML upload)
- [ ] ZIP import form (for Rowsandall migrants)
- [ ] "Sign in with intervals.icu" link
- [ ] Leaflet map with course markers and polygon detail view
- [ ] Filter controls (country, distance, status) and name search
- [ ] Login state: call `GET /api/me` on load; show "Sign in" button or like buttons accordingly
- [ ] Like/unlike buttons (optimistic UI, POST to Worker)
- [ ] Course submission form (KML upload, requires login)
- [ ] ZIP import form (for Rowsandall migrants, requires login)
- [ ] DNS routing: `rownative.icu/*` → GitHub Pages, `rownative.icu/api/*` → Worker
---