Stabile Task-IDs + Toggle-Rückschreibpfad #153

Closed
opened 2026-07-20 00:15:49 +02:00 by fable-5 · 1 comment
Collaborator

Ziel

Jede Aufgabenlisten-Zeile (task_item) ist stabil adressierbar, und der Server kann ihren checked-Zustand kollisionsfrei ändern — auch wenn die Seite gerade im Collab-Editor offen ist. Grundlage für die Aufgabenübersicht.

Umsetzungsskizze

  • Neues Attr id (nanoid, default: null → kompatibel mit Bestandsdokumenten) auf task_item (packages/shared/src/editor-schema/schema.ts:168-177); data-task-id in toDOM/parseDOM.
  • Vergabe/Dedup clientseitig per ProseMirror-Plugin mit appendTransaction (fehlende ODER duplizierte IDs — Copy/Paste! — bekommen frische); eingebunden neben apps/web/src/editor/nodes/task-item.tsx.
  • Markdown (- [ ]) bleibt ID-los; bei Import regenerieren IDs (akzeptiert — Markdown ist Austauschformat, nicht Quelle der Wahrheit).
  • Rückschreibpfad nach dem Vorbild des Restore-Mechanismus (VersionsService.restorepg_notifyapps/collab/src/restore-listener.ts mit openDirectConnection + transact; funktioniert auch bei nicht geöffneten Seiten, offene Editoren konvergieren per CRDT — NIE docFromState/docToState direkt in der API):
    • Neuer TASK_TOGGLE_CHANNEL + Payload {pageId, taskId, checked, userId} in packages/shared/src/collab-token.ts.
    • Neuer Listener apps/collab/src/task-toggle-listener.ts (Struktur = restore-listener): DirectConnection öffnen, YXmlElement taskItem mit passender id finden, setAttribute('checked', …) in transact; Registrierung in apps/collab/src/index.ts.
    • API POST /pages/:pageId/tasks/:taskId {checked} mit Write-Permission-Guard + pg_notify + pending-contributor-Eintrag (Versions-Attribution). Antwort asynchron → Aufrufer togglen optimistisch und refetchen.

Akzeptanzkriterien

  • Neue/bearbeitete Aufgabenzeilen tragen IDs; Copy/Paste erzeugt keine Duplikate.
  • Toggle-Endpoint ändert checked auch bei geschlossener Seite; offene Clients sehen den Toggle live und konfliktfrei.
  • Unbekannte taskId → 404/No-op mit Log; Versions-Historie attributiert den togglenden Nutzer.

Bewusst nicht enthalten

UI, die den Endpoint nutzt (Folge-Issue Aufgabenübersicht); Backfill-Migration alter Dokumente (ID-lose Zeilen bleiben bis zum nächsten Editor-Öffnen ohne ID).

## Ziel Jede Aufgabenlisten-Zeile (`task_item`) ist stabil adressierbar, und der Server kann ihren `checked`-Zustand kollisionsfrei ändern — auch wenn die Seite gerade im Collab-Editor offen ist. Grundlage für die Aufgabenübersicht. ## Umsetzungsskizze - Neues Attr `id` (nanoid, `default: null` → kompatibel mit Bestandsdokumenten) auf `task_item` (`packages/shared/src/editor-schema/schema.ts:168-177`); `data-task-id` in toDOM/parseDOM. - Vergabe/Dedup clientseitig per ProseMirror-Plugin mit `appendTransaction` (fehlende ODER duplizierte IDs — Copy/Paste! — bekommen frische); eingebunden neben `apps/web/src/editor/nodes/task-item.tsx`. - Markdown (`- [ ]`) bleibt ID-los; bei Import regenerieren IDs (akzeptiert — Markdown ist Austauschformat, nicht Quelle der Wahrheit). - Rückschreibpfad nach dem Vorbild des Restore-Mechanismus (`VersionsService.restore` → `pg_notify` → `apps/collab/src/restore-listener.ts` mit `openDirectConnection` + `transact`; funktioniert auch bei nicht geöffneten Seiten, offene Editoren konvergieren per CRDT — NIE docFromState/docToState direkt in der API): - Neuer `TASK_TOGGLE_CHANNEL` + Payload `{pageId, taskId, checked, userId}` in `packages/shared/src/collab-token.ts`. - Neuer Listener `apps/collab/src/task-toggle-listener.ts` (Struktur = restore-listener): DirectConnection öffnen, YXmlElement `taskItem` mit passender id finden, `setAttribute('checked', …)` in `transact`; Registrierung in `apps/collab/src/index.ts`. - API `POST /pages/:pageId/tasks/:taskId {checked}` mit Write-Permission-Guard + `pg_notify` + pending-contributor-Eintrag (Versions-Attribution). Antwort asynchron → Aufrufer togglen optimistisch und refetchen. ## Akzeptanzkriterien - Neue/bearbeitete Aufgabenzeilen tragen IDs; Copy/Paste erzeugt keine Duplikate. - Toggle-Endpoint ändert `checked` auch bei geschlossener Seite; offene Clients sehen den Toggle live und konfliktfrei. - Unbekannte taskId → 404/No-op mit Log; Versions-Historie attributiert den togglenden Nutzer. ## Bewusst nicht enthalten UI, die den Endpoint nutzt (Folge-Issue Aufgabenübersicht); Backfill-Migration alter Dokumente (ID-lose Zeilen bleiben bis zum nächsten Editor-Öffnen ohne ID).
fable-5 added this to the M22 — Aufgaben milestone 2026-07-20 00:15:49 +02:00
Author
Collaborator

Umgesetzt in PR #158 (3f7190e): task_item bekommt optionales id-Attr (default null, Bestandsdocs bleiben gueltig); der Editor vergibt/entdoppelt IDs lazy per appendTransaction (auch Copy/Paste). Neuer Kanal TASK_TOGGLE_CHANNEL; POST /pages/:id/tasks/:taskId prueft Schreibrecht, registriert den Toggler als pending contributor (Versions-Attribution) und feuert pg_notify; neuer collab task-toggle-listener (restore-listener-Muster, openDirectConnection) flippt das checked-Attribut als normalen Edit — offene Editoren konvergieren, unbekannte taskId = geloggter No-op. DB-Test (NOTIFY-Payload, 403/404/400); Loop im tasks-CI-Pack end-to-end.

Umgesetzt in PR #158 (3f7190e): task_item bekommt optionales id-Attr (default null, Bestandsdocs bleiben gueltig); der Editor vergibt/entdoppelt IDs lazy per appendTransaction (auch Copy/Paste). Neuer Kanal TASK_TOGGLE_CHANNEL; POST /pages/:id/tasks/:taskId prueft Schreibrecht, registriert den Toggler als pending contributor (Versions-Attribution) und feuert pg_notify; neuer collab task-toggle-listener (restore-listener-Muster, openDirectConnection) flippt das checked-Attribut als normalen Edit — offene Editoren konvergieren, unbekannte taskId = geloggter No-op. DB-Test (NOTIFY-Payload, 403/404/400); Loop im tasks-CI-Pack end-to-end.
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: stwaidele/dorfteich#153
No description provided.