# UI_EDIT_V1_DESIGN.md ## 1. Scope `Edit v1` is een eenvoudige teksteditor in de webui, gekoppeld aan de functiebalkactie `Edit`. In scope: - alleen tekstbestanden - alleen files, geen directories - openen, wijzigen en opslaan van tekstinhoud - eenvoudige modal-editor Out of scope: - geen binary files - geen PDF - geen rich text - geen collaborative editing - geen autosave --- ## 2. Ondersteunde bestandstypen in v1 Voorstel v1: - `txt`: ja - `log`: ja - `md`: ja - `yml` / `yaml`: ja - `json`: ja - `js`: ja - `css`: ja - `html`: ja - `Dockerfile`: ja - `Containerfile`: ja De allowlist blijft gelijk aan `View v1`, zodat `View` en `Edit` inhoudelijk consistent zijn. --- ## 3. UI/UX ### Openen - `Edit` opent via de functiebalk - alleen geldig bij exact 1 geselecteerde file - alleen bij ondersteund teksttype ### Modal - openen in modal boven de bestaande dual-pane UI - modal bevat: - titel/header - bestandsnaam - volledig pad - bewerkbaar tekstgebied - `Save` - `Cancel` - rechtsboven `X` ### Sluiten - `Cancel` sluit zonder opslaan - `X` sluit zonder opslaan - `Escape`: - als geen onopgeslagen wijzigingen: direct sluiten - als wel onopgeslagen wijzigingen: waarschuwing/bevestiging tonen ### Inhoud - scrollbaar tekstgebied - monospace presentatie - selecteerbaar en bewerkbaar - geen syntax highlighting als dat extra dependencies vraagt ### Dirty state - modal houdt een eenvoudige `isDirty` status bij - verschil tussen originele inhoud en huidige inhoud bepaalt of waarschuwing nodig is --- ## 4. Backend ### Nieuwe endpoint(s) Voorstel: - hergebruik `GET /api/files/view?path=...` voor initial read - nieuw write-endpoint: - `POST /api/files/save` Voorstel request shape: - `path` - `content` - `expected_modified` of vergelijkbare timestamp/hash alleen als conflictcheck in v1 wordt gekozen Voorstel response shape: - `path` - `size` - `modified` ### Relatie met bestaand view-model `Edit` gebruikt dezelfde type-allowlist en dezelfde padvalidatie als `View`. Pragmatische lijn: - `View` blijft read-only preview - `Edit` leest initieel via `View` of een gedeelde servicefunctie - `Save` schrijft alleen naar hetzelfde pad binnen whitelist ### Validatie - alle paden via bestaand `path_guard` - directories afwijzen - unsupported types afwijzen - write alleen binnen whitelisted roots ### Grote bestanden Voorstel: - dezelfde leeslimiet als `View` is **niet** voldoende voor edit - `Edit v1` moet alleen openen tot een veilige editorlimiet, bijvoorbeeld `256 KiB` of `512 KiB` - boven die limiet: - openen blokkeren met duidelijke foutmelding - geen partial edit voor grote bestanden in v1 Reden: - partial content bewerken zonder volledige file-context is onveilig en verwarrend --- ## 5. Veiligheid en conflictgedrag ### Wijziging intussen op schijf Voorstel v1: - **wel** eenvoudige optimistic locking / modified timestamp check Mechaniek: - read-response bevat `modified` - save-request stuurt `expected_modified` - backend vergelijkt actuele `mtime` - mismatch geeft conflictfout Voordeel: - beperkt risico op stil overschrijven - technisch klein genoeg voor v1 ### Readonly/permissieproblemen Bij save: - permissieprobleem of readonly file -> `io_error` of specifieker `permission_denied` als we die foutcode toevoegen Voorstel: - als bestaande foutset compact moet blijven, map dit in v1 naar `io_error` met duidelijke boodschap ### Foutmodel Minimaal: - `path_not_found` - `path_traversal_detected` - `invalid_root_alias` - `type_conflict` - `unsupported_type` - `conflict` - `io_error` `conflict` wordt gebruikt voor modified-timestamp mismatch. --- ## 6. Scopebeperking Niet in v1: - geen syntax highlighting als dat extra dependencies vraagt - geen undo/redo systeem buiten browser-native textarea gedrag - geen find/replace - geen multi-file edit - geen directory edit - geen split view diff --- ## 7. Impactanalyse Waarschijnlijk te wijzigen backendbestanden: - `webui/backend/app/api/routes_files.py` - `webui/backend/app/api/schemas.py` - `webui/backend/app/services/file_ops_service.py` - `webui/backend/app/fs/filesystem_adapter.py` - nieuwe golden tests voor save/edit flow Waarschijnlijk te wijzigen frontendbestanden: - `webui/html/index.html` - `webui/html/app.js` - `webui/html/style.css` - `webui/backend/tests/golden/test_ui_smoke_golden.py` ### Regressierisico - `Edit` enabled/disabled toestand kan verkeerd meelopen met huidige selectie - modal-keyboardgedrag kan botsen met paneelnavigatie - save-conflict of dirty-state kan leiden tot onduidelijk UX-gedrag - onveilige overschrijving zonder conflictcheck moet vermeden worden Mitigatie: - dezelfde selectievoorwaarden als `View` - keyboard shortcuts blokkeren zolang editor open is - expliciete dirty-state en save-conflict handling --- ## 8. Teststrategie ### Golden tests Voor backend: - edit/open success voor ondersteund tekstbestand - save success - unsupported type - directory -> type conflict - path not found - traversal attempt - conflict bij gewijzigde file - io_error bij write failure ### UI smoke/regressietests Aanpassen: - `Edit` knop aanwezig in functiebalk - edit-modal container aanwezig in HTML - save/cancel controls aanwezig ### Handmatige validatie - `Edit` enabled bij exact 1 ondersteunde file - `Edit` disabled bij: - geen selectie - meerdere selectie - directoryselectie - unsupported filetype - modal opent met juiste inhoud - `Save` schrijft wijziging correct weg - `Cancel` sluit zonder opslaan - `Escape` sluit alleen veilig volgens dirty-state regel - conflictmelding bij tussentijdse externe wijziging