docs(260618-smr): remove Redis references from documentation and e2e config

- CLAUDE.md: remove Redis constraint, ioredis library row, Redis architecture sentence, update compose comment
- README.md: remove Redis from prereqs, quick-start command, compose description, tech-stack live-sync row
- docs/ARCHITECTURE.md: delete Redis infrastructure table row
- docs/CONFIGURATION.md: remove Redis localhost:6379 mention from dev section
- docs/deployment.md: delete redis services table row
- docs/DEVELOPMENT.md: remove prereq mention, heading, two up commands, expose bullet, stack comment
- docs/GETTING-STARTED.md: prereq row, up command, prose mention
- docs/TESTING.md: 'API and MariaDB' (was API, MariaDB, and Redis)
- apps/pwa/e2e/README.md: delete Redis on :6379 bullet
- apps/pwa/playwright.config.ts: two comments updated (API+MariaDB, not API+MariaDB+Redis)
This commit is contained in:
Lucas Berger
2026-06-18 20:43:12 -04:00
parent b968f5d53b
commit 0b4266628b
10 changed files with 24 additions and 30 deletions
+2 -4
View File
@@ -11,7 +11,6 @@ FamilySync is a self-hosted, Dockerized family organization hub for a two-person
### Constraints ### Constraints
- **Tech stack**: MariaDB for the database — PostgreSQL is not available in the stack - **Tech stack**: MariaDB for the database — PostgreSQL is not available in the stack
- **Tech stack**: Redis available (optional, for live list sync / push)
- **Infrastructure**: Unraid host running Docker + Docker Compose - **Infrastructure**: Unraid host running Docker + Docker Compose
- **Auth**: Authelia (already deployed) + Local Auth — OIDC/OAuth2 for the custom app; all members authenticate through it - **Auth**: Authelia (already deployed) + Local Auth — OIDC/OAuth2 for the custom app; all members authenticate through it
- **Calendar backend**: Fastmail (paid, existing) is the single source for all calendars via JMAP/CalDAV - **Calendar backend**: Fastmail (paid, existing) is the single source for all calendars via JMAP/CalDAV
@@ -50,7 +49,6 @@ FamilySync is a self-hosted, Dockerized family organization hub for a two-person
| web-push | 3.6.7 | Server-side VAPID push | Generate VAPID keys, sign and dispatch push messages to browser push services (APNs for iOS, FCM for Android) | | web-push | 3.6.7 | Server-side VAPID push | Generate VAPID keys, sign and dispatch push messages to browser push services (APNs for iOS, FCM for Android) |
| @hono/oidc-auth | 1.8.3 | OIDC session middleware for Hono | Storage-less JWT session cookies; authorization-code + PKCE flow; works with any RFC-compliant OIDC provider including Authelia | | @hono/oidc-auth | 1.8.3 | OIDC session middleware for Hono | Storage-less JWT session cookies; authorization-code + PKCE flow; works with any RFC-compliant OIDC provider including Authelia |
| openid-client | 6.8.4 | Low-level OIDC primitives | If `@hono/oidc-auth` proves insufficient (e.g., custom token introspection), use this as the lower-level escape hatch | | openid-client | 6.8.4 | Low-level OIDC primitives | If `@hono/oidc-auth` proves insufficient (e.g., custom token introspection), use this as the lower-level escape hatch |
| ioredis | 5.11.0 | Redis client | Pub/sub for broadcasting list-change events to SSE connections across Node processes |
| zod | 3.24.x | Schema validation | Validate API request bodies and CalDAV event payloads before writing back to Fastmail | | zod | 3.24.x | Schema validation | Validate API request bodies and CalDAV event payloads before writing back to Fastmail |
| @hono/zod-validator | 0.8.0 | Hono middleware for Zod | Validate request body/query in route handlers with Zod schemas | | @hono/zod-validator | 0.8.0 | Hono middleware for Zod | Validate request body/query in route handlers with Zod schemas |
| @tanstack/react-query | 5.101.0 | Server state + caching | Manages calendar and list data fetching, background refetch, stale-while-revalidate; pairs with SSE for live list updates | | @tanstack/react-query | 5.101.0 | Server state + caching | Manages calendar and list data fetching, background refetch, stale-while-revalidate; pairs with SSE for live list updates |
@@ -199,7 +197,7 @@ The backend handles two auth paths: local username/password (scrypt + HS256 JWT
Calendar data lives exclusively in Fastmail CalDAV. The broker layer (`apps/api/src/broker/`) uses `tsdav` for PROPFIND/REPORT/PUT/DELETE, `ical.js` for VCALENDAR parsing, and `rrule` for server-side recurrence expansion. Writes are enqueued in a `calendarOutbox` table and drained asynchronously every 15 seconds; a ctag-based poller re-syncs calendars every 5 minutes. Calendar data lives exclusively in Fastmail CalDAV. The broker layer (`apps/api/src/broker/`) uses `tsdav` for PROPFIND/REPORT/PUT/DELETE, `ical.js` for VCALENDAR parsing, and `rrule` for server-side recurrence expansion. Writes are enqueued in a `calendarOutbox` table and drained asynchronously every 15 seconds; a ctag-based poller re-syncs calendars every 5 minutes.
Lists are persisted in MariaDB. Live list updates flow over SSE (`text/event-stream`) via an in-process Node.js `EventEmitter`; a 30-second polling fallback is always active. Push notifications (reminders + calendar change alerts) are dispatched via `web-push` (VAPID) to APNs/FCM. Redis is present in the stack but not yet used at runtime (reserved for future multi-process pub/sub). Lists are persisted in MariaDB. Live list updates flow over SSE (`text/event-stream`) via an in-process Node.js `EventEmitter`; a 30-second polling fallback is always active. Push notifications (reminders + calendar change alerts) are dispatched via `web-push` (VAPID) to APNs/FCM.
The PWA uses TanStack Query for all server state (events, lists, user, sync status, auth mode) and Zustand for UI-only state (selected date, open panels, active tab). The PWA uses TanStack Query for all server state (events, lists, user, sync status, auth mode) and Zustand for UI-only state (selected date, open panels, active tab).
@@ -221,7 +219,7 @@ familysync/
│ ├── hooks/ # useListSSE, usePushSubscription │ ├── hooks/ # useListSSE, usePushSubscription
│ ├── store/ # Zustand stores (calendarStore, listsStore) │ ├── store/ # Zustand stores (calendarStore, listsStore)
│ └── sw.ts # Custom Workbox service worker │ └── sw.ts # Custom Workbox service worker
├── docker-compose.yml # Production stack (api + mariadb + redis) ├── docker-compose.yml # Production stack (api + mariadb)
└── docker-compose.dev.yml # Dev overrides └── docker-compose.dev.yml # Dev overrides
``` ```
+5 -5
View File
@@ -15,7 +15,7 @@ A self-hosted family organization hub for a two-person household. One color-code
- Node.js 22 LTS - Node.js 22 LTS
- pnpm 11.5.1 (`corepack enable pnpm`) - pnpm 11.5.1 (`corepack enable pnpm`)
- Docker + Docker Compose (for MariaDB, Redis, and production deployment) - Docker + Docker Compose (for MariaDB and production deployment)
## Installation ## Installation
@@ -53,7 +53,7 @@ Required environment variables (set in `.env` or your Docker host):
```bash ```bash
# Start backing services # Start backing services
docker compose -f docker-compose.yml -f docker-compose.dev.yml up mariadb redis docker compose -f docker-compose.yml -f docker-compose.dev.yml up mariadb
# Run migrations # Run migrations
pnpm --filter @familysync/api db:migrate pnpm --filter @familysync/api db:migrate
@@ -79,8 +79,8 @@ The API listens on port 3000. The PWA build is served separately (Vite `preview`
apps/ apps/
api/ Hono backend — CalDAV sync, OIDC auth, lists API, push notifications api/ Hono backend — CalDAV sync, OIDC auth, lists API, push notifications
pwa/ React 19 PWA — calendar view, lists UI, service worker pwa/ React 19 PWA — calendar view, lists UI, service worker
docker-compose.yml Production services (API, MariaDB 11, Redis 7) docker-compose.yml Production services (API, MariaDB 11)
docker-compose.dev.yml Dev overrides (bind-mount src/, expose DB/Redis ports) docker-compose.dev.yml Dev overrides (bind-mount src/, expose DB ports)
``` ```
## Commands ## Commands
@@ -110,7 +110,7 @@ docker-compose.dev.yml Dev overrides (bind-mount src/, expose DB/Redis ports)
| Auth | `@hono/oidc-auth` 1.8.3 — authorization code + PKCE against Authelia | | Auth | `@hono/oidc-auth` 1.8.3 — authorization code + PKCE against Authelia |
| Calendar | tsdav 2.2.2 (CalDAV) + ical.js 2.2.1 against Fastmail | | Calendar | tsdav 2.2.2 (CalDAV) + ical.js 2.2.1 against Fastmail |
| Push | web-push 3.6.7 (VAPID) | | Push | web-push 3.6.7 (VAPID) |
| Live sync | Server-Sent Events + Redis 7 pub/sub | | Live sync | Server-Sent Events (in-process EventEmitter) |
| Frontend | React 19, Vite 8, vite-plugin-pwa 1.3, TanStack Query 5, Zustand 5 | | Frontend | React 19, Vite 8, vite-plugin-pwa 1.3, TanStack Query 5, Zustand 5 |
| Calendar UI | Schedule-X 4.6 | | Calendar UI | Schedule-X 4.6 |
-1
View File
@@ -15,7 +15,6 @@ The stack must include:
- API on `:3000` started with `DEV_AUTH_BYPASS=true` (see Security Guardrail below) - API on `:3000` started with `DEV_AUTH_BYPASS=true` (see Security Guardrail below)
- PWA dev server on `:5173` (`pnpm --filter @familysync/pwa dev`) - PWA dev server on `:5173` (`pnpm --filter @familysync/pwa dev`)
- Dev MariaDB on `:3306` (exposed via `docker-compose.dev.yml`) - Dev MariaDB on `:3306` (exposed via `docker-compose.dev.yml`)
- Redis on `:6379`
**`DEV_AUTH_BYPASS=true` MUST be set in the API's environment BEFORE the API process starts.** The harness cannot inject it at runtime — the API reads the env var once at startup. If the API is running without it, all `/api/*` requests return an auth redirect and every spec fails. **`DEV_AUTH_BYPASS=true` MUST be set in the API's environment BEFORE the API process starts.** The harness cannot inject it at runtime — the API reads the env var once at startup. If the API is running without it, all `/api/*` requests return an auth redirect and every spec fails.
+2 -2
View File
@@ -5,7 +5,7 @@
* Auth: DEV_AUTH_BYPASS=true on the API (never storageState — D-01/Pitfall 14) * Auth: DEV_AUTH_BYPASS=true on the API (never storageState — D-01/Pitfall 14)
* SW: serviceWorkers: 'block' on all profiles (D-02/Pitfall 15) * SW: serviceWorkers: 'block' on all profiles (D-02/Pitfall 15)
* baseURL: env-driven PLAYWRIGHT_BASE_URL (D-08/Rule 8) * baseURL: env-driven PLAYWRIGHT_BASE_URL (D-08/Rule 8)
* webServer: manages Vite only — API+MariaDB+Redis stay compose-managed (D-10) * webServer: manages Vite only — API+MariaDB stay compose-managed (D-10)
* *
* Run: * Run:
* pnpm --filter @familysync/pwa test:e2e * pnpm --filter @familysync/pwa test:e2e
@@ -63,7 +63,7 @@ export default defineConfig({
}, },
], ],
// D-10: manage Vite only; API+MariaDB+Redis are compose-managed // D-10: manage Vite only; API+MariaDB are compose-managed
// reuseExistingServer: reuse operator's pnpm dev locally; start fresh in CI // reuseExistingServer: reuse operator's pnpm dev locally; start fresh in CI
webServer: { webServer: {
command: 'pnpm --filter @familysync/pwa dev', command: 'pnpm --filter @familysync/pwa dev',
-1
View File
@@ -248,7 +248,6 @@ routes/setup.ts ──→ db (app_config)
| Local auth storage | scrypt PHC hash in `local_credentials.password_hash`; session signed with `LOCAL_SESSION_SECRET` env var | | Local auth storage | scrypt PHC hash in `local_credentials.password_hash`; session signed with `LOCAL_SESSION_SECRET` env var |
| Push notifications | `web-push` (VAPID) → APNs (iOS) / FCM (Android) | | Push notifications | `web-push` (VAPID) → APNs (iOS) / FCM (Android) |
| Live list sync | In-process Node.js `EventEmitter` → SSE (`text/event-stream`) | | Live list sync | In-process Node.js `EventEmitter` → SSE (`text/event-stream`) |
| Redis | Present in stack (image: `redis:7-alpine`); not used in current runtime (reserved for future multi-process pub/sub) |
| PWA | React 19 + Vite 8 + `vite-plugin-pwa` (Workbox `injectManifest` mode) | | PWA | React 19 + Vite 8 + `vite-plugin-pwa` (Workbox `injectManifest` mode) |
| Networking | Pangolin/Newt tunnel — no open ports; split-DNS internal domain | | Networking | Pangolin/Newt tunnel — no open ports; split-DNS internal domain |
| Deployment | Docker Compose on Unraid; single `api` container serves both the API and the PWA static build | | Deployment | Docker Compose on Unraid; single `api` container serves both the API and the PWA static build |
+1 -1
View File
@@ -163,7 +163,7 @@ VAPID_SUBJECT=mailto:admin@example.com
### Local Development (host-side) ### Local Development (host-side)
The dev Docker Compose override (`docker-compose.dev.yml`) exposes MariaDB on `localhost:3306` and Redis on `localhost:6379`. To run the API and PWA directly on the host: The dev Docker Compose override (`docker-compose.dev.yml`) exposes MariaDB on `localhost:3306`. To run the API and PWA directly on the host:
```bash ```bash
# Build the API first (dev script runs compiled output) # Build the API first (dev script runs compiled output)
+6 -7
View File
@@ -35,7 +35,7 @@ src/
- **Node.js 22 LTS** — the Dockerfile base is `node:22-alpine`; match this locally - **Node.js 22 LTS** — the Dockerfile base is `node:22-alpine`; match this locally
- **pnpm 11.5.1** — managed via corepack (`corepack enable pnpm`) - **pnpm 11.5.1** — managed via corepack (`corepack enable pnpm`)
- **Docker + Docker Compose** — for MariaDB and Redis in dev - **Docker + Docker Compose** — for MariaDB in dev
- **TypeScript 5.x** — installed per-workspace as a dev dependency - **TypeScript 5.x** — installed per-workspace as a dev dependency
## Local Setup ## Local Setup
@@ -48,13 +48,13 @@ pnpm install
This installs all workspace packages (`apps/api` and `apps/pwa`) in a single pass. This installs all workspace packages (`apps/api` and `apps/pwa`) in a single pass.
### 2. Start the dev database and Redis ### 2. Start the dev database
```bash ```bash
docker compose -f docker-compose.yml -f docker-compose.dev.yml up mariadb redis -d docker compose -f docker-compose.yml -f docker-compose.dev.yml up mariadb -d
``` ```
The dev override (`docker-compose.dev.yml`) exposes MariaDB on `localhost:3306` and Redis on `localhost:6379`. The dev override (`docker-compose.dev.yml`) exposes MariaDB on `localhost:3306`.
### 3. Configure environment variables ### 3. Configure environment variables
@@ -238,17 +238,16 @@ Migration files live in `apps/api/src/db/migrations/` and are committed to versi
## Docker Compose Dev Stack ## Docker Compose Dev Stack
```bash ```bash
# Bring up the full dev stack (API in Docker + MariaDB + Redis, with ports exposed) # Bring up the full dev stack (API in Docker + MariaDB, with ports exposed)
docker compose -f docker-compose.yml -f docker-compose.dev.yml up docker compose -f docker-compose.yml -f docker-compose.dev.yml up
# Bring up only backing services (run API on host for faster iteration) # Bring up only backing services (run API on host for faster iteration)
docker compose -f docker-compose.yml -f docker-compose.dev.yml up mariadb redis -d docker compose -f docker-compose.yml -f docker-compose.dev.yml up mariadb -d
``` ```
The dev override: The dev override:
- Exposes MariaDB on `localhost:3306` - Exposes MariaDB on `localhost:3306`
- Exposes Redis on `localhost:6379`
- Mounts `apps/api/src` into the container for live source access - Mounts `apps/api/src` into the container for live source access
- Sets `NODE_ENV=development` - Sets `NODE_ENV=development`
+3 -3
View File
@@ -12,7 +12,7 @@ This guide walks from a fresh clone to a running local development environment.
| ----------------------- | ------------------ | ---------------------------------------------------------------------------------- | | ----------------------- | ------------------ | ---------------------------------------------------------------------------------- |
| Node.js | `22 LTS` | Matches the `node:22-alpine` base in `apps/api/Dockerfile` | | Node.js | `22 LTS` | Matches the `node:22-alpine` base in `apps/api/Dockerfile` |
| pnpm | `11.5.1` | Pinned in `package.json` `packageManager` field; enable via `corepack enable pnpm` | | pnpm | `11.5.1` | Pinned in `package.json` `packageManager` field; enable via `corepack enable pnpm` |
| Docker + Docker Compose | Any recent version | Used to run MariaDB and Redis locally | | Docker + Docker Compose | Any recent version | Used to run MariaDB locally |
**Node version management:** If you use nvm or fnm, install Node 22 LTS and set it as the default before continuing. There is no `.nvmrc` in the repo; the target version comes from the Dockerfile. **Node version management:** If you use nvm or fnm, install Node 22 LTS and set it as the default before continuing. There is no `.nvmrc` in the repo; the target version comes from the Dockerfile.
@@ -72,10 +72,10 @@ Open `.env` and fill in the required values. See [docs/CONFIGURATION.md](CONFIGU
### 5. Start the database services ### 5. Start the database services
```bash ```bash
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d mariadb redis docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d mariadb
``` ```
This starts MariaDB (bound to `localhost:3306`) and Redis (`localhost:6379`) using the dev override. Wait for MariaDB to pass its health check before proceeding. This starts MariaDB (bound to `localhost:3306`) using the dev override. Wait for MariaDB to pass its health check before proceeding.
### 6. Run database migrations ### 6. Run database migrations
+1 -1
View File
@@ -89,7 +89,7 @@ pnpm --filter @familysync/pwa test:e2e:ui
pnpm --filter @familysync/pwa test:e2e:headed pnpm --filter @familysync/pwa test:e2e:headed
``` ```
The `baseURL` is driven by `PLAYWRIGHT_BASE_URL` (default: `http://localhost:5173`). In local mode the config reuses a running Vite dev server; in CI it starts Vite itself. The API, MariaDB, and Redis must already be running via Docker Compose before launching e2e tests locally — see `docs/DEVELOPMENT.md`. The `baseURL` is driven by `PLAYWRIGHT_BASE_URL` (default: `http://localhost:5173`). In local mode the config reuses a running Vite dev server; in CI it starts Vite itself. The API and MariaDB must already be running via Docker Compose before launching e2e tests locally — see `docs/DEVELOPMENT.md`.
### Type checking (separate from tests — required) ### Type checking (separate from tests — required)
+1 -2
View File
@@ -17,10 +17,9 @@ Self-hosted Docker deployment on Unraid behind Authelia OIDC and a Pangolin/Newt
The production compose file brings up three services: The production compose file brings up three services:
| Service | Image | Purpose | | Service | Image | Purpose |
| --------- | ---------------------------------------------------- | ---------------------------------------------------------- | | --------- | ---------------------------------------------------- | --------------------------------------------------- |
| `api` | Built from `apps/api/Dockerfile` target `production` | Hono API + compiled React PWA, listens on port 3000 | | `api` | Built from `apps/api/Dockerfile` target `production` | Hono API + compiled React PWA, listens on port 3000 |
| `mariadb` | `mariadb:11` | Persistent MariaDB database | | `mariadb` | `mariadb:11` | Persistent MariaDB database |
| `redis` | `redis:7-alpine` | Present for live list sync (pub/sub); unused until Phase 4 |
--- ---