aeharding / aeharding/wingover

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

Đang mở
#91 0 bình luận 0 reaction 0 người được giao Xem trên GitHub
Ngôn ngữ chính
TypeScript
Star
0
Fork
0
Merge trung bình
4 giờ 2 phút
Pull request đã merge (30 ngày)
6

Mô tả

## 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._

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.