Multi-fix batch from a rapid feedback round:
- Password policy mirrors Facebook's documented rule (≥6 chars + mix of
letters with numbers/symbols). Centralised in
apps/web/src/lib/password-policy.ts; createUserAction,
resetUserPasswordAction, the AddUser form, and the row Reset-password
flow all use it. CLI scripts/set-password.ts inlines the same check
so the bootstrap path stays consistent.
- App shell adds a Sign-out button in both the desktop sidebar footer
and the mobile drawer footer, with the signed-in username next to it.
Layout passes username down alongside role. Theme toggle was removed
from the shell per request — operators don't need it in the chrome.
- Dashboard stats: getDashboardStats was running findMany on reminders
with NO operator filter, so a brand-new user saw global counts from
every tenant. Switched to an INNER JOIN on whatsapp_accounts so the
card on / only counts this user's reminders. (Counts had been showing
'1 / 1 / 3 / 5' to a fresh user — the cross-tenant leak the user
flagged.)
- /activity drops the All tab and the Clear-history button. Default
filter is now Success when no ?filter= is set; Partial keeps fanning
into Paused + Failed; Skipped still merges into Archived.
- /settings drops the Display name row entirely and only shows the Role
row to admins. Layout receives username so the shell can also surface
it next to the Sign-out button.
- Tests: password-policy.test.ts (11 cases), updated users.test.ts to
use policy-compliant passwords + cover letters-only / digits-only
rejection, sidebar-footer assertion swapped from theme-toggle to the
new Sign-out + username markup. 453 tests green; typecheck clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
robots.ts + metadata.robots blocks indexing.
serverActions.allowedOrigins gates cross-origin Server Action posts.
Bot + web Dockerfiles add a non-root 'app' user (uid 1000) with
chmod 700 on /data/sessions.
sendTestAction grows a per-group rate limit (3/60s).
resumeReminderRunAction + cancelReminderRunAction get a per-IP
rate limit (30/10s).
.env.example documents every required key.
packages/db/src/scripts/{set-password,create-user}.ts + thin shell
wrappers in scripts/ — first admin sets their password via
./scripts/set-password.sh admin before signing in.