4. Solution Strategy
4.1 Approach
forked is a local-first, offline-first PWA. Every device holds the full data set in PouchDB and works without a network. Optional sync replicates that store directly with a CouchDB. The sync mode is a property of the deployment, not a user choice.
4.2 Technology Decisions
The one list of technologies; other sections link here.
| Concern | Choice | Why | Quality goal |
|---|---|---|---|
| Architecture | Local-first | Data on the device, sync optional | Offline-First, Privacy |
| Delivery | PWA only (ADR-039) | One installable web UI for phones, tablets and desktops, updates via service worker | Usability |
| Frontend | React 19, TypeScript (strict), Tailwind 4, react-router 7 | Component model, large ecosystem, mobile-first utilities | Usability, Learnability |
| Build, packages | Vite with vite-plugin-pwa, Bun | Fast builds, TypeScript without a toolchain | Evolvability |
| Client database | PouchDB over IndexedDB | Browser-native persistence with CouchDB-compatible replication | Offline-First |
| Sync | Direct PouchDB-to-CouchDB replication (ADR-028) | One sync path, no server code of ours in the data path | Privacy, Operability |
| Sync mode | Self-hosted or forked cloud, chosen by /forked-config.json (ADR-038) | One image serves both; users never choose | Learnability, Evolvability |
| Conflicts | CouchDB deterministic revision winner (ADR-025) | Convergence without custom code | Reliability |
| i18n | react-i18next with JSON files | Standard, easy to extend (Section 8.5) | Internationalization |
| AI import | Opt-in, user’s own provider and key (ADR-024) | Only off-device path besides sync, gated by consent | Privacy, Usability |
| Tests, CI | Vitest, Playwright, GitHub Actions | Section 8.8 | Reliability |
4.3 Achieving the Quality Goals
| Goal | Approach |
|---|---|
| Usability | Mobile-first adaptive shell, bottom navigation on phones, optimistic local updates, 44×44 px touch targets (Section 8.2). |
| Learnability | Familiar mobile patterns, minimal configuration, one sync flow per deployment. Self-hosting asks only for a user name and password; address and database are implicit. |
| Offline-First | Read and write the local store first; live replication runs in the background; conflicts converge automatically (Section 6.2, Section 6.3). |
| Privacy | Data leaves the device only through household sync and consented AI import; no analytics; a restrictive CSP; no built-in backend; export for portability (Section 8.3). Security measures are part of this goal. |
| Internationalization | All UI text from locale files, German and English, key parity enforced (Section 8.5). |
4.4 Sync Modes
The PWA replicates directly with CouchDB in both modes. The Sync page shows exactly one flow.
| Aspect | Self-hosted mode (no gateway announced) | Forked cloud mode (gateway announced) |
|---|---|---|
| Identity | One CouchDB user shared by all devices; no accounts, invites or device records | Account on the operator’s website; each device enrolled by device approval or invite |
| Credential | User name and password, stored as SelfHostedLogin; Basic auth | Session cookie at the gateway, 15-minute CouchDB JWT in memory; stored only as GatewayEnrollment |
| Database | Fixed name forked, address from the announcement | Named by the sync token and pinned per device |
| Server side | Plain CouchDB and proxy (Section 7.1) | Operator gateway and website, outside this repository (Section 7.3) |
| Flow | Section 6.1 | Section 6.4 |
One deployment equals one household and one database. Multi-tenancy belongs in the operator’s gateway, not in the self-hosted default. Self-hosting is the baseline because it fits the main use case, one household with as little operator complexity as possible and data on infrastructure the household controls.
4.5 Patterns
- Local store as single source for the UI: components read and write through
ForkedDatabaseonly (Section 5.1); they never talk to the network for core data. - Background replication: PouchDB live sync with
retry: truereplicates the local database. There is no application operation queue. Start-up retries and failure rules are in Section 6.2. - Strategy per mode: both modes share
syncWithRemoteand the status store and differ only in how the remote is authenticated (Section 5.2). - Layered dependencies: enforced by an architecture test (ADR-031).