Records the design decisions for the next planned work:
- Per-reminder delivery window (default 6am–6pm, operator timezone).
Window-close hard-stops the run; remaining targets become
skipped; status reports as partial with a clear "this account is
at capacity, consider another paired account" message.
- Per-account isolation via pg-boss teamSize ≥ N + an in-process
PerKeyMutex keyed by accountId. Different accounts run in
parallel; the same account serialises (no double-rate sends
that would risk a ban).
- Per-account token-bucket rate limiter (default 40 msg/min,
BOT_MAX_SEND_PER_MINUTE).
- Up-front media-upload cache via prepareWAMessageMedia: 1000
groups × 5 MB upload turns into 5 MB. Biggest single win for
text+picture reminders.
- Bounded group concurrency (default 3 in-flight per account);
parts-within-a-group stay serial for visible message order.
- Pre-fetched DB Maps (groups / messages / media), no inner-loop
round-trips.
- Replaces the rigid 1.5 s inter-part sleep with 200–500 ms
jitter; the per-account rate-limiter is the real gate.
Out of scope for v1 (documented under "v2 candidates"): cross-day
window resume, mid-restart resumability, multi-account auto-split,
adaptive rate-limit back-off, pause/resume mid-run.
Acceptance: 1000-group reminder + one image, established account
finishes in ~30–50 minutes, well inside a 6am–6pm window. Two
reminders on different accounts at the same wall-clock minute
both progress in parallel.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
13 sections covering every flow that unit tests can't:
1. Smoke (mobile header, sidebar, page titles, tab strips)
2. Account pairing (live QR, sync groups, send-test)
3. Re-pair / unpair (status flips, no spurious reconnect)
4. Reminders — single-message one-off (5-step wizard)
5. Reminders — multi-message stack with media swap
6. Reminders — recurrence picker (Daily / Weekly / Monthly /
Yearly + multi-rule, descriptions are sentences not raw cron)
7. Reminders — edit each section preserves the message stack
(regression guard for the parts-2..N drop bug)
8. Reminders list — swipe + lifecycle (no reshuffle on Pause /
Restart, shelf collapses after action)
9. Activity — swipe archive / delete + Archived tab + restore
10. Send-test feedback round trip (Sending… → Sent ✓)
11. Media upload limits (size caps, HEIC/MOV → document fallback)
12. PWA install (standalone display, offline shell)
13. Theme toggle (desktop only)
Captures the policy decisions that aren't immediately obvious from
the code:
- browser-extension hydration warnings are expected, app code is
not at fault — Incognito clears them
- HEIC/MOV uploads are NOT rejected; they fall back to document
delivery
- cron rules render as descriptive sentences in the UI
- status changes don't reorder the reminders list
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
After live-testing the Telegram bot we hit limits that don't go away with
more menu polish (Markdown fragility, callback_data limits, no native
date pickers, awkward media UX). Pivot to a Next.js PWA installable on
the operator's phone; remove Telegram entirely.
Spec covers: service topology with bot codebase shrunk, no-auth access
stance with rate limiting + reverse-proxy gating, Server Actions
replacing public REST mutation endpoints, SSE for live updates, the new
web-side pair flow with live QR display, multi-step reminder wizard
backed by URL state, mobile-first shadcn/ui visual layer, PWA service
worker via @serwist/next, and a step-by-step plan to delete the existing
Telegram code first.
Inherits all confirmed values from the 2026-05-03 master spec.
Captures the validated design from the brainstorming session: two-service
topology (Next.js web + Node bot) communicating via Postgres LISTEN/NOTIFY,
Baileys for WhatsApp, grammy for Telegram, pg-boss for scheduling, Drizzle
for the data model, and Docker/Gitea-registry deploy flow.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>