Files

8.5 KiB

Research: Remote Single-File Copy To Host

Relevante file analysis

Backend

  • routes_files.py Bevat de bestaande lokale upload-route (POST /api/files/upload) en de remote read-only Phase 3 routes (view, info, download, image) via RemoteFileService.
  • routes_copy.py Bevat de bestaande copy-route (POST /api/files/copy) die volledig uitgaat van host-side source en host-side destination.
  • file_ops_service.py Bevat lokale file-acties. Relevant is vooral upload(), omdat die host-write doet na PathGuard-validatie van een doeldirectory.
  • copy_task_service.py Bevat task-opbouw, destination-validatie en taakcreatie voor copy, maar gaat uit van een lokale bron die via PathGuard naar een host-pad resolveert.
  • remote_file_service.py Bevat al de benodigde remote read-path parsing, share-validatie via registry, agent-auth, error mapping en een gestreamde prepare_download() naar de agent.
  • filesystem_adapter.py Bevat de feitelijke host-write helpers:
    • write_uploaded_file(path, file_stream, overwrite=False)
    • copy_file(source, destination, on_progress=None) copy_file vereist een lokale bron op de host en is dus niet bruikbaar voor remote input. write_uploaded_file schrijft een inkomende stream naar een hostpad en is conceptueel het dichtstbij.
  • path_guard.py Houdt host-write validatie strikt lokaal. Dat moet zo blijven; remote paden mogen hier niet als bronsemantiek in terechtkomen.
  • tasks_runner.py Bevat task-based copy/move uitvoering, maar alleen voor host-side bronpaden. Wel relevant als patroon voor een aparte remote-to-host worker.
  • schemas.py Bevat bestaande CopyRequest en upload/copy response-modellen. Voor een aparte feature is waarschijnlijk een nieuw requestmodel nodig.

Frontend

  • app.js Relevante bestaande flows:
    • uploadFileRequest() gebruikt uitsluitend /api/files/upload
    • startCopySelected() gebruikt uitsluitend /api/files/copy
    • remote browse/view/download is al source-aware
    • remote copy is nu bewust geblokkeerd Dit bevestigt dat upload-flow en copy-flow momenteel twee losse UI-contracten zijn.

Agent

  • finder_commander/app/main.py Agent heeft al wat voor deze feature nodig is:
    • strikte share + relative path validatie
    • GET /api/info
    • GET /api/download Voor remote single-file copy naar host is geen nieuwe remote write-API nodig.

Oordeel over hergebruik van upload-internals

Bestaande upload-functionaliteit aanpassen?

Nee.

Reden:

  • de bestaande upload-route, upload-requestvorm en upload-UI werken al goed
  • upload is browser -> host via multipart/form-data
  • de gewenste feature is agent/remote -> host via backend-proxy/stream
  • dat is een ander contract, andere foutbron en andere bronsemantiek

Interne host-write logica hergebruiken?

Ja, maar alleen op intern helper/service-niveau.

Concreet oordeel:

  • FilesystemAdapter.copy_file() is niet geschikt voor hergebruik Reden: vereist een lokale host-bronpad als source.
  • FilesystemAdapter.write_uploaded_file() is deels relevant Reden: dit doet precies de host-write van een inkomende stream naar een doelbestand.
  • Direct hergebruik van FileOpsService.upload() is niet verstandig Reden: die methode is semantisch en contractueel gekoppeld aan multipart upload en UploadFile.

Best passende richting:

  • niet hergebruiken via bestaande upload-endpoints of upload-flow
  • wel overwegen om de onderliggende stream-naar-bestand write logica te hergebruiken of te veralgemeniseren in FilesystemAdapter
  • voorkeur: een nieuwe sibling-helper zoals write_stream_file(...) of een kleine interne extractie, zodat upload ongewijzigd blijft en remote copy dezelfde veilige host-write primitief kan gebruiken

Ontwerpvoorstel

Feature

Copy remote file to host

Scope

  • alleen single file
  • alleen source onder /Clients/...
  • alleen destination op host-side lokale map
  • geen mappen
  • geen overwrite in eerste change request tenzij expliciet gewenst
  • geen upload-route hergebruik
  • geen brede refactor

