--- phase: quick-261009-dkv plan: 01 status: complete completed_tasks: [1, 2, 3] remaining_tasks: [] task1_commits: [207d37b, bf893af] task2_commits: [fe429db, c3adf85] task3_commits: [0585fd1] commits: 5 plan_head_before: 43a6a83 plan_head_after: 0585fd1 module_version: 1.0.0 (unchanged, per D-05 as corrected) pushed: false deployed: false --- # Quick 261009-dkv: Dateien Etappe 2a (Teilen) - Fortschrittsnotizen Alle drei Aufgaben sind erledigt (fünf Commits auf main, nichts gepusht, nichts ausgeliefert). Die Abschnitte zu Aufgabe 1 und 2 stammen aus deren Läufen, Aufgabe 3 steht am Ende. ## Aufgabe 1: Durchstich Personen und Gruppen (fertig, zwei Commits, nicht gepusht) | Commit | Inhalt | |--------|--------| | 207d37b | Schnittstelle: Freigaben-Schicht, Dienst, DTOs, Routen, shareTypes im Listeneintrag, Begrenzung, Fehlercodes, Live-Test `e2e-shares.sh` (Abschnitt people) | | bf893af | Oberfläche: Teilen-Dialog, Kennzeichen, Menüeintrag, Web-Client, Hilfen, Meldungen de/en; kleine API-Ergänzung `scope: 'groups'` am Fehler `sharingDisabled` | ### Gemessene Tore (auf dem neu gebauten Stack, `docker compose up -d --build api web`) | Tor | Ergebnis | |-----|----------| | api vitest `src/nextcloud-files module-manage-handlers` | 17 Dateien, 570 Tests grün (neu: nextcloud-shares 39, Dienst 34, Guard +4, Propfind +1, Controller +4) | | web vitest `modules/nextcloud-files components/nextcloud-files src/lib/nextcloud-files src/messages` | 16 Dateien, 214 Tests grün (neu: ShareDialog 14, share-policy 7, FileBrowser +6, Client +6) | | tsc api / web | sauber | | biome lint (api nextcloud-files, web Modul, Komponenten, Client) | 0 Fehler; 4 alte Warnungen in `nextcloud-files-account.service.spec.ts` (nicht von dieser Aufgabe) | | Schlüsselgleichheit de/en `nextcloudFiles` und Wortsperre (mandant, tenant, lizenz, licens, Pfeil, Mittelpunkt) | ok | | `nc-test-setup.sh` | `nc test ready` | | `e2e-shares.sh people` | `e2e shares people ok` (nach dem Neubau mit dem Endstand zweimal grün) | | Browser-Rauchtest (playwright-core, hell) | Zeilenmenü, Teilen, Suche `ben`, Auswahl legt Freigabe an, Kennzeichen erscheint, Entfernen: ok; Bilder lagen im Arbeitsverzeichnis der Sitzung (keine Beweisbilder, die kommen in Aufgabe 3) | Live bestätigt gegen Nextcloud 34.0.4: Empfängersuche findet die Person `ben` über den Teilbegriff `ben` und die Gruppe über `tessera`; Anlegen als Bearbeiten ergibt 201 mit permissions 15, Ändern auf Ansehen ergibt 1 (auch in Bens eigener Liste); doppeltes Anlegen ergibt 409 `shareAlreadyExists` ohne zweite Freigabe; Hochladen für eine Person ergibt 400 `shareAccessInvalid`; Gruppenfreigabe einer Datei 201; `GET files` trägt `shareTypes` (0 am Ordner, 1 an der Datei, leer am nicht geteilten Ordner); Entfernen 200; unbekannte oder ungültige Kennung 404 `shareNotFound`. Kein 401/403 in allen Aufrufen des Laufs. ### Abweichungen 1. **[Rule 3] Zusätzliche Datei im Commit:** `nextcloud-files-page.test.tsx` (nicht in der Dateiliste von Aufgabe 1) bekam `shareTypes: []` in der Eintragsattrappe, sonst bricht das Kennzeichen (`entry.shareTypes.length`) im Seitentest. Aufgabe 2 ändert diese Datei ohnehin weiter. 2. **[Rule 2] `scope: 'groups'` am Fehler `sharingDisabled`:** Der Web-Text für die Gruppenvariante braucht ein Merkmal statt eines Textvergleichs; die API hängt `scope: 'groups'` an (Dienst und Spec angepasst, Text des Servers unverändert). Der Web-Code mappt `sharingDisabled` mit `scope === 'groups'` auf `codes.sharingDisabledGroups`. 3. **Skriptfehler im Live-Test, behoben:** (a) `ben_perm` las eine veraltete Antwort (holt jetzt selbst neu), (b) `occ group:list | grep -q` scheitert unter `pipefail` durch SIGPIPE (jetzt Ausgabe in Variable, dann `case`), (c) die gemerkten HTTP-Status gingen in der Unterschale von `$(...)` verloren (jetzt Datei `$SEEN`). 4. Der Formatierer (`biome format --write` auf ein ganzes Verzeichnis) fasste die ungeformten Dateien `nextcloud-server-info.ts` und `.spec.ts` an; beide wurden per `git checkout -- ` zurückgenommen. Künftig nur die eigenen Dateien formatieren. ### Bekannte Lücken (absichtlich, für Aufgabe 2) - `update()` im Dienst lehnt Links vorerst mit `shareAccessInvalid` ab (`if (current.kind === 'link')`); Link-Ändern, Link-Anlegen, `mine`, `received`, `accept` fehlen. - `mapShareFailure` ist schon vollständig (auch die Passwort- und Ablauf-Zweige für create/update), aber die Passwort-/Ablauf-Zweige haben noch keinen Test (erst über Link-Aufrufe erreichbar). - Der Dialog zeigt in der Personenliste nur `kind !== 'link'`; Links tauchen im Dialog erst mit dem Link-Abschnitt auf. - Der Buchstabe `S` für eingehende Freigaben ist noch nicht live gemessen (Annahme A1); Kennzeichen und Spec nutzen ihn, Aufgabe 2 misst ihn im Abschnitt received und fällt sonst auf `nc:mount-type` zurück. - Die gemessenen Nextcloud-Status für Ablauf jenseits des Höchstwerts beim Ändern und schwaches Passwort beim Ändern (Auftrag der Abschlusszusammenfassung) stehen noch aus (Aufgabe 2). ## Hinweise für Aufgabe 2 **Bausteine, die schon da sind** - API `nextcloud-shares.ts`: `ocsShareRequest`, `parseShare` (url nur für eigene Links, `hasPassword`, nie `redacted`), `parseShareList(data, selfId)` liefert `{ shares, hidden, truncated }` (für `received` die Arten 0/1 danach selbst filtern oder einen Parameter ergänzen), `parseSharePolicy` (Links, Passwort, Ablauf, `uploadAllowed`, `multipleLinks`, `passwordMinLength`), `permissionsFor(access, itemType)` (liefert `null` für Hochladen bei einer Datei), `accessOf`, `isShareId`, `cleanText`. - API Dienst `nextcloud-files-shares.service.ts`: private Helfer `run(tenantId, userId, session, opts, operation, sent)` (wirft über `mapShareFailure`), `loadPolicy`, `listByPath`, `loadShare`; `SentFields { kind, passwordNonEmpty, expireDateSent, expireDateNonEmpty }` steuert D-15. `checkShareCreate(userId)` sitzt unmittelbar vor dem POST und nach jeder Vorprüfung. - Alle zwölf Fehlercodes samt Texten stehen in `nextcloud-files.types.ts`; im Web sind sie in `KNOWN` und `nextcloudFiles.codes` (de und en) vorhanden, dazu `codes.ncDetail` und `sharingDisabledGroups`. - DTO `CreateShareDto.kind` erlaubt noch nur `user` und `group` (`SHARE_KINDS_PEOPLE`), `UpdateShareDto` nur `access`. - Web: `share-policy.ts` hat schon `accessOptions` mit Link-Zweig und `generatePassword(minLength, fill?)`; es fehlen `linkPasswordMode`, `todayLocal`, `addDays`, `expiryRule`, `linkUpdateDiff`. `ShareDialog` hat `run()` (ein Aufruf zugleich, `busy`), `fail()` (connectionExpired führt zu `onExpired`) und den Fehlerblock mit zweiter Zeile; der Link-Abschnitt kommt neben `
`. - `FileBrowser` hat `sharingEnabled` (Standard true) und reicht `onShare` (optional) an `FileList`/`FileGrid`; `initialPath`/`initialFocus` fehlen noch. `page.tsx` ist unverändert (Tabs, Richtlinie, `browserStart` noch offen). **Stolpersteine, die ich gemessen habe** - Nextcloud antwortet auf `PUT` für eine Berechtigungsänderung 200 mit dem neuen Objekt; Bens eigene Liste (`shared_with_me`) zeigt `permissions` (Freigabe) und `item_permissions` (wirksam) getrennt (1 und 9 nach dem Ändern auf Ansehen bei einem Ordner), `parseShare` nutzt `permissions` für `access` und `item_permissions` für `itemWritable`. - Im Live-Skript immer erst die Liste neu holen, bevor man eine Eigenschaft liest (`ben_shares`), sonst misst man einen alten Stand. - Das Skript schaltet die Ratenbegrenzung der Test-Nextcloud nur für seinen Lauf aus (Schlüssel `ratelimit.protection.enabled`, im `trap` gelöscht; nach den Läufen mit `occ config:system:get ratelimit.protection.enabled` geprüft: nicht gesetzt). Es setzt/löscht außerdem im `trap` die Schlüssel `core shareapi_enforce_links_password`, `shareapi_default_expire_date`, `shareapi_enforce_expire_date`, `shareapi_expire_after_n_days` und `files_sharing default_accept` für `anna`. Aufgabe 2 muss sie dort setzen (Details im Plan, Abschnitt "Discovered facts"). - Der Zähler von Tessera für neue Freigaben liegt im Arbeitsspeicher; `docker compose restart api` setzt ihn zurück. Der Abschnitt people legt 2 Freigaben an (Person, Gruppe), die Abschnitte links und received dürfen insgesamt höchstens 6 je `all`-Lauf (Plan) anlegen. - Der Abschnitt people braucht die Test-Nextcloud mit `ben` (`User3-Pass-12345`) und Gruppe `tessera-team`; beides legt das Skript selbst an (bleibt nach dem Lauf bestehen). - Browser-Rauchtest ohne MCP: `playwright-core` aus `/home/vicolab/.npm/_npx/705bc6b22212b352/node_modules/playwright-core` mit `executablePath: '/home/vicolab/.cache/ms-playwright/chromium-1247/chrome-linux64/chrome'` (die Standard-Chromium-Version der Bibliothek ist nicht installiert); Anmeldung admin/admin123 auf http://localhost:3000, Anna ist im Admin-Konto verbunden. Skript lag im Arbeitsverzeichnis der Sitzung. - Formatieren nur mit der Dateiliste der Aufgabe (`biome format --write `), nie über ein ganzes Verzeichnis. **Aufgabe 1 hat keine Dokumente angefasst:** SUMMARY, STATE und PLAN sind nicht committet; ROADMAP unverändert. ## Aufgabe 2: Links nach den Regeln der Nextcloud, Von mir geteilt, Mit mir geteilt (fertig, zwei Commits, nicht gepusht) | Commit | Inhalt | |--------|--------| | fe429db | Schnittstelle: Links anlegen/ändern (Passwort, Ablauf, Bezeichnung, Vorprüfung aus den frischen Fähigkeiten, echte Datumsprüfung, nur geänderte Felder), `shares/mine`, `shares/received`, `POST shares/:id/accept`, DTO und Controller, Live-Test (Abschnitte links, received) | | c3adf85 | Oberfläche: `LinkShareForm`, Link-Abschnitt im `ShareDialog`, `SharesView` (beide Ansichten), Reiter in `page.tsx`, `FileBrowser` `initialPath`/`initialFocus`, Hilfen in `share-policy.ts`, `clipboard.ts`, Web-Client, Meldungen de/en | ### Gemessene Tore (neu gebauter Stack, `docker compose up -d --build api web`) | Tor | Ergebnis | |-----|----------| | api vitest `src/nextcloud-files module-manage-handlers` | 17 Dateien, 614 Tests grün (Dienst jetzt 73, Freigaben-Schicht 40, Controller +Routen) | | web vitest `modules/nextcloud-files components/nextcloud-files src/lib/nextcloud-files src/messages` | 17 Dateien, 265 Tests grün (neu: SharesView 14, ShareDialog-Links 14, Seite +8, Hilfen +14, Client +3, FileBrowser +2) | | tsc api / web | sauber | | biome lint (Pfade des Plans) | 0 Fehler; dieselben 4 alten Warnungen in `nextcloud-files-account.service.spec.ts` | | Schlüsselgleichheit de/en (310 Schlüssel) und Wortsperre | ok | | `nc-test-setup.sh` | `nc test ready` | | `e2e-shares.sh all` | people, links, received grün (`version` folgt in Aufgabe 3); zweimal hintereinander grün, jeweils nach `docker compose restart api` (Zähler zurückgesetzt) | | Zurückgesetzt nach den Läufen | alle occ-Schlüssel (`shareapi_*`, `ratelimit.protection.enabled`, annas `default_accept`) geprüft: nicht gesetzt; Fixture-Ordner von anna und ben entfernt | | Browser-Rauchtest (playwright-core, dunkel) | Reiter Dateien/Von mir geteilt/Mit mir geteilt, Teilen am Ordner, Link erstellen und anzeigen, „Link kopieren“ zeigt „Kopiert“, Von mir geteilt zeigt den Eintrag, Link löschen mit Rückfrage: ok (Bilder liegen im Arbeitsverzeichnis der Sitzung, keine Beweisbilder) | ### Gemessene Nextcloud-Werte (Nextcloud 34.0.4, Ausgabe des Live-Tests) | Messung | Ergebnis | passt zu D-15? | |---------|----------|----------------| | PUT mit schwachem Passwort `abc` (direkt bei der Nextcloud) | Status **400** | ja (400 + Passwort gesendet = `sharePasswordRejected`) | | PUT mit Ablauf jenseits des Höchstwerts (heute plus 30 bei 7 Tagen Pflicht, direkt) | Status **404** | ja (404 + Ablauf gesendet = `shareExpiryInvalid`) | | POST über Tessera mit Ablauf jenseits des Höchstwerts | 400 `shareExpiryInvalid` | ja | | PUT über Tessera mit Ablauf jenseits des Höchstwerts | 400 `shareExpiryInvalid` | ja | | Berechtigungsbuchstaben eines eingehenden Ordners (Ansehen) | **`SGDNV`**: `S` ist da (Annahme A1 bestätigt, kein Rückfall auf `nc:mount-type` nötig); **`R` fehlt**, das Menü „Teilen“ (nur bei `R`) erscheint daher bei eingehenden Einträgen nicht | ja | | Bens eigene Liste nach dem Verlassen durch anna | **0 Freigaben**: eine verlassene Personenfreigabe ist bei der Nextcloud ganz gelöscht, nicht nur ausgeblendet | Hinweis für die Anleitung | | Link-Berechtigung bei Nextcloud | Ansehen kommt als `17` (Teilen-Bit 16 gesetzt) zurück, Nur hochladen als `20`; `accessOf` maskiert mit 15 und ordnet richtig zu | Hinweis | | Link-Adresse | `http://172.17.0.1:18080/s/` (Nextcloud baut sie aus dem Aufrufhost, im Test intern; Hinweis für Anleitung/Betrieb) | Hinweis | ### Abweichungen 1. **[Rule 1 - Bug, Test] Fähigkeiten der Nextcloud nach occ-Änderung kurz veraltet:** die Nextcloud lieferte nach `occ config:app:set/delete` die Fähigkeiten für wenige Sekunden aus einem Zwischenspeicher (einmal gemessen: Pflicht-Passwort an, danach nach Löschen noch an). Tessera speichert nichts. Der Live-Test wartet deshalb mit `policy_wait` bis dreimal hintereinander die erwartete Richtlinie kommt, ehe er schreibt. 2. **[Rule 1] Live-Test-Erwartung korrigiert:** Links tragen bei der Nextcloud das Teilen-Bit (Ansehen 17, Nur hochladen 20); geprüft wird `permissions & 15` und `access`. 3. **[Rule 2] „Nur hochladen“ und „Bearbeiten“ bei Links brauchen auch Schreibrecht am Eintrag (API und Browser):** Plan nannte es nur für Bearbeiten; ein Ordner ohne Schreibrecht (`RG`) kann nicht zum Hochladen freigegeben werden, die Nextcloud lehnte es mit 403 ab. Jetzt `shareAccessInvalid` vorab, mit Test; `accessOptions` bietet es nicht an. 4. **[Rule 3] `isRealDate` exportiert** aus `nextcloud-shares.ts` (Dienst nutzt es für die Datumsprüfung), mit eigenem Test. 5. **Empfängerzeile „Gruppe {name}“:** die Empfängerzeile in „Von mir geteilt“ heißt „Gruppe team (Ansehen)“ statt verschachtelter Klammern. 6. Der Zähler der Begrenzung zählt auch einen Versuch, den die Nextcloud ablehnt (Ablauf jenseits des Höchstwerts, Abschnitt links); `all` verbraucht damit 7 Zähler (2 people, 5 links); höchstens zwei `all`-Läufe zwischen zwei `docker compose restart api`. ### Bekannte Lücken / Hinweise für Aufgabe 3 - Nicht umgesetzt wie im Plan beschrieben, weil nicht nötig: Passwort-Erzeugen-Endpunkt der Nextcloud (D-18, bleibt beim lokalen Zufallserzeuger). - Das Passwort eines frisch angelegten (oder per „Passwort ändern“ gesetzten) Links steht nur solange im Dialog, wie er offen ist, in einem Hinweisfeld mit „Passwort kopieren“; es wird nie gespeichert. Der Anwenderleitfaden soll sagen: danach zeigt Tessera es nicht mehr. - Der Dialog zeigt Fehler je Abschnitt (Personen, Link), nicht mehr nur unten; es gibt immer nur einen Fehlerblock. - `SharesView` gruppiert „Von mir geteilt“ je Eintrag (Pfad); „Freigaben bearbeiten“ öffnet den bekannten `ShareDialog`; „Im Ordner zeigen“ öffnet den Ordner und fokussiert den Eintrag. „Mit mir geteilt“: „Öffnen“ bei einem Ordner geht auf `target`, bei einer Datei auf den Ordner darüber mit Fokus; offene Freigaben haben nur Annehmen/Ablehnen. - Für die Bildbeweise: die Reiter heißen „Von mir geteilt“ / „Mit mir geteilt“ (Seite, Tab-Leiste); Datenattribute `nextcloud-files-shares-byMe` / `-withMe` am Abschnitt, `nextcloud-files-shared-by-me` / `-with-me` an der Hülle. Für Pflicht-Passwort-Bilder `occ config:app:set core shareapi_enforce_links_password --value=true --type=boolean` setzen und danach löschen; nach jeder occ-Änderung ein paar Sekunden warten (Zwischenspeicher der Fähigkeiten). - Eingehende Freigaben tragen kein `R`: das Menü „Teilen“ erscheint dort nicht (richtig so). - Für Aufgabe 3 sind `e2e-shares.sh` Abschnitt `version` (Stub) und der Modul-Changelog (1.0.0 um drei Punkte erweitern), CHANGELOG, vier Anleitungen und die Bildbeweise offen. Die Anleitungen sollen die gemessenen Werte nutzen: verlassene Freigabe ist weg, Link-Adresse stammt aus der Nextcloud (extern erreichbare Adresse in Tessera eintragen oder `overwritehost`), Fähigkeiten werden bei jeder Aktion frisch gelesen. - Nicht committet: SUMMARY, STATE, PLAN; ROADMAP unverändert; die gestagten Löschungen von `.planning/HANDOFF.json` und `.planning/.continue-here.md` sind unberührt. ## Aufgabe 3: Modul-Changelog, Anleitungen, Gesamttore, Bildbeweise (fertig, ein Commit, nicht gepusht) | Commit | Inhalt | |--------|--------| | 0585fd1 | Modul-Changelog 1.0.0 um drei Teilen-Punkte erweitert, `CHANGELOG.md` (zwei Punkte), vier Anleitungen, `e2e-shares.sh` Abschnitt `version`, zwei kleine Oberflächenkorrekturen aus der Bildprüfung | ### Version (Bestätigung zu D-05) Die Modulversion von „Dateien“ **blieb 1.0.0** (Datum 2026-10-08 unverändert, die vier Punkte der Etappe 1 unverändert, drei `new`-Punkte angehängt, jetzt sieben). Das entspricht der Regel „Höchstens ein Sprung je Modul zwischen zwei Tessera-Freigaben“ (`docs/anleitung-entwicklung.md`): das Modul war noch in keiner Tessera-Freigabe (letzte Freigabe v1.10.1 vom 06.10.). Es gibt keine 1.1.0, das Seed-File blieb unverändert (die Version kommt aus dem Changelog), `CHANGELOG.md` trägt die beiden Punkte unter „Unveröffentlicht“ ohne „Modulversion …“. Der feste Test in `module-changelog.spec.ts` prüft jetzt zusätzlich: genau ein Eintrag 1.0.0, sieben Neu-Punkte, die letzten drei sind die Teilen-Punkte. Der Live-Test-Abschnitt `version` prüft über `GET /modules/changelog/nextcloud-files` Version 1.0.0 und den Punkt „Öffentliche Links“. ### Gemessene Tore (neu gebauter Stack: `docker compose up -d --build api web`, danach nach der Bildprüfung `--build web` noch einmal) | Tor | Ergebnis | |-----|----------| | `pnpm --filter @tessera/api test` (voll) | 154 Dateien, 3182 Tests grün | | `pnpm --filter @tessera/web test` (voll) | 151 Dateien, 1778 Tests grün | | tsc api / web | sauber | | biome lint (Pfade des Plans plus `module-changelog.spec.ts`) | 0 Fehler, 7 Warnungen, alle schon vorher da (4 in `nextcloud-files-account.service.spec.ts`, 3 `noNonNullAssertion` in `module-changelog.spec.ts`); mein neuer Test fügt keine hinzu | | `biome format` auf den eigenen Dateien | sauber (`module-changelog.spec.ts` hat Altlasten im Wörterbuch oben, nicht angefasst) | | Seed-Zeile im api-Log („Nextcloud files module seeded in registry“) | da | | `nc-test-setup.sh`, `e2e-settings.sh`, `e2e-connect.sh`, `e2e-files.sh`, `e2e-transfer.sh` | alle grün (Etappe 1, Listenantwort geändert) | | `e2e-shares.sh all` (nach `docker compose restart api`) | people, links, received, version grün; mehrfach, auch als letzter Lauf der Kette | | Prüfkette aus `` | endet mit „final gates ok“ (Bilder: 14 vorhanden, 12 Pflicht plus 2 Zusatzbilder) | | occ-Rücksetzung | `shareapi_enforce_links_password`, `ratelimit.protection.enabled`, annas `default_accept` geprüft: nicht gesetzt; Ordner Projekte, Angebote, Ben-Unterlagen, Ben-Offen von anna und ben gelöscht, Papierkörbe geleert; Annas Freigabenliste leer | ### Ergebnisse der Messungen (verlangt vom Plan, Abschnitt Ausgabe) 1. **Nextcloud-Status bei Änderung (e2e, Nextcloud 34.0.4):** PUT mit schwachem Passwort `abc` direkt bei der Nextcloud: **400**; PUT mit Ablauf jenseits des Höchstwerts direkt: **404**; über Tessera jeweils 400 `shareExpiryInvalid` beim Anlegen und Ändern. Alles passt zu D-15 (400 + Passwort gesendet = `sharePasswordRejected`, 404 + Ablauf gesendet = `shareExpiryInvalid`). 2. **Buchstabe S:** eingehende Ordner trugen `SGDNV`, also **S vorhanden** (Annahme A1 bestätigt, kein Rückfall auf `nc:mount-type`). `R` fehlt, daher kein Menüpunkt „Teilen“ an eingehenden Einträgen. Nach dem Verlassen durch anna zeigte **bens eigene Liste 0 Freigaben**: die verlassene Personenfreigabe ist bei der Nextcloud ganz gelöscht (steht so in der Anleitung). 3. **Version:** blieb 1.0.0 (siehe oben). 4. **Bildbeweise** (alle unter `/home/vicolab/projects/tessera-ctl/.playwright-mcp/nextcloud-files/`, im Git ignoriert), Auflösung 1440x900, Mobil 390x844: - dunkel: `s2a-dark-menu.png`, `s2a-dark-people.png`, `s2a-dark-link-form.png`, `s2a-dark-links.png`, `s2a-dark-indicator.png`, `s2a-dark-by-me.png`, `s2a-dark-with-me.png` (mit „Noch nicht angenommen“), `s2a-dark-mobile.png`; zusätzlich `s2a-dark-link-password.png` (Passwort-Hinweis nach dem Erstellen) und `s2a-dark-link-expiry.png` (Ablaufdatum ändern) - hell: `s2a-light-people.png`, `s2a-light-links.png`, `s2a-light-by-me.png`, `s2a-light-with-me.png` - Im Browser ausgeführt und bestätigt: Teilen mit ben, Ändern auf Bearbeiten, Entfernen; Link erstellen (Pflicht-Passwort, „Passwort erzeugen“), Passwort kopieren, „Verstanden“, Link kopieren (Zwischenablage trug die Adresse `http://172.17.0.1:18080/s/`), Ablaufdatum ändern (Zeile zeigt „gültig bis …“), Link löschen mit Rückfrage; „Öffnen“ bei Ben-Unterlagen in „Mit mir geteilt“ landet im Ordner (Pfadleiste „Alle Dateien > Ben-Unterlagen“); offene Freigabe Ben-Offen angenommen, danach „Angenommen“ mit „von Ben Beispiel, Ansehen“. 5. **Checkliste für die echte Umgebung** steht weiter unten. ### Prüfung der Bilder gegen L-09 und Korrekturen Jedes Bild wurde angesehen. Ruhige, dichte Listen; Kennzeichen in beiden Modi lesbar (Link-Symbol an „Projekte“, Personen-Symbol an „Ben-Unterlagen“); keine Großbuchstaben-Etiketten, keine Mittelpunkte in Meta-Zeilen, keine Pfeilknöpfe; Fokusring am Suchfeld sichtbar; Mobil als Bodenblatt mit gekürztem Gruppennamen und gekürzter Adresse, alle Knöpfe erreichbar. Zwei Mängel gefunden und behoben (im Commit): 1. **Linkformular verdeckt:** im Dialog stand das Formular unter den Personen, „Link erstellen“ und „Abbrechen“ lagen außerhalb des sichtbaren Bereichs. Das Formular scrollt jetzt beim Öffnen mit `scrollIntoView({ block: 'nearest' })` in den sichtbaren Bereich (`LinkShareForm.tsx`). 2. **Offene Freigabe zeigte „Eigene Berechtigung“:** die Nextcloud meldet eine noch nicht angenommene Freigabe mit permissions 0 (gemessen; `item_permissions` ist dort 9, das ist Lesen plus Löschen und deshalb nicht als Ansehen deutbar). „Mit mir geteilt“ zeigt bei offenen Freigaben jetzt keinen Berechtigungstext (`SharesView.tsx`, Test ergänzt); nach dem Annehmen steht „Ansehen“. ### Abweichungen 1. **[Rule 1 - Bug] zwei Oberflächenkorrekturen** aus der Bildprüfung (siehe oben), Dateien aus Aufgabe 2 im selben Commit. 2. **[Rule 3] Hell-Bilder im Modus „System“:** die Hell-Bilder entstanden mit der Themenwahl „System“ (Betriebssystem hell), nicht mit der Wahl „Hell“; das Aussehen ist gleich. Die Dunkel-Bilder entstanden über den Themenknopf. 3. **Beobachtung ohne Änderung (Etappe 1):** in einem eingehenden Nur-Ansehen-Ordner bietet die Dateiansicht „Neuer Ordner“ und „Hochladen“ an, die die Nextcloud ablehnen würde. Das war schon vor Etappe 2a so (der Ordner liegt im Hauptordner); nicht Teil dieser Aufgabe. Vorschlag für später: Schreibrecht des geöffneten Ordners auswerten. 4. Formatierer nur auf eigene Dateien angewendet. ### Bedrohungsstatus (Threat Model) Alle Einträge T-dkv-01 bis -14 mit Disposition „mitigate“ sind in den Aufgaben 1 und 2 umgesetzt und durch Einheitstests und Live-Tests belegt; Aufgabe 3 ändert nur Dokumente, Changelog-Daten, einen Scroll-Aufruf im Formular und die Anzeige offener Freigaben. T-dkv-15 (Link-Adresse mit interner Adresse, „accept“) ist in Administrations- und Betriebshandbuch erklärt (externe Adresse eintragen oder `overwritehost`). Das Passwort eines Links erschien weder in einer Antwort noch im api-Log. Neue Angriffsfläche in Aufgabe 3: keine. ### Bekannte Stubs Keine. Keine neuen Einträge im Fenster-Register nötig. ### Checkliste für die echte Umgebung (nach dem eigenen Pull auf alpha, Auslieferung macht der Benutzer) - [ ] Version und Regeln der Firmen-Nextcloud: „Teilen“ an einer Datei öffnen, „Link erstellen“. Das Formular muss die Regeln der Firmen-Nextcloud so zeigen, wie sie dort eingestellt sind: Passwort Pflicht (Feld „Passwort (Ihre Nextcloud verlangt eines)“, „Passwort erzeugen“ geht), kein erzwungenes Ablaufdatum (nur „Ablaufdatum festlegen“ als Wahl). - [ ] Link-Adresse: „Link kopieren“, in einem privaten Browserfenster öffnen. Die Adresse muss die **äußere** Nextcloud-Adresse tragen. Zeigt sie eine interne Adresse, entweder in den Einstellungen des Moduls die äußere Adresse eintragen oder in der `config.php` der Nextcloud `overwritehost`, `overwriteprotocol`, `overwrite.cli.url` setzen (steht in Administrations- und Betriebshandbuch); schon erstellte Links ändern sich nicht rückwirkend. - [ ] Teilen mit einer Kollegin oder einem Kollegen: sie oder er sieht die Freigabe in der Nextcloud (und unter „Mit mir geteilt“ in Tessera, bei „Annehmen verlangt“ unter „Noch nicht angenommen“). - [ ] Desktop-App: „Link kopieren“ und „Passwort kopieren“ legen in die Zwischenablage (Tauri-Fenster; falls die App-Zwischenablage nicht greift, fällt Tessera auf das Markieren des Felds zurück). - [ ] Gruppenfreigabe: eine Gruppe suchen und teilen; „Teilen mit Gruppen“ in der Nextcloud muss erlaubt sein, sonst erscheint die deutsche Meldung dazu. - [ ] Der Zähler (15 neue Freigaben in 10 Minuten je Benutzer) liegt im Arbeitsspeicher des `api`-Containers; nach einem Neustart beginnt er bei null. ## Self-Check: PASSED - Commit 0585fd1 liegt auf main (`git merge-base --is-ancestor`), enthält genau die elf Dateien der Aufgabe, keine Löschungen; die gestagten Löschungen von `.planning/HANDOFF.json` und `.planning/.continue-here.md` sind unberührt. - Dateien vorhanden: Changelog, Anleitungen (vier), `CHANGELOG.md`, `e2e-shares.sh`; alle zwölf Pflichtbilder vorhanden. - Nicht committet, wie gefordert: SUMMARY, STATE, PLAN; ROADMAP unverändert. Nicht gepusht, nicht ausgeliefert. ## Review fixes (nach 261009-dkv-REVIEW.md) Alle elf Befunde und die zwei Zusatzpunkte sind behoben (Einzelheiten in `261009-dkv-REVIEW.md`, Abschnitt „Fix status“). Zwei Commits, nicht gepusht, nicht ausgeliefert. | Commit | Inhalt | |--------|--------| | 78f6cf3 | Schnittstelle: wörtliche Pfade und Kennungen (CR-01), `accessOf` nach Eintragsart (IN-03), Weitergaben (IN-05), Begrenzung 10/10 Minuten plus Versuchszähler und Aufräumen (WR-03), Serverdatum in den Regeln (IN-01), Berechtigungsbuchstaben des Ordners in der Liste (EXTRA-1), Live-Test (Ablehnen, Weitergabe, Ordner-Buchstaben) | | d487a00 | Oberfläche und Dokumente: Link-Formular (WR-01), Abschnittsfehler und Kleinigkeiten (IN-02, IN-05), stabile Ansichten (WR-04), Ablaufgrenzen nach Serverdatum und Passwortlänge (IN-01, IN-04), Dateiansicht nach Rechten (EXTRA-1), Importreihenfolge (WR-02), CHANGELOG und vier Anleitungen (10 statt 15, Suche ab einem oder zwei Zeichen) | ### Tore (neu gebauter Stack: `docker compose up -d --build api web`) | Tor | Ergebnis | |-----|----------| | `pnpm --filter @tessera/api test` (voll) | 154 Dateien, 3213 Tests grün (vorher 3182) | | `pnpm --filter @tessera/web test` (voll) | 152 Dateien, 1812 Tests grün (vorher 1778) | | tsc api / web | sauber | | `biome check` (nicht nur lint) auf allen 31 geänderten Quelldateien, Tests und Meldungen | 0 Fehler, keine Warnungen; `organizeImports` in den sechs gemeldeten Dateien behoben | | `nc-test-setup.sh`, `e2e-settings.sh`, `e2e-connect.sh`, `e2e-files.sh`, `e2e-transfer.sh` | alle grün | | `e2e-shares.sh all` (nach `docker compose restart api`) | people, links, received, version grün; neu: Buchstaben des Ordners (`CK` an der Wurzel, `SGDN` im Nur-Ansehen-Ordner), Ablehnen, Weitergabe mit Pfad „Sub X“ | | Browser (playwright-core, dunkel) | siehe unten | | Zurückgesetzt | `shareapi_allow_public_upload`, `shareapi_*`, `ratelimit.protection.enabled`, `default_accept` nicht gesetzt; Fixtures (Fix-Link, Ben-RO, rs-test, rs-ro) und alle Freigaben gelöscht, Papierkörbe geleert; Freigabenlisten von anna und ben leer | ### Browserprüfung (dunkel, `.playwright-mcp/nextcloud-files/s2a-fix-*.png`) - Eingehender Nur-Ansehen-Ordner „Ben-RO“ (`s2a-fix-dark-readonly.png`): kein „Neuer Ordner“, kein „Hochladen“, stattdessen „Nur ansehen“; Menü der Datei nur „Herunterladen“ und „In Nextcloud öffnen“ (`-readonly-menu`), Auswahlleiste nur „Herunterladen“ (`-readonly-selection`); die eigene Wurzel hat beide Knöpfe weiter (`-own-root`). - Link mit eigener Berechtigung (Nextcloud-Maske 21): „Aktuell: Eigene Berechtigung“ gewählt und gesperrt (`-link-current`); nur die Bezeichnung geändert und gespeichert, in der Nextcloud blieb die Maske 21 und die Bezeichnung wurde übernommen. - Suchfehler (Antwort 502 abgefangen) steht unter „Personen und Gruppen“, nicht unter „Link“ (`-search-error`). ### Messungen und Entscheidungen 1. **Weitergaben (IN-05):** `uid_owner` ist bei der Nextcloud der Freigebende, `uid_file_owner` der Dateieigentümer; die Annahme des Befunds (uid_owner = Dateieigentümer) stimmt nicht. Bens Weitergabe von Annas Ordner: bei Ben `uid_owner = ben`, `path` in Bens Baum (`/rs-test/Sub X`), `file_target` im Baum des Empfängers (`/Sub X`). Gewählt: Weitergabe bleibt in „Von mir geteilt“ mit dem eigenen `path` (`target` = `path`), mit Hinweis und Eigentümer; kein Ausschluss. Für Anna (Dateieigentümerin) liefert nur die Pfadliste mit `reshares=true` die Weitergabe, mit `uid_owner = ben`. Ohne die Änderung wäre `target` der Pfad im fremden Baum gewesen (nur dort, wo `target` benutzt wird: eingehende Ansicht). 2. **Ablehnen (IN-06):** `DELETE shares/{id}` ist richtig; `DELETE shares/pending/{id}` ergibt 405. Dienst blieb unverändert. 3. **Link mit Bearbeiten, nachdem die Nextcloud das öffentliche Hochladen verbot:** die Nextcloud lehnt dann schon eine reine Bezeichnungsänderung mit „Public upload is not allowed.“ ab (gemessen). Tessera bleibt dabei ehrlich: Berechtigung nicht still senken, die Meldung der Nextcloud steht als zweite Zeile; wer die Änderung will, wählt ausdrücklich „Ansehen“. Für den Fall ohne Konflikt (z. B. eigene Berechtigung bei erlaubtem Hochladen) bleibt die Berechtigung erhalten. 4. **Modulversion:** bleibt 1.0.0, kein neuer Punkt im Modul-Changelog (Korrekturen an noch nicht veröffentlichtem Code, die Punkte „Ordner durchsuchen“ und „Teilen“ gelten unverändert). Im `CHANGELOG.md` steht die Nummer 10 statt 15 und ein Satz zu den ausgeblendeten Aktionen bei „Arbeiten mit Dateien“. 5. **Meldungstext „tooManyShares“** gilt jetzt auch für den Versuchszähler („viele Freigaben angelegt“); Wortlaut unverändert gelassen, damit Oberfläche und API übereinstimmen. 6. Ohne Buchstaben des Ordners (ältere Antwort, fehlende Eigenschaft) blendet die Dateiansicht nichts aus; unbekannt ist nie verboten. ### Für die echte Umgebung (Checkliste) - Die Begrenzung liegt jetzt bei 10 neuen Freigaben in 10 Minuten (Checkliste oben bei Aufgabe 3 sprach noch von 15). - In einem Ordner, den jemand nur zum Ansehen geteilt hat, sind „Neuer Ordner“ und „Hochladen“ verschwunden; „Nur ansehen“ steht an deren Stelle.