MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 50s
Phase 1 of the collaboration plan (server side):
- internal/collab: block tree with parent IDs and fractional order keys,
operations with conflict rules (version check, block leases, conflict
copies instead of lost text, restore on late edits, cycle checks),
in-memory leases/sessions and long-poll notifier.
- Storage: per-note lock + transaction, append-only effect log (doc_ops),
idempotent results per opId (doc_op_results), snapshot, log paging,
central DocRole. Old flat block data is converted to the tree.
- The existing whole-document save (PUT/PATCH) runs as an adapter through
the same engine, so the current editor keeps working and writes to the log.
- API: GET /docs/{id}/snapshot, POST /docs/{id}/sync, GET /docs/{id}/changes
(long poll), POST /docs/{id}/leave; DOC_SEQ poke for WebSocket/SSE rooms.
- Backend accepts editor (write) shares for notes and folders; the forced
read-only migration is gone. The share dialog still offers read only.
- Tests: conflict matrix, order keys, leases, storage adapter round trip,
idempotency, API protocol incl. long poll, and a randomized simulation
(4 clients, lost/duplicated requests and responses, offline phases,
lease expiry) checking convergence, no lost text and exactly-once results.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
4.2 KiB
4.2 KiB
Teilen & Berechtigungen
Rollen
| Ebene | Werte | Bedeutung |
|---|---|---|
| Server | admin, member |
Admins verwalten Benutzer, Einladungen und Einstellungen (/admin/*). |
| Gruppe | admin, member |
Gruppen-Admins ändern/löschen die Gruppe und verwalten Mitglieder. Wer eine Gruppe anlegt, wird Admin. |
| Ressource | siehe unten | Eigentümer, Bearbeiter, Leser. |
Berechtigungen je Ressource
| Ressource | Eigentümer | Bearbeiter | Leser | Freigabe an |
|---|---|---|---|---|
Aufgabenliste (task_list_shares.permission) |
alles, löschen, (un)teilen | Aufgaben anlegen/ändern/abhaken/verschieben/löschen, Liste umbenennen, Spalten ändern | nur ansehen | Benutzer, Gruppen |
Geteilte Liste (list_shares.role) |
alles, löschen, (un)teilen | Einträge anlegen/ändern/abhaken/löschen | nur ansehen | Benutzer, Gruppen |
Notiz (doc_shares, doc_team_shares) |
alles, Freigaben, löschen | Inhalt, Struktur, Titel | nur lesen | Benutzer, Gruppen |
Geteilter Ordner (workspace_folder_shares) |
alles | Notizen darin bearbeiten | nur lesen | Benutzer, Gruppen |
- Notizen und Ordner: Die effektive Rolle berechnet
Store.DocRole(Eigentümer, Eigentümer des geteilten Ordners = Bearbeiter, direkte Freigabe, Gruppenfreigabe, Ordnerfreigabe; höchste gewinnt). Das Backend akzeptiert Bearbeiter-Freigaben (write). Der Freigabe-Dialog bietet bis zur Umstellung des Editors (Phase 5 im Plan) noch nur „Nur Lesen“ an, und der alte Editor schreibt weiterhin nur für den Eigentümer. - Bei Aufgabenlisten und Listen gilt: Hat jemand mehrere Zugriffswege (direkt und über Gruppen), zählt die höchste Stufe.
- Für Gruppen gilt die Freigabe für alle aktuellen und künftigen Mitglieder.
- Aufgabenlisten besitzen zusätzlich das Altfeld
team_id: Mitglieder dieser Gruppe haben ohne Freigabezeile Bearbeiterrechte. Eine Gruppenfreigabe über den Dialog setztteam_id, falls es noch leer ist.
Aufgabenlisten teilen (Details)
- Eigentümer öffnet „Teilen“ an der Liste, wählt Gruppe oder Benutzer und die Stufe Bearbeiten oder Nur Lesen.
POST /task-lists/{id}/sharesspeichertpermission; erneutes Hinzufügen desselben Ziels ändert die Stufe.GET /task-listsliefert je Listepermission(owner/editor/viewer). Das Frontend blendet fürvieweralle Eingabemöglichkeiten aus und zeigt „Nur Lesen“.- Der Server prüft unabhängig davon jeden Schreibzugriff (
403,storage.ErrTaskListReadOnly).
Bestehende Freigaben aus der Zeit vor dieser Stufe wurden mit editor migriert, behalten also ihr Verhalten.
Isolations-Modi (system_settings.sharing_mode)
Werte: strict_private, teams_only (Standard), open. Gedacht ist:
| Modus | Zweck |
|---|---|
strict_private |
Keine Sichtbarkeit zwischen Benutzern |
teams_only |
Freigaben nur zwischen Mitgliedern gemeinsamer Gruppen |
open |
Jeder kann für jeden freigeben |
Tatsächlich wird der Modus nur in GetDiscoverableUsers ausgewertet, und dort liefert teams_only bereits alle Benutzer. GET /collaborators ignoriert den Modus, und keine Freigabe-Funktion prüft ihn. Die Einstellung hat derzeit also kaum Wirkung (FLAW-10).
Entkoppelte Ablage geteilter Notizen und Ordner
- Geteilte Ordner: Der Ordner existiert einmal (
workspace_shared_folders); jeder Empfänger hat seinen eigenen Einhängepfad (workspace_folder_mounts.mount_path). Verschiebt ein Empfänger den Ordner, ändert sich nur sein Pfad. Der Unterpfad innerhalb des Ordners (documents.sub_folder_path) gilt für alle. - Einzelne Notizen: Jeder Empfänger kann eine geteilte Notiz in einen eigenen Ordner legen (
doc_user_folders); die Notiz des Eigentümers bleibt unberührt.
Sitzungen und Zugriff
- Tokens werden bei Passwortänderung, Rollenwechsel, Deaktivierung und „Alle Sitzungen beenden“ ungültig (
token_version); ausgeloggte Tokens landen inrevoked_tokens. - Registrierung nur per Einladungscode oder, wenn vom Admin freigeschaltet, offen. Das erste Konto wird immer Administrator.
- Bekannte Lücken in der Zugriffskontrolle: FLAW-01, FLAW-02, FLAW-03, FLAW-06, FLAW-07, FLAW-08, FLAW-24.