screentinker/server
ScreenTinker c55ca60b56 feat(api): batched email digest for agency uploads (#73)
Reuses the existing scheduler + sendEmail infra (no new scheduler). The agency endpoint
enqueues one agency_notifications row per item added; a 15-min flush groups unsent rows per
token+playlist+action and sends ONE digest per group to the workspace owner/admins + the
playlist owner (deduped via UNION). Draft -> "added N items, awaiting approval"; published ->
"updated <playlist>".

Two robustness rules, both tested:
- Queue never balloons when SMTP is off: the endpoint skips enqueue when !isConfigured(),
  and the flush drains-and-discards unsent rows as a backstop.
- sent_at is stamped ONLY after a successful send, so a failed send retries next cycle
  instead of silently dropping.

Wired into boot via startAgencyDigest(). 147 suite green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 13:59:37 -05:00
..
config feat(api): agency-token security primitive - off-ladder scope + agencyGate (#73) 2026-06-13 21:30:38 -05:00
db feat(api): batched email digest for agency uploads (#73) 2026-06-14 13:59:37 -05:00
lib feat(api): GET /api/agency/layouts - device-free layout geometry (#73) 2026-06-14 13:53:30 -05:00
middleware feat(api): per-agency-token auto-publish (#73) 2026-06-14 13:48:17 -05:00
player feat(scheduling): per-item schedule blocks (#74 dayparting, #75 auto-expire) 2026-06-11 15:46:41 -05:00
routes feat(api): batched email digest for agency uploads (#73) 2026-06-14 13:59:37 -05:00
scripts feat(scheduling): per-item schedule blocks (#74 dayparting, #75 auto-expire) 2026-06-11 15:46:41 -05:00
services feat(api): batched email digest for agency uploads (#73) 2026-06-14 13:59:37 -05:00
test feat(api): batched email digest for agency uploads (#73) 2026-06-14 13:59:37 -05:00
ws feat(scheduling): per-item schedule blocks (#74 dayparting, #75 auto-expire) 2026-06-11 15:46:41 -05:00
.gitignore feat(email): Microsoft Graph send + alert spam protection + preferences UI 2026-05-12 18:16:40 -05:00
config.js chore(version): single-source VERSION, env-configurable data paths, bump tooling 2026-06-10 12:56:03 -05:00
package-lock.json chore(server): TOTP schema + otplib dep (#100) 2026-06-13 20:48:55 -05:00
package.json chore(server): TOTP schema + otplib dep (#100) 2026-06-13 20:48:55 -05:00
server.js feat(api): batched email digest for agency uploads (#73) 2026-06-14 13:59:37 -05:00
version.js chore(version): single-source VERSION, env-configurable data paths, bump tooling 2026-06-10 12:56:03 -05:00