234 lines
8.0 KiB
Markdown
234 lines
8.0 KiB
Markdown
# Local Upload v1
|
|
|
|
## 1. Doel
|
|
Local upload voegt nu direct waarde toe omdat de app al een bruikbare dual-pane bestandsworkflow heeft, maar nog geen ingang om bestanden vanaf de lokale machine de beheerde storage in te brengen. Dat gat is functioneel groot: browse, rename, move, copy en delete bestaan al, maar import ontbreekt.
|
|
|
|
Binnen de dual-pane workflow is de meest natuurlijke semantiek:
|
|
- bron: lokale machine via de native browser file picker
|
|
- doel: `currentPath` van het actieve paneel
|
|
|
|
Dat houdt het model eenvoudig en voorspelbaar. De gebruiker kiest eerst waar in de storage hij staat, en uploadt daarna naar die locatie.
|
|
|
|
## 2. Scope
|
|
Aanbevolen scope voor v1:
|
|
- upload van lokale bestanden via browser naar storage
|
|
- target = `currentPath` van het actieve paneel
|
|
- native browser file picker gebruiken
|
|
- single-file upload
|
|
- multi-file upload
|
|
- geen folder upload in v1
|
|
- geen drag & drop in v1
|
|
- geen resumable upload
|
|
- geen chunked upload
|
|
|
|
Motivatie:
|
|
- Multi-file upload via de native picker is klein en nuttig.
|
|
- Folder upload verhoogt de complexiteit direct sterk: recursie, conflictgedrag, voortgang, directory-creatie, mixed failures.
|
|
- Drag & drop is UX-matig aantrekkelijk, maar voegt event-complexiteit en extra foutpaden toe zonder dat het nodig is voor een eerste bruikbare versie.
|
|
- Chunking/resume is pas zinvol als gewone multipart upload aantoonbaar onvoldoende is.
|
|
|
|
## 3. Startgedrag / UI
|
|
Voor v1:
|
|
- een `Upload` knop links van `F1 Settings` in de onderbalk/topactiezone waar die nu logisch past
|
|
- klik op `Upload` opent direct de native browser file picker
|
|
- de upload werkt altijd naar het actieve paneel
|
|
- de UI toont compact en expliciet:
|
|
- `Upload to: <currentPath van actief paneel>`
|
|
|
|
Aanbevolen flow:
|
|
1. gebruiker activeert een paneel
|
|
2. gebruiker klikt `Upload`
|
|
3. browser opent native file picker
|
|
4. gebruiker kiest 1 of meerdere bestanden
|
|
5. upload start naar `currentPath` van actief paneel
|
|
6. voortgang wordt zichtbaar
|
|
7. na afronding wordt het actieve paneel refreshed
|
|
|
|
Belangrijk:
|
|
- de actieve-paneelcontext moet vooraf duidelijk zijn
|
|
- de knop hoeft niet disabled te zijn zolang een geldig `currentPath` bestaat
|
|
- als een modal open is, moet `Upload` niet tegelijk een nieuwe flow starten
|
|
|
|
## 4. Voortgang
|
|
Aanbevolen v1-model:
|
|
- één compacte upload-progress UI per lopende uploadbatch
|
|
- globale voortgang over de batch
|
|
- daarnaast compacte status per huidig bestand indien nodig
|
|
|
|
V1 hoeft niet meteen een volledige task-UI te hergebruiken. De eenvoudigste bruikbare richting is:
|
|
- één uploadstatusblok of kleine modal
|
|
- toont:
|
|
- totaal aantal bestanden
|
|
- huidig bestand
|
|
- globale voortgangsbalk of percentage
|
|
|
|
Aanbevolen velden in de UI:
|
|
- `Uploading 3 files to /Volumes/...`
|
|
- `2/3 files`
|
|
- huidige bestandsnaam
|
|
- percentage of bytes-progress voor de actieve upload
|
|
|
|
Dit is lichter dan de bestaande task-list volledig integreren in v1.
|
|
|
|
## 5. Backend-impact
|
|
Er is zeer waarschijnlijk een nieuw upload-endpoint nodig, bijvoorbeeld:
|
|
- `POST /api/files/upload`
|
|
|
|
Verwachte vorm:
|
|
- multipart/form-data
|
|
- target path als apart veld, bijvoorbeeld `target_path`
|
|
- één of meerdere file parts
|
|
|
|
Veiligheidsmodel:
|
|
- `target_path` altijd via bestaande `path_guard`
|
|
- target moet binnen whitelist/toegestane roots vallen
|
|
- target moet bestaan
|
|
- target moet een directory zijn
|
|
- bestandsnamen niet vertrouwen vanuit clientpad-informatie
|
|
- alleen de basename van het gekozen lokale bestand gebruiken
|
|
- validatie van naam via bestaande naamregels (`validate_name` of equivalent)
|
|
- geen client-side padsegmenten overnemen
|
|
|
|
Traversalpreventie:
|
|
- geen directorystructuur uit de browser aan serverzijde interpreteren in v1
|
|
- geen relatieve paden uit multipart metadata vertrouwen
|
|
- ieder bestand wordt server-side gemapt naar:
|
|
- `target_path / validated_basename`
|
|
|
|
## 6. Conflictgedrag
|
|
Ontwerp voor Engelstalige keuzes:
|
|
- `Overwrite`
|
|
- `Overwrite all`
|
|
- `Skip`
|
|
- `Cancel`
|
|
|
|
Aanbevolen v1-gedrag:
|
|
- conflictcontrole gebeurt server-side per bestand
|
|
- bij conflict in een batch wordt de batch niet stil doorgezet
|
|
- de UI toont een compacte conflictmodal voor het huidige conflicterende bestand
|
|
- de gebruiker kiest één actie
|
|
|
|
Semantiek:
|
|
- `Overwrite`: alleen huidig conflicterend bestand overschrijven
|
|
- `Overwrite all`: huidig en alle volgende conflicten automatisch overschrijven
|
|
- `Skip`: huidig conflicterend bestand overslaan en doorgaan
|
|
- `Cancel`: resterende batch stoppen
|
|
|
|
Aanbevolen v1-realisatie:
|
|
- conflict afhandelen per bestand binnen de uploadbatch-flow
|
|
- geen complexe vooraf-scan van alle conflicten nodig
|
|
- geen rollback
|
|
|
|
Belangrijk:
|
|
- ook directoryconflicten moeten duidelijk zijn
|
|
- als target al een directory met dezelfde naam bevat voor een file-upload, moet dat als conflict/typefout behandeld worden
|
|
|
|
## 7. Grote bestanden / performance
|
|
Aanbevolen v1:
|
|
- gewone multipart upload
|
|
- geen chunking
|
|
- geen resumable upload
|
|
|
|
Motivatie:
|
|
- technisch het eenvoudigst
|
|
- breed ondersteund door browser en backendstack
|
|
- voldoende voor een eerste bruikbare versie
|
|
|
|
Risico:
|
|
- zeer grote bestanden kunnen lang duren of mislukken bij netwerkonderbreking
|
|
- dat risico moet in v1 geaccepteerd en netjes gecommuniceerd worden
|
|
|
|
V1 hoeft daarom niet meer te doen dan:
|
|
- voortgang tonen
|
|
- foutmelding tonen bij mislukking
|
|
- geen herstart of resume bieden
|
|
|
|
## 8. Relatie met tasks/history
|
|
Aanbevolen v1:
|
|
- upload opnemen in `history`
|
|
- upload niet meteen in het generieke `tasks` model stoppen
|
|
|
|
Motivatie:
|
|
- upload heeft wel auditwaarde, dus history is logisch
|
|
- task-integratie maakt de slice groter: background execution, task persistence, progress mapping, polling-UI integratie
|
|
- voor een eerste bruikbare upload is een lichtere directe UI-flow met history-opslag pragmatischer
|
|
|
|
History v1 voor upload zou moeten registreren:
|
|
- operation = `upload`
|
|
- status = `completed` / `failed`
|
|
- destination = doelpad
|
|
- path of source-naam waar nuttig
|
|
- error_code / error_message bij failure
|
|
|
|
Als later blijkt dat uploads langlopend worden of meerdere gelijktijdige uploads normaal zijn, kan task-integratie in v2 logisch worden.
|
|
|
|
## 9. Regressierisico
|
|
Belangrijkste risico's:
|
|
- security: onbetrouwbare bestandsnamen of target path misbruik
|
|
- grote bestanden: timeouts of langlopende requests
|
|
- foutafhandeling: deels geslaagde batch zonder duidelijke feedback
|
|
- UI-complexiteit: conflictflow kan snel onrustig worden
|
|
- actieve-paneelcontext: upload naar verkeerd paneel/pad als context niet duidelijk is
|
|
- conflictafhandeling: onduidelijke semantiek rond overwrite/skip
|
|
|
|
Laag-regressierisico aanpak:
|
|
- target altijd expliciet koppelen aan actief paneel
|
|
- geen folder upload
|
|
- geen drag & drop
|
|
- geen chunking/resume
|
|
- compacte conflictmodal per bestand
|
|
- direct paneelrefresh na succesvolle upload(s)
|
|
|
|
## 10. Teststrategie
|
|
Backend golden tests:
|
|
- upload single file success
|
|
- upload multi-file success
|
|
- target path not found
|
|
- target path is file -> type_conflict
|
|
- traversal blocked
|
|
- invalid root alias
|
|
- invalid filename blocked
|
|
- conflict -> already_exists of equivalent
|
|
- overwrite success
|
|
- skip/cancel flow indien servercontract dat nodig maakt
|
|
|
|
UI smoke/regressietests:
|
|
- `Upload` knop aanwezig links van `F1 Settings`
|
|
- geen uploadstart als ongeldige UI-context aanwezig is
|
|
- targetpaneel-context zichtbaar in uploadflow
|
|
- progress UI verschijnt
|
|
- conflictkeuze-UI verschijnt met:
|
|
- `Overwrite`
|
|
- `Overwrite all`
|
|
- `Skip`
|
|
- `Cancel`
|
|
|
|
Handmatige validatie:
|
|
- upload 1 klein bestand
|
|
- upload meerdere bestanden
|
|
- conflict op bestaand bestand
|
|
- overwrite all werkt over meerdere conflicten
|
|
- skip laat batch doorgaan
|
|
- cancel stopt batch
|
|
- actief paneel bepaalt doelpad correct
|
|
- history bevat upload-resultaten
|
|
|
|
## 11. Aanbeveling
|
|
Aanbevolen v1-richting met laag regressierisico:
|
|
- native browser file picker
|
|
- single + multi-file upload
|
|
- target = `currentPath` van actief paneel
|
|
- geen folder upload
|
|
- geen drag & drop
|
|
- gewone multipart upload
|
|
- directe voortgangsweergave in lichte upload-UI
|
|
- conflictafhandeling per bestand met:
|
|
- `Overwrite`
|
|
- `Overwrite all`
|
|
- `Skip`
|
|
- `Cancel`
|
|
- wel history-integratie
|
|
- nog geen task-integratie
|
|
|
|
Dit is de kleinste versie die echt bruikbaar is, zonder meteen te ontsporen in mediaserver- of synchronisatiecomplexiteit.
|