feat: file edit added

This commit is contained in:
kodi
2026-03-11 14:09:44 +01:00
parent ba6a369f78
commit b93cb01879
18 changed files with 701 additions and 16 deletions
+241
View File
@@ -0,0 +1,241 @@
# 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