# 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: ` 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.