Backendontwerp

Voeg een aparte backend feature toe, niet via POST /api/files/upload en niet via bestaande POST /api/files/copy.

Voorkeursvorm:

  • nieuwe route, bijvoorbeeld POST /api/files/remote-copy
  • request bevat:
    • source: remote bestandspad onder /Clients/...
    • destination_dir: host-directory pad

Nieuwe service, bijvoorbeeld:

  • RemoteCopyToHostService

Verantwoordelijkheden:

  1. valideer dat source een remote /Clients/... file is
  2. valideer dat destination_dir een host-directory is via bestaande lokale PathGuard
  3. haal remote metadata op of resolve remote naam via bestaande RemoteFileService
  4. bouw destination pad als destination_dir/<remote-filename>
  5. faal op bestaand doelbestand in eerste versie
  6. open remote download-stream via aparte interne helper op RemoteFileService
  7. schrijf gestreamd naar host met een aparte interne host-write helper
  8. map fouten strikt:
    • remote unavailable blijft lokale actie-fout
    • host permission/path-conflict blijft gewone host-fout

Aanbevolen interne hergebruikslijn

  • laat RemoteFileService een interne streaming primitive aanbieden, bijvoorbeeld een variant op de huidige remote download-open logica zonder HTTP-response voor browser-download
  • laat FilesystemAdapter een aparte stream-write helper aanbieden voor generieke inkomende streams
  • laat upload zijn bestaande publieke route en flow behouden

Frontendontwerp

Geen wijziging aan upload-UI.

Kleine aparte UI-feature:

  • toon een aparte actie alleen als:
    • bronpane een remote file-selectie heeft van exact 1 bestand
    • doelpane op een host/local directory staat
  • de actie roept de nieuwe backend-route aan
  • na succes:
    • refresh beide panes
    • toon lokale foutmelding bij falen

Voorkeur:

  • aparte actie of expliciete source-aware branch voor "Copy remote file to host"
  • niet de bestaande upload-flow hergebruiken

Agentontwerp

Geen nieuwe agent-endpoints nodig in deze scope.

De bestaande GET /api/download is voldoende als read-only bron voor streaming.

Acceptance criteria

  • een enkel bestand onder /Clients/... kan naar een host-directory worden gekopieerd
  • de destination moet een host/local directory zijn
  • mappen als remote bron worden geweigerd
  • remote -> remote wordt geweigerd
  • host -> remote wordt geweigerd
  • overwrite gebeurt niet impliciet; bestaand doelbestand geeft een nette fout
  • bestaande upload-route, upload-contract en upload-UI blijven ongewijzigd
  • bestaande lokale copy-flow blijft ongewijzigd
  • remote fouten blijven lokaal tot deze actie
  • host-write blijft onder bestaande lokale PathGuard-regels vallen
  • data wordt gestreamd; geen volledige file-buffer in memory

Klein plan

  1. Voeg een research-backed change request toe voor een aparte route POST /api/files/remote-copy.
  2. Voeg een kleine service toe die alleen remote single-file source + local destination_dir ondersteunt.
  3. Voeg een interne streaming helper toe in RemoteFileService voor remote bestand-inname door backend.
  4. Voeg een aparte interne host-write helper toe in FilesystemAdapter voor generieke stream-naar-bestand writes, zonder upload-API te wijzigen.
  5. Voeg minimale frontend wiring toe voor een aparte "Copy remote file to host"-actie.
  6. Test stapsgewijs:
    • success path remote file -> local dir
    • bestaand doelbestand
    • remote directory rejected
    • remote failure stays local
    • upload-regressie: bestaande /api/files/upload blijft ongewijzigd

Expliciete lijst van wat buiten scope blijft

  • remote mappen kopiëren
  • remote write-acties
  • remote -> remote
  • host -> remote
  • aanpassing van bestaande upload-routes
  • aanpassing van upload-requestcontract
  • aanpassing van upload-UI
  • brede refactor van copy/upload/task-infrastructuur
  • bookmarks/startup paths
  • remote task-runner verbreding buiten deze ene actie