Two related follow-ups for the 3 000+ groups-per-account scale path:
1. New B-tree index on whatsapp_groups (account_id, name) (migration
0014). Covers the groups list page's
`WHERE account_id=? ORDER BY name ASC LIMIT 200` query so PG
streams pre-sorted from the index instead of pulling all rows
then sorting. The unique (account_id, wa_group_jid) was the only
prior B-tree on this table; it backed the WHERE prefix but not
the ORDER BY.
2. listGroupsForAccount now filters `is_archived = false` in both
the search and the no-search branch. Soft-archived groups
(set when group-sync sees them disappear from the live
participant list, or when an operator unpairs the account) used
to leak into the wizard picker, letting operators pick a group
the bot can no longer reach. Archived rows still exist in DB so
reminders that target them keep working; a re-pair flips them
back via the on-conflict upsert.
README "Deferred" entry for the composite index removed (it's
shipped). Search-as-you-type in the wizard picker stays deferred.
482 web + 88 bot tests still green; typecheck clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The status section reflected the post-Plan-1 world where pairing
went through Telegram. Reality has long since moved on:
- Plans 1, 2, and 3 are all complete.
- The Telegram bot is gone (removed in P3/T4).
- The web app at wabot.04080616.xyz is the primary surface.
- The recurrence picker, multi-message stack, swipe rows, archive
flow, HEIC fallback, and PWA install all shipped.
Other updates:
- Quick-start no longer mentions Telegram tokens — replaced with
the URL the operator opens to use the app.
- Architecture paragraph swapped grammy mention for the LISTEN/
NOTIFY consumer + SSE shape.
- Pointed at the new design spec
(2026-05-09-web-app-design.md) and manual test runbook.
- Layout / scripts tables trimmed: dropped the publish.sh and
link-account.sh stubs that were never implemented.
- "Deferred" section lists honest gaps (media library, E2E tests,
auth, multi-operator).
Test counts called out (249 web + 31 shared + 26 bot = 306) so the
status claim is verifiable in a single grep.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>