docs(map): production caught up to 0035, knowledge/recordings/settings sync, remaining GUI check

This commit is contained in:
Yun Chan 2026-09-27 14:44:57 +09:00
parent 9a8f7e6aa6
commit 8d6b166de5
6 changed files with 20 additions and 13 deletions

View file

@ -96,10 +96,11 @@ Legend: `[ ]` open · `[~]` in progress · `[!]` blocked externally · `[x]` res
| GAP-SYNC-02 | Sync | **Desktop Realtime never connected.** Electron 33 main (Node 20.18) has no global `WebSocket`; supabase-js Realtime only ever logged `TIMED_OUT`/`CLOSED` (installed-app log 2026-09-16) and gave up after three retries. Also: filtered `postgres_changes` channels never deliver DELETE (Supabase limitation). | `CloudSyncService.ts`, `services/sync/realtime-transport.ts`, integration test "Realtime" case | `[x]` 2026-09-27: `ws` injected as the Realtime transport (`ws` now a declared desktop dependency, externalised in the main bundle); deletions arrive as `sync_tombstones` INSERT events; the heartbeat re-subscribes a channel that is not `joined`. Verified live against the local stack (INSERT/UPDATE + tombstone events received). |
| GAP-SYNC-03 | Portability | Mobile/cloud data export failed for any account with meetings or generated documents: `export_account_portability` used `to_jsonb(row)` while the v1 archive contract (server restore + mobile `exactKeys`) is a frozen key set, and later migrations added columns. | `server/supabase/migrations/20260927000034_cross_device_sync_parity.sql` §7 | `[x]` 2026-09-27: export projects each dataset onto its v1 keys; integration test asserts the memo/meeting key sets. |
| GAP-SYNC-04 | Mobile devices | Mobile `normalizeRegisteredDevice` rejected every platform except `android`/`ios`, so the first desktop/web device on an account would have made the whole Devices screen fail to load. | `apps/mobile-rn/src/features/devices/device-service.ts`, `screens/DevicesScreen.tsx` | `[x]` 2026-09-27: accepts the server platform list (`android/ios/web/windows/macos`), card shows the platform; `__tests__/devices.test.ts` 3/3, full mobile Jest 372/372. |
| GAP-SYNC-05 | Sync | **Not yet in production.** Migration `20260927000034` is applied only to the local stack; the rewritten desktop sync ships with the next desktop release. Until the migration is deployed, desktop tombstone pulls and template RPCs fail against production (they are isolated per step, other entities keep syncing). | migration file, `apps/desktop/src/main/services/sync/` | `[ ]` Deploy the migration (`supabase db push` against the production project) **before** publishing a desktop build that contains this engine; then run a GUI pass: sign in on desktop, edit/delete on the phone, confirm desktop updates within seconds and the phone lists the desktop under Devices. |
| GAP-SYNC-06 | Sync | Still desktop-local (not mirrored): knowledge base (desktop local RAG embeddings vs cloud pgvector — different embedding spaces), audio (desktop WAV files vs mobile Storage uploads), `user_settings` (locale, auto-polish, active command), desktop preset-command prompt edits, meeting `transcripts` segments (desktop uses `raw_transcript`, which mobile also fills). | `docs/map/10-feature-catalog.md` MEM-09/MEM-05/SHELL rows | `[ ]` Decide per item: knowledge docs could sync as source text and be re-embedded per surface; audio needs a size/quota policy before upload. |
| GAP-SYNC-07 | Sync | `sync_tombstones` grows without a schedule. `prune_sync_tombstones_v1(interval)` (service_role) exists; nothing calls it. | migration §1 | `[ ]` Call it from an existing cron (e.g. the Forgejo scheduled workflow) with the 180-day default. A client whose cursor is older than the retention must fall back to a full resync. |
| GAP-SYNC-05 | Sync | **Not yet in production.** Migration `20260927000034` is applied only to the local stack; the rewritten desktop sync ships with the next desktop release. Until the migration is deployed, desktop tombstone pulls and template RPCs fail against production (they are isolated per step, other entities keep syncing). | migration file, `apps/desktop/src/main/services/sync/` | `[~]` 2026-09-27: production `supabase db push` applied `0029`–`0035` (backup dump taken first; see GAP-OPS-01), all 23 Edge Functions redeployed, v1.7.0 published (runtime/portable first, then the updater feed) and installed on the owner PC. **Remaining:** the desktop on that PC is in local mode — one Google sign-in in Settings > Cloud, then edit/delete on the phone and confirm the desktop updates within seconds and appears under Devices. |
| GAP-SYNC-06 | Sync | Still desktop-local (not mirrored): knowledge base (desktop local RAG embeddings vs cloud pgvector — different embedding spaces), audio (desktop WAV files vs mobile Storage uploads), `user_settings` (locale, auto-polish, active command), desktop preset-command prompt edits, meeting `transcripts` segments (desktop uses `raw_transcript`, which mobile also fills). | `docs/map/10-feature-catalog.md` MEM-09/MEM-05/SHELL rows | `[x]` 2026-09-27: knowledge docs sync as source text and are re-embedded per surface; recordings upload to the mobile storage contract (≤50 MiB per file, opt-out toggle) and remote recordings play through signed URLs; `user_settings` maps the shared fields. Deliberately not synced (see §7.x): meeting `transcripts` segments (mobile renders `raw_transcript`/`edited_transcript`, which the desktop fills) and desktop preset-command prompt edits (server presets are immutable by RLS). Evidence: `tests/main/sync/SyncExtensions.test.ts` (9) + integration case "지식 문서·설정·녹음" against the local Supabase stack. |
| GAP-SYNC-07 | Sync | `sync_tombstones` grows without a schedule. `prune_sync_tombstones_v1(interval)` (service_role) exists; nothing calls it. | migration §1 | `[x]` 2026-09-27: migration `0035` enables `pg_cron` and schedules `prune-sync-tombstones` daily at 03:17 UTC (production `cron.job` active=true). A client whose cursor is older than 180 days must fall back to a full resync. |
| GAP-OPS-01 | Ops | **Production Supabase was five migrations behind** (`0029` content reporting, `0030` profile column ACL — users could raise their own `role`/`tier` through PostgREST, `0031` audit-log actor unlink, `0032` meeting-document reporting, `0033` team activity feed) and `content-report` was never deployed, while the map listed those features GREEN from local runs. Most functions still ran the 2026-08-21 build. | `server/supabase/migrations/`, Management API `schema_migrations`, `functions` list | `[x]` 2026-09-27: schema+data dump taken, `db push` applied `0029`–`0035`, all functions redeployed (unauthenticated calls return 401, i.e. live and gated); `authenticated` can no longer UPDATE `profiles.tier`; real-account export returns exactly the v1 keys. Next: add a CI check that compares `supabase migration list --linked` with the repo so production cannot silently lag again. |
---
## 2. Mobile checklist roll-up (from `MOBILE_APP_COMPLETION_SSOT.md` §4)
@ -217,6 +218,10 @@ Actionable checklist for the work started this session. Fields to fill are blank
- **원격 삭제가 로컬 미전송 수정보다 우선한다.** 다른 기기에서 지운 행은 데스크톱에서 편집 중이었어도 지워진다.
- **업그레이드 후 첫 동기화는 예전 삭제를 되살릴 수 있다.** 이 버전 이전에는 삭제 기록이 없었으므로, 데스크톱에만 남아 있던 행(모바일에서 지웠지만 데스크톱이 몰랐던 행)은 첫 대조에서 서버로 다시 올라간다. 데이터 유실보다 되살림을 택했다.
- **데스크톱 사용 횟수(`dictionary.usage_count`)는 자주 바뀌어 매번 올리지 않는다.** 단어를 추가·수정할 때 함께 올라간다.
- **회의 `transcripts` 세그먼트는 동기화하지 않는다.** 모바일은 회의 본문을 `raw_transcript`/`edited_transcript`로 그리고, 데스크톱은 이 두 컬럼을 채운다.
- **데스크톱 프리셋 명령의 프롬프트 수정은 기기 로컬이다.** 서버 프리셋(`builtin_key`)은 RLS상 클라이언트가 고칠 수 없고 두 프리셋 목록도 다르다. 사용자가 만든 명령만 동기화한다.
- **설정은 뜻이 같은 것만 맞춘다.** 언어는 모바일이 지원하는 ko/en, 테마는 시스템/라이트/다크만(데스크톱 전용 테마는 로컬), 자동 다듬기는 켬/끔, 활성 명령은 양쪽에 있는 사용자 명령일 때만. 서버에 설정 행이 이미 있으면 첫 동기화에서 서버 값이 이긴다.
- **지식 문서는 원문만 옮긴다.** 기기마다 임베딩 모델·차원이 달라(데스크톱 768, 서버 1536) 벡터는 각자 만든다. 다른 기기에서 온 문서에는 원본 파일이 없다.
여기 있는 항목은 고쳐야 할 갭이 아니라 **대안을 검토한 뒤 의도적으로 유지하기로 한 절충**이다.
§1 에 갭으로 재등록하지 마라.