style(13-03): apply Prettier formatting across repo
Mechanical reformat — no logic changes. 398 files changed, 19125 insertions(+), 16457 deletions(-). Prettier 3.8.4 with .prettierrc (singleQuote:true, semi:true, tabWidth:2, trailingComma:all, printWidth:100). Isolated per D-13-08 for reviewability.
This commit is contained in:
+89
-83
@@ -12,15 +12,15 @@ This section covers ONLY what is new for v1.1. The rest of the file (below) docu
|
||||
|
||||
### What needs NO new dependency
|
||||
|
||||
| Feature | Existing tool that covers it | Why no addition needed |
|
||||
|---------|------------------------------|------------------------|
|
||||
| Per-event reminders (VALARM) | `ical.js` + `tsdav` + existing write path | VALARM is a VCALENDAR component; ical.js parses/emits it; tsdav handles the PUT. No new library. |
|
||||
| Outbox drain event-driven wake | `ioredis` pub/sub (already in stack) | Publish a `caldav:drain` event on Redis after a write; outbox worker subscribes and drains immediately. Zero new deps. |
|
||||
| Admin Settings UI (app passwords + shared calendar) | Existing Drizzle schema + AES-256-GCM crypto (already in `apps/api`) | Role-gated Hono routes + React form. Schema already has the tables. |
|
||||
| Setup wizard — DB connectivity probe | `mysql2` (already in stack) | Attempt a `mysql2` connect with the env-supplied credentials; resolve/reject gives pass/fail. |
|
||||
| Setup wizard — VAPID key validation | `web-push` + Node.js built-in `crypto` (already in stack) | `Buffer.from(key, 'base64url').length === 32` for the private key; `web-push.generateVAPIDKeys()` for a fresh keypair; no extra library. |
|
||||
| Setup wizard — OIDC discovery probe | Node.js 22 built-in `fetch` | `fetch(issuer + '/.well-known/openid-configuration')` and check for `200` + `authorization_endpoint` field. Native fetch in Node 22; zero extra library. |
|
||||
| Setup wizard — env-var presence checks | `zod` (already in stack) | A `z.object({...}).safeParse(process.env)` at startup is the entire validation. Already used for request body validation. |
|
||||
| Feature | Existing tool that covers it | Why no addition needed |
|
||||
| --------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Per-event reminders (VALARM) | `ical.js` + `tsdav` + existing write path | VALARM is a VCALENDAR component; ical.js parses/emits it; tsdav handles the PUT. No new library. |
|
||||
| Outbox drain event-driven wake | `ioredis` pub/sub (already in stack) | Publish a `caldav:drain` event on Redis after a write; outbox worker subscribes and drains immediately. Zero new deps. |
|
||||
| Admin Settings UI (app passwords + shared calendar) | Existing Drizzle schema + AES-256-GCM crypto (already in `apps/api`) | Role-gated Hono routes + React form. Schema already has the tables. |
|
||||
| Setup wizard — DB connectivity probe | `mysql2` (already in stack) | Attempt a `mysql2` connect with the env-supplied credentials; resolve/reject gives pass/fail. |
|
||||
| Setup wizard — VAPID key validation | `web-push` + Node.js built-in `crypto` (already in stack) | `Buffer.from(key, 'base64url').length === 32` for the private key; `web-push.generateVAPIDKeys()` for a fresh keypair; no extra library. |
|
||||
| Setup wizard — OIDC discovery probe | Node.js 22 built-in `fetch` | `fetch(issuer + '/.well-known/openid-configuration')` and check for `200` + `authorization_endpoint` field. Native fetch in Node 22; zero extra library. |
|
||||
| Setup wizard — env-var presence checks | `zod` (already in stack) | A `z.object({...}).safeParse(process.env)` at startup is the entire validation. Already used for request body validation. |
|
||||
|
||||
### What IS new for v1.1
|
||||
|
||||
@@ -37,6 +37,7 @@ This section covers ONLY what is new for v1.1. The rest of the file (below) docu
|
||||
**Install scope:** `devDependencies` in `apps/pwa` only (not the monorepo root; only the PWA workspace needs browser tests).
|
||||
|
||||
**Why this and not playwright-cli alone:**
|
||||
|
||||
- `playwright-cli` (the global binary) does not support `storageState` file save/restore — the mechanism required to inject an Authelia session into a test context without re-running the full OIDC redirect flow on every test run.
|
||||
- `@playwright/test` provides `devices` registry (iPhone 15 Pro, Pixel 5, etc.) which sets `viewport`, `userAgent`, `isMobile`, `hasTouch` together as a named preset.
|
||||
- `@playwright/test` is the only path to a `playwright.config.ts` that defines a `setup` project (do login once, write `storageState` to `.auth/user.json`) and a `mobile` project that consumes it — the pattern needed for an authenticated, mobile-emulated CI run against the DEV_AUTH_BYPASS entry point.
|
||||
@@ -136,7 +137,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ vars.GITEA_REGISTRY }} # e.g. git.bergerhouse.ca
|
||||
registry: ${{ vars.GITEA_REGISTRY }} # e.g. git.bergerhouse.ca
|
||||
username: ${{ secrets.REGISTRY_USER }}
|
||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
- uses: docker/build-push-action@v5
|
||||
@@ -169,42 +170,42 @@ jobs:
|
||||
|
||||
### Core Technologies
|
||||
|
||||
| Technology | Version | Purpose | Why Recommended |
|
||||
|------------|---------|---------|-----------------|
|
||||
| Node.js + TypeScript | 22 LTS | Backend runtime | First-class typing, same language as frontend, largest CalDAV/OIDC library ecosystem |
|
||||
| Hono | 4.12.23 | HTTP framework | Web-Standards-native, first-class TypeScript, built-in SSE helper, WebSocket via `@hono/node-server`; lighter than Express and better ergonomics than Fastify for this size |
|
||||
| Drizzle ORM | 0.45.2 | MariaDB query layer | Type-safe SQL, zero runtime overhead, native `mysql2` driver support, schema-as-code migrations via `drizzle-kit` |
|
||||
| mysql2 | 3.22.4 | MariaDB driver | The only maintained native MariaDB/MySQL driver; Drizzle targets it explicitly |
|
||||
| React 19 | 19.x | PWA frontend | Required by project; concurrent features, stable |
|
||||
| Vite | 8.0.x | Build tooling | De-facto standard for React PWAs; fast HMR, native ESM |
|
||||
| vite-plugin-pwa | 1.3.0 | Service worker + manifest | Zero-config Workbox integration, handles install prompt, offline cache, background sync scaffolding |
|
||||
| Technology | Version | Purpose | Why Recommended |
|
||||
| -------------------- | ------- | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Node.js + TypeScript | 22 LTS | Backend runtime | First-class typing, same language as frontend, largest CalDAV/OIDC library ecosystem |
|
||||
| Hono | 4.12.23 | HTTP framework | Web-Standards-native, first-class TypeScript, built-in SSE helper, WebSocket via `@hono/node-server`; lighter than Express and better ergonomics than Fastify for this size |
|
||||
| Drizzle ORM | 0.45.2 | MariaDB query layer | Type-safe SQL, zero runtime overhead, native `mysql2` driver support, schema-as-code migrations via `drizzle-kit` |
|
||||
| mysql2 | 3.22.4 | MariaDB driver | The only maintained native MariaDB/MySQL driver; Drizzle targets it explicitly |
|
||||
| React 19 | 19.x | PWA frontend | Required by project; concurrent features, stable |
|
||||
| Vite | 8.0.x | Build tooling | De-facto standard for React PWAs; fast HMR, native ESM |
|
||||
| vite-plugin-pwa | 1.3.0 | Service worker + manifest | Zero-config Workbox integration, handles install prompt, offline cache, background sync scaffolding |
|
||||
|
||||
### Supporting Libraries
|
||||
|
||||
| Library | Version | Purpose | When to Use |
|
||||
|---------|---------|---------|-------------|
|
||||
| tsdav | 2.2.2 | CalDAV client for Node.js | All calendar reads and writes against Fastmail CalDAV endpoint; handles PROPFIND, REPORT, PUT, DELETE |
|
||||
| ical.js | 2.2.1 | iCalendar (.ics) parsing | Parse raw VCALENDAR/VEVENT payloads returned by tsdav; handles VTIMEZONE, RDATE, EXDATE |
|
||||
| rrule | 2.8.1 | Recurrence rule expansion | Expand RRULE strings into concrete event occurrences for the calendar view; ical.js's built-in expansion is less ergonomic for UI consumption |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| @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 |
|
||||
| zustand | 5.0.14 | Client state | UI-only state (selected date range, color assignments, drawer open/closed); keep server state in React Query |
|
||||
| drizzle-kit | 0.31.10 | Schema migrations | Generates and runs MariaDB migrations from Drizzle schema definitions |
|
||||
| Library | Version | Purpose | When to Use |
|
||||
| --------------------- | ------- | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| tsdav | 2.2.2 | CalDAV client for Node.js | All calendar reads and writes against Fastmail CalDAV endpoint; handles PROPFIND, REPORT, PUT, DELETE |
|
||||
| ical.js | 2.2.1 | iCalendar (.ics) parsing | Parse raw VCALENDAR/VEVENT payloads returned by tsdav; handles VTIMEZONE, RDATE, EXDATE |
|
||||
| rrule | 2.8.1 | Recurrence rule expansion | Expand RRULE strings into concrete event occurrences for the calendar view; ical.js's built-in expansion is less ergonomic for UI consumption |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| @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 |
|
||||
| zustand | 5.0.14 | Client state | UI-only state (selected date range, color assignments, drawer open/closed); keep server state in React Query |
|
||||
| drizzle-kit | 0.31.10 | Schema migrations | Generates and runs MariaDB migrations from Drizzle schema definitions |
|
||||
|
||||
### Development Tools
|
||||
|
||||
| Tool | Purpose | Notes |
|
||||
|------|---------|-------|
|
||||
| TypeScript 5.x | Strict typing across backend + frontend | `strict: true`; share types between packages via a `packages/shared` workspace |
|
||||
| ESLint + Prettier | Lint + format | Standard config; no bikeshedding needed |
|
||||
| Docker Compose | Local dev + production parity | Match Unraid stack exactly in dev |
|
||||
| Vitest | Unit + integration tests | Vite-native, same config as frontend |
|
||||
| **@playwright/test** | **v1.1 NEW — Mobile PWA test harness** | **devDependency in apps/pwa only; 1.60.0** |
|
||||
| Tool | Purpose | Notes |
|
||||
| -------------------- | --------------------------------------- | ------------------------------------------------------------------------------ |
|
||||
| TypeScript 5.x | Strict typing across backend + frontend | `strict: true`; share types between packages via a `packages/shared` workspace |
|
||||
| ESLint + Prettier | Lint + format | Standard config; no bikeshedding needed |
|
||||
| Docker Compose | Local dev + production parity | Match Unraid stack exactly in dev |
|
||||
| Vitest | Unit + integration tests | Vite-native, same config as frontend |
|
||||
| **@playwright/test** | **v1.1 NEW — Mobile PWA test harness** | **devDependency in apps/pwa only; 1.60.0** |
|
||||
|
||||
---
|
||||
|
||||
@@ -266,6 +267,7 @@ Fastmail's multi-user calendar sharing is documented only for users within the s
|
||||
**Decision: Hono on Node.js**
|
||||
|
||||
Hono is the right size for this app. Express is fine but has no TypeScript-native ergonomics. NestJS is overkill for a two-person household app. Hono gives you:
|
||||
|
||||
- First-class TypeScript with RPC-style type sharing (Hono RPC can export typed client for the React frontend — eliminates API drift)
|
||||
- Built-in SSE streaming helper (`streamSSE`) for live list updates
|
||||
- WebSocket support via `@hono/node-server`
|
||||
@@ -274,6 +276,7 @@ Hono is the right size for this app. Express is fine but has no TypeScript-nativ
|
||||
**ORM: Drizzle + mysql2**
|
||||
|
||||
Drizzle is the correct choice over Prisma for this stack:
|
||||
|
||||
- Prisma generates a binary engine that adds complexity in Docker images and has weaker MariaDB compatibility signals
|
||||
- Drizzle uses `mysql2` directly — the same driver you'd use raw; no runtime translation layer
|
||||
- Drizzle's `mysqlTable` schema is fully MariaDB-compatible (MariaDB is wire-compatible with MySQL; Drizzle's `mysql` dialect works)
|
||||
@@ -301,14 +304,14 @@ Standard for React PWAs. `vite-plugin-pwa` configures the Web App Manifest and i
|
||||
|
||||
**iOS-specific Web Push constraints (CRITICAL):**
|
||||
|
||||
| Requirement | Detail |
|
||||
|-------------|--------|
|
||||
| Minimum iOS version | 16.4 — push is silently unavailable on earlier versions |
|
||||
| Installation required | PWA **must** be added to Home Screen; push does not work from Safari browser tabs |
|
||||
| User gesture | `pushManager.subscribe()` must be called inside a tap handler, not on page load |
|
||||
| Requirement | Detail |
|
||||
| --------------------- | -------------------------------------------------------------------------------------- |
|
||||
| Minimum iOS version | 16.4 — push is silently unavailable on earlier versions |
|
||||
| Installation required | PWA **must** be added to Home Screen; push does not work from Safari browser tabs |
|
||||
| User gesture | `pushManager.subscribe()` must be called inside a tap handler, not on page load |
|
||||
| EU users on iOS 17.4+ | PWAs may open in Safari tabs instead of standalone mode due to DMA; affects push reach |
|
||||
| Silent push | Not supported on iOS; all push messages must display a visible notification |
|
||||
| Background sync | Not supported on iOS; no `BackgroundSync` or `PeriodicBackgroundSync` |
|
||||
| Silent push | Not supported on iOS; all push messages must display a visible notification |
|
||||
| Background sync | Not supported on iOS; no `BackgroundSync` or `PeriodicBackgroundSync` |
|
||||
|
||||
**Declarative Web Push (Safari 18.4+):** Apple shipped Declarative Web Push in Safari 18.4 (iOS 18.4, March 2025). It's backward-compatible: send a JSON payload with `"web_push": 8030` and the browser renders the notification without a service worker handler. The `web-push` npm library (v3.6.7) does not generate this format natively — you'd hand-craft the JSON payload for iOS while the same endpoint handles standard Web Push for Android/desktop. As of mid-2026, Declarative Web Push is a W3C Working Draft and the preferred format for iOS/macOS push. Build the push payload to be Declarative Web Push compatible from day one (it's just a JSON schema change), since `web-push` still handles the VAPID transport layer.
|
||||
|
||||
@@ -323,12 +326,14 @@ Standard for React PWAs. `vite-plugin-pwa` configures the Web App Manifest and i
|
||||
Authelia exposes a standards-compliant OIDC discovery endpoint. `@hono/oidc-auth` uses `oauth4webapi` under the hood, supports authorization code + PKCE, and produces storage-less JWT session cookies — no Redis or session DB required for auth state.
|
||||
|
||||
**Flow:**
|
||||
|
||||
1. Unauthenticated request → middleware redirects to Authelia's authorization endpoint
|
||||
2. Authelia authenticates the user, redirects back with `code`
|
||||
3. Middleware exchanges code for tokens, creates signed JWT session cookie (httpOnly, Secure, SameSite=Lax)
|
||||
4. Cookie is verified on every request; refresh tokens are used to silently re-authenticate before expiry
|
||||
|
||||
**Authelia configuration requirements:**
|
||||
|
||||
- `response_types: [code]`
|
||||
- `grant_types: [authorization_code, refresh_token]`
|
||||
- `require_pkce: true`, `pkce_challenge_method: S256`
|
||||
@@ -347,6 +352,7 @@ Authelia's own integration docs show this exact pattern for Express.js (`express
|
||||
Lists are co-edited by two people. The update direction is server → client (server broadcasts when one client mutates a list). SSE is simpler than WebSockets for this: plain HTTP, works through proxies, automatic reconnection in browsers.
|
||||
|
||||
Pattern:
|
||||
|
||||
1. Client opens `GET /api/lists/stream` → Hono `streamSSE` keeps connection alive
|
||||
2. On a list mutation, the backend publishes a `list:updated:{listId}` event to Redis
|
||||
3. All Node processes subscribed to Redis receive the event and push it to connected SSE clients
|
||||
@@ -358,50 +364,50 @@ Redis (`ioredis`) is only needed if multiple Node containers run behind a load b
|
||||
|
||||
## Alternatives Considered
|
||||
|
||||
| Recommended | Alternative | Why Not |
|
||||
|-------------|-------------|---------|
|
||||
| Hono | Express | No native TypeScript ergonomics; no built-in SSE; larger ecosystem but more boilerplate |
|
||||
| Hono | Fastify | Good choice but heavier plugin model; Hono's Web Standards alignment is better for this size |
|
||||
| Drizzle | Prisma | Binary engine complicates Docker; weaker explicit MariaDB support; heavier |
|
||||
| tsdav | Raw fetch + xml2js | CalDAV XML namespace handling is tedious; tsdav is the established TypeScript CalDAV client |
|
||||
| ical.js | node-ical | node-ical is a fork that has diverged; ical.js is the Mozilla-maintained reference implementation |
|
||||
| @hono/oidc-auth | express-openid-connect | express-openid-connect is Express-specific; Hono middleware is the correct fit |
|
||||
| SSE | WebSockets | WebSockets are bidirectional; list sync is server→client only; SSE is simpler and proxy-friendly |
|
||||
| CalDAV | JMAP | JMAP calendars not available on Fastmail as of 2026 |
|
||||
| @playwright/test | playwright-cli alone | playwright-cli lacks storageState save/restore and device presets needed for CI; both coexist |
|
||||
| PAT for Gitea registry | secrets.GITEA_TOKEN / built-in token | Gitea does not inject a built-in token with container-registry push scope; PAT required |
|
||||
| Recommended | Alternative | Why Not |
|
||||
| ---------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------- |
|
||||
| Hono | Express | No native TypeScript ergonomics; no built-in SSE; larger ecosystem but more boilerplate |
|
||||
| Hono | Fastify | Good choice but heavier plugin model; Hono's Web Standards alignment is better for this size |
|
||||
| Drizzle | Prisma | Binary engine complicates Docker; weaker explicit MariaDB support; heavier |
|
||||
| tsdav | Raw fetch + xml2js | CalDAV XML namespace handling is tedious; tsdav is the established TypeScript CalDAV client |
|
||||
| ical.js | node-ical | node-ical is a fork that has diverged; ical.js is the Mozilla-maintained reference implementation |
|
||||
| @hono/oidc-auth | express-openid-connect | express-openid-connect is Express-specific; Hono middleware is the correct fit |
|
||||
| SSE | WebSockets | WebSockets are bidirectional; list sync is server→client only; SSE is simpler and proxy-friendly |
|
||||
| CalDAV | JMAP | JMAP calendars not available on Fastmail as of 2026 |
|
||||
| @playwright/test | playwright-cli alone | playwright-cli lacks storageState save/restore and device presets needed for CI; both coexist |
|
||||
| PAT for Gitea registry | secrets.GITEA_TOKEN / built-in token | Gitea does not inject a built-in token with container-registry push scope; PAT required |
|
||||
|
||||
---
|
||||
|
||||
## What NOT to Use
|
||||
|
||||
| Avoid | Why | Use Instead |
|
||||
|-------|-----|-------------|
|
||||
| JMAP for calendars | Not implemented by Fastmail; spec not finalized | CalDAV via tsdav |
|
||||
| Prisma | Binary engine, weaker MariaDB compat, larger footprint in Docker | Drizzle ORM |
|
||||
| oidc-client-ts | Browser-side OIDC library; wrong layer for a backend-session app | @hono/oidc-auth |
|
||||
| node-ical | Older fork of ical.js, less maintained, weaker RRULE handling | ical.js |
|
||||
| Create React App | Deprecated February 2025 | Vite |
|
||||
| PostgreSQL | Not in the Unraid stack; hard constraint | MariaDB |
|
||||
| NestJS | Massive framework overhead for a two-user household app | Hono |
|
||||
| Firebase/FCM as push broker | Third-party dependency; VAPID direct push works without it | web-push (VAPID) |
|
||||
| `mysqladmin ping` health check with MariaDB 11 | mysqladmin not shipped in mariadb:11 image; silently blocks CI | `healthcheck.sh --connect --innodb_initialized` |
|
||||
| `runs-on: ubuntu-latest` on Gitea self-hosted runner | Label only resolves on GitHub's hosted infrastructure | `runs-on: self-hosted` (or the runner's registered label) |
|
||||
| Any validation library for setup wizard | zod + mysql2 + web-push + Node 22 fetch cover all checks natively | Use existing stack |
|
||||
| Avoid | Why | Use Instead |
|
||||
| ---------------------------------------------------- | ----------------------------------------------------------------- | --------------------------------------------------------- |
|
||||
| JMAP for calendars | Not implemented by Fastmail; spec not finalized | CalDAV via tsdav |
|
||||
| Prisma | Binary engine, weaker MariaDB compat, larger footprint in Docker | Drizzle ORM |
|
||||
| oidc-client-ts | Browser-side OIDC library; wrong layer for a backend-session app | @hono/oidc-auth |
|
||||
| node-ical | Older fork of ical.js, less maintained, weaker RRULE handling | ical.js |
|
||||
| Create React App | Deprecated February 2025 | Vite |
|
||||
| PostgreSQL | Not in the Unraid stack; hard constraint | MariaDB |
|
||||
| NestJS | Massive framework overhead for a two-user household app | Hono |
|
||||
| Firebase/FCM as push broker | Third-party dependency; VAPID direct push works without it | web-push (VAPID) |
|
||||
| `mysqladmin ping` health check with MariaDB 11 | mysqladmin not shipped in mariadb:11 image; silently blocks CI | `healthcheck.sh --connect --innodb_initialized` |
|
||||
| `runs-on: ubuntu-latest` on Gitea self-hosted runner | Label only resolves on GitHub's hosted infrastructure | `runs-on: self-hosted` (or the runner's registered label) |
|
||||
| Any validation library for setup wizard | zod + mysql2 + web-push + Node 22 fetch cover all checks natively | Use existing stack |
|
||||
|
||||
---
|
||||
|
||||
## Version Compatibility
|
||||
|
||||
| Package | Compatible With | Notes |
|
||||
|---------|-----------------|-------|
|
||||
| drizzle-orm@0.45.x | mysql2@3.x | Use `drizzle-orm/mysql2` import path; mysql2@3.x uses Promises API by default |
|
||||
| vite-plugin-pwa@1.3.x | Vite@8.x, Workbox@7.x | vite-plugin-pwa 0.16+ requires Node 16+; 1.x tracks Vite 6+ |
|
||||
| @hono/oidc-auth@1.8.x | hono@4.x, oauth4webapi | Peer-depends on hono 4.x |
|
||||
| ical.js@2.x | rrule@2.8.x | Use together: ical.js parses the RRULE string, pass to `new RRule(RRule.parseString(...))` |
|
||||
| web-push@3.6.x | Node.js 18+ | VAPID uses Web Crypto; works in Node.js 18+ natively |
|
||||
| @playwright/test@1.60.x | Node.js 18+ | Install Chromium only in CI (`npx playwright install --with-deps chromium`) |
|
||||
| mariadb:11 service container | GitHub/Gitea Actions | Health check must use `healthcheck.sh`; `mysqladmin` removed in 11.x |
|
||||
| Package | Compatible With | Notes |
|
||||
| ---------------------------- | ---------------------- | ------------------------------------------------------------------------------------------ |
|
||||
| drizzle-orm@0.45.x | mysql2@3.x | Use `drizzle-orm/mysql2` import path; mysql2@3.x uses Promises API by default |
|
||||
| vite-plugin-pwa@1.3.x | Vite@8.x, Workbox@7.x | vite-plugin-pwa 0.16+ requires Node 16+; 1.x tracks Vite 6+ |
|
||||
| @hono/oidc-auth@1.8.x | hono@4.x, oauth4webapi | Peer-depends on hono 4.x |
|
||||
| ical.js@2.x | rrule@2.8.x | Use together: ical.js parses the RRULE string, pass to `new RRule(RRule.parseString(...))` |
|
||||
| web-push@3.6.x | Node.js 18+ | VAPID uses Web Crypto; works in Node.js 18+ natively |
|
||||
| @playwright/test@1.60.x | Node.js 18+ | Install Chromium only in CI (`npx playwright install --with-deps chromium`) |
|
||||
| mariadb:11 service container | GitHub/Gitea Actions | Health check must use `healthcheck.sh`; `mysqladmin` removed in 11.x |
|
||||
|
||||
---
|
||||
|
||||
@@ -449,5 +455,5 @@ Redis (`ioredis`) is only needed if multiple Node containers run behind a load b
|
||||
|
||||
---
|
||||
|
||||
*Stack research for: FamilySync — self-hosted family calendar + shared-lists PWA on Fastmail*
|
||||
*Researched: 2026-06-03 (v1.0 baseline) / 2026-06-10 (v1.1 Operability & Polish additions)*
|
||||
_Stack research for: FamilySync — self-hosted family calendar + shared-lists PWA on Fastmail_
|
||||
_Researched: 2026-06-03 (v1.0 baseline) / 2026-06-10 (v1.1 Operability & Polish additions)_
|
||||
|
||||
Reference in New Issue
Block a user