docs(agents): record offline/dead-relay behaviour + nip05 seeds

This commit is contained in:
SkateSpots 2026-09-28 12:52:04 +07:00
parent c79373ed05
commit 08bc3a8b41

View file

@ -499,9 +499,11 @@ session with **no other memory of this project**. So:
— the app works without one), **proof by signature** (a claim carries a NIP-98
kind-27235 event in the `x-nip05-auth` header, signed by the pubkey that will
own the name), and `onlyIfNew` writes so two claims can't clobber each other.
Platform names are seeded in code (`skate-spots`, `skatespots` → owner pubkey)
and cannot be claimed/released by users; a small `RESERVED` list blocks
impersonation words. Client: `src/lib/skateNip05.ts` (shared validation,
Platform names are seeded in code (`skate-spots`/`skatespots` → owner pubkey,
`skater` → the second admin `caba497f…`) and cannot be claimed/released by
users; a small `RESERVED` list blocks impersonation words. Any admin can wear
a seeded handle by typing it in Edit Profile → NIP-05 (it verifies against the
seed; no claim needed). Client: `src/lib/skateNip05.ts` (shared validation,
`deriveSkateNip05Handle`, `parseSkateNip05`, `skateApiBase()` for the native
absolute-URL rule), `src/hooks/useSkateNip05.ts` (check/claim/release), and
`src/components/SkateNip05Input.tsx` (debounced availability + Claim).
@ -515,6 +517,27 @@ session with **no other memory of this project**. So:
functions with a free draft (`netlify deploy --dir=dist`), not a prod deploy.
Verified end-to-end on a draft (2026-09-28): claim → resolves → a second key
gets 409 → release → gone.
- **Offline / dead-relay behaviour (2026-09-28):** the app is a utility, so a
relay outage must degrade, not blank. ⚠️ `querySkateContent` used to swallow
**every** relay error and return `[]`, so a dead relay looked like "no spots"
AND overwrote good cached data with an empty list (which the persister then
saved). Now:
- `querySkateContent` / `queryCanonical` take an opt-in **`requireAny`** that
throws when NO relay answered. Only the map's own feeds pass it
(`useSkateSpots`, `useShops`, `useMarketplaceItems`, `useTours`); the other
~75 call sites keep the old behaviour, deliberately.
- `useSkateSpots` / `useSkateSpot` catch that error and fall back to the
**Dexie spot cache** (`lib/offlineCache`), so the map still works at the
park; they only re-throw when nothing is cached (UI shows an offline card).
- `shouldDehydrateQuery` **never persists an empty array** — otherwise one
blip would wipe the persisted map for the next 24h.
- `MapPage` shows "Offline · showing saved spots" + retry, and a "Can't reach
the relays" card instead of the false "No spots mapped yet". Reachability
reuses the existing **`useRelayStatus(url)`** (`lib/relayProbe`, a real
Nostr handshake) plus `useOnlineStatus` — NOT `navigator.onLine` alone,
which is true on a captive-portal Wi-Fi.
- Not done yet: offline **map tiles** (needs a service worker on web / an
IndexedDB tile layer for native) and the app shell offline — the next slice.
- **Mints directory**: `/mints` page lists Cashu mints from the community
**MintRadar** project. MintRadar has **no CORS**, so it's fetched same-origin
at `/api/mints/*` — prod proxies via `public/_redirects` (`/api/mints/* →