aeharding / aeharding/wingover

Settings: "Copy diagnostics" button — privacy-safe, no telemetry

Abierto
#91 0 comentarios 0 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
TypeScript
Estrellas
0
Forks
0
Merge medio
4 h 2 min
PR fusionados (30 d)
6

Descripción

## Why
The "Not subscribed" investigation (client fix #90; server side aeharding/wingover.app#4) took hours and ultimately required attaching Safari Web Inspector to a physical device and hand-dumping the Keychain. A one-tap **"Copy diagnostics"** in Settings would have made it a paste — and it fits our **no-telemetry** stance: the pilot copies a blob and chooses whether to share it; nothing phones home.

This is the privacy-scoped replacement for the postmortem's "client telemetry" item (telemetry is off the table).

## What it does
- A button in Settings (Support / About) → assembles a **redacted** diagnostics blob → copies to clipboard (and/or opens the share sheet).
- **No auto-send.** The pilot reviews and pastes it wherever they want.
- Pairs with the new `/v1/session` server logging (wingover.app#4): both sides key on `userId`, so a pasted client dump correlates directly with `docker logs deploy-api-1 | grep `.

## What to include

### Sync / subscription — the part that mattered most here
- Sync `state` (off / connecting / syncing / unsubscribed / error) and `readOnly`
- `held.entitled` (in-memory credential flag)
- The **stored (Keychain) credential's `entitled`** — a divergence between the live session response and the persisted copy is exactly what we were blind to
- `lastSyncedAt`, `SYNC_DISABLED`
- Credential: `environment` (Sandbox/Production), `dbName`, `userId`, `login` (apple/null) — **redact `password`**
- Last replication `error`, and the **last `denied` event (doc `_id` + reason)** — the invisible per-doc `forbidden` on `_design/auth` was the whole bug

### StoreKit — device-side subscription truth
- `appEnvironment()` — the build's StoreKit environment (Sandbox on TestFlight)
- `appleSubscriptionState()` — active / expired / null
- Whether a current entitlement exists; if so a **decoded summary only** (`expiresDate`, `environment`, `productId`) — **never the raw JWS**

### Identity / account
- `userId` (derived hash — safe, and the key to joining with server logs)
- account `environment`, `login`
- **Do NOT include** the SIWA `sub`, Apple ID, or email

### Build / platform
- App version (`__APP_VERSION__`) + build number / commit
- iOS version, native (Tauri) vs web, Tauri version
- Which credential store is live: **Keychain vs IndexedDB fallback**

### Local data
- Local flight/doc count + approx local DB size
- Whether a replication checkpoint / pending push exists
- **No flight content or GPS** — counts and sizes only

## Privacy / redaction rules
- **Never** include: CouchDB `password`, raw JWS / identity tokens, Apple ID / email / SIWA `sub`, flight GPS or content
- `userId` is a one-way hash of `appTransactionId + environment` → safe to include and the join key to server logs
- Clipboard/share only; the pilot decides what happens next

_Postmortem follow-up (A3). Related: #90, aeharding/wingover.app#4._

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.