Files
WhispAssist/docs/adr/0010-remote-sync-targets.md
T

73 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ADR-0010 — Remote sync / upload targets
- **Status:** Accepted
- **Date:** 2026-06-30
- **Context source:** User request (2026-06-30)
## Context
WA stores everything locally. The user wants the **option** to upload meeting artifacts
(transcript, notes, summary, and optionally the `.wav` recording) to a destination they configure.
Required (primary) targets: **Nextcloud, ownCloud, Cloudreve, Seafile**. Desired (secondary):
**OneDrive, Dropbox, Box, Synology NAS**.
This must be reconciled with WA's core promise (local-only). The reconciliation: sync is an
**explicit, user-configured export** — exactly the carve-out the privacy invariant already allows.
It is **off by default**, never automatic without configuration, and clearly surfaced. The primary
targets are notably all **self-hostable**, so the default story is "your data, on your server."
## Decision
### One protocol covers the entire primary set: WebDAV
Nextcloud, ownCloud, Cloudreve, and Seafile (via SeafDAV) all expose **WebDAV (RFC 4918)**, as does
**Synology** (WebDAV Server package). So a single `WebDavTarget` implementation serves all four
primary targets **and** Synology:
- Upload: `PUT`; create folders: `MKCOL`; existence/listing: `PROPFIND`.
- Large files (`.wav`): chunked/resumable upload where the server supports it (e.g. Nextcloud
chunked upload); otherwise single `PUT` with a size guard.
- Per-server base paths, e.g. Nextcloud/ownCloud `…/remote.php/dav/files/<user>/`,
Seafile `…/seafdav/`, Cloudreve `…/dav`. Seafile note: SeafDAV is **disabled by default**
server-side and may need `LOCK` disabled — surfaced in setup help.
- Auth: URL + username + **app password** (recommended over account password where supported).
### Secondary targets use provider APIs + OAuth (one impl each)
`OneDriveTarget` (Microsoft Graph), `DropboxTarget` (Dropbox API v2), `BoxTarget` (Box API). Each
uses **OAuth 2.0 Authorization Code + PKCE** with a **loopback redirect** (`http://127.0.0.1:<port>`)
— desktop-appropriate, no client secret embedded. Resumable/upload-session APIs for large files.
Synology can alternatively use its FileStation API, but WebDAV is the default path for it.
### Common architecture
- A `SyncTarget` trait (`test`, `ensure_dir`, `put`, `exists`) abstracts all providers; a
`SyncManager` owns a **durable queue** of upload jobs (per artifact × per target).
- **What/when to upload is configurable** (FR-SYNC-3): choose artifacts (transcript / notes /
summary / recording) and trigger (on finalize, manual "Upload now", or retry). Recording is
uploadable only if it was retained (ADR-0009).
- **Reliability:** queue with exponential-backoff retry; SHA-256 to skip unchanged files
(idempotent); resumable upload for large recordings; status per job surfaced via events.
- **Remote layout:** mirrors local meeting folders under a user-chosen base path.
- **Credentials:** stored in the **OS credential store** (Windows Credential Manager / DPAPI),
referenced by target id — **never** in `settings.json` or the DB.
- **Transport security:** TLS required; plaintext `http://` is refused unless the user explicitly
allows it for a LAN address, with a warning.
- **Privacy labeling:** primary/self-hosted targets are labeled "your server"; third-party clouds
(OneDrive/Dropbox/Box) carry a clear "data leaves your device to a third party" banner, mirroring
the remote-LLM caveat (ADR-0007). Enabling any sync requires explicit acknowledgment.
- **Optional client-side encryption** before upload (ties to FR-SEC-3): when the WA vault is
enabled, artifacts can be encrypted locally so the destination only ever holds ciphertext —
provider-agnostic, independent of any server-side E2EE.
## Consequences
- **Positive:** four primary targets + Synology delivered by **one** WebDAV implementation — small,
testable surface; secondary set is additive and isolated behind the same trait; default-off +
explicit config keeps the privacy promise intact; self-hostable primaries fit the ethos.
- **Negative / care:** secondary targets each need an OAuth app registration (client IDs) and
per-provider quirks (chunk sizes, path APIs) — hence "secondary"; sync introduces real network
egress, so the privacy egress test (FR-SEC-1) must be widened to *allow only* configured target
hosts and *fail* on any other; credential handling and TLS enforcement are security-critical.
- **Phasing:** WebDAV primary set first, then OAuth secondary set (see Phase 9 in `05-roadmap.md`).
## Revisit if
A primary target drops WebDAV, or we need provider-native features (e.g. Nextcloud Talk, Seafile
library sharing) beyond plain file upload — would add a provider-specific path behind the trait.