What
Send email notifications to interested parties when relevant activity happens on a post — specifically: new comments on a post you authored or commented on, and status changes on a post you authored.
Why it matters
Without notifications, users have to poll the board to know if their feedback got a response or moved status. That's a poor feedback loop — the people who care most about a post have no way to learn it was updated. Email is the universal lowest-friction channel for this.
Scope
Events → recipients
| Event |
Recipients |
| New comment on post P |
Author of P + everyone who commented on P (excluding the commenter) |
| Status change on post P |
Author of P + everyone who commented on P |
| (Optional) Post created |
Project admins only |
Backend
- SMTP config:
SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASSWORD, SMTP_FROM. Document in docs/configuration.md. Provide a log sink mode (SMTP_DRIVER=log) for dev/CI that writes the rendered email to tracing instead of sending.
- Template rendering: plaintext + basic HTML. Keep templates in-code (Handlebars or
lettre's built-in). Localize subject/body around the post title and a deep link.
- Subscription model: use existing comment/author rows as the source of truth (no new
subscriptions table for v0.2). A user is "subscribed" by authoring or commenting.
- Unsubscribe: include a signed per-recipient unsubscribe token in every email (HMAC with
APP_SECRET, like the OAuth redirect cookie). GET /api/notifications/unsubscribe?token=… sets a per-user notifications_opt_out flag (new column).
- Queue: start with an in-process
tokio::spawn fire-and-forget job per event. Don't block the request. Note in docs that this is not durable and a real queue is deferred to v0.3 (Redis-backed or DB-backed).
Frontend
- "Email notifications" toggle in user profile / settings (writes
notifications_opt_out).
- No new admin UI for v0.2.
Tests
- Unit tests on template rendering with various inputs.
- Unit tests on unsubscribe token sign/verify.
- Integration test using the log sink: post a comment, assert the right recipients are notified.
- Integration test: unsubscribe token flips the opt-out flag.
Docs
docs/configuration.md — SMTP env vars + log-sink mode.
docs/features/notifications.md — new page explaining what triggers an email, how to opt out, how admins configure SMTP.
- Privacy/security note: never expose recipient list to other recipients (BCC or individual sends).
Non-goals
- Digest emails (daily/weekly) — follow-up.
- Webhook/Slack notifications — separate feature, v0.3 (#webhooks).
- In-app notifications / notification feed UI — follow-up.
- Custom per-post subscription toggle (auto-subscribe from author/comment is the v0.2 model).
- Durable queue (v0.3 with Redis).
Migration
- Add
users.notifications_opt_out BOOLEAN NOT NULL DEFAULT 0 to both SQLite and Postgres migrations.
Context
- Roadmap item:
v0.2.0 Polish → "Email notifications (new comments, status changes)".
- Largest item in v0.2.0 — consider splitting into "send plain-text on comment" → "HTML template" → "status-change events" → "unsubscribe flow" as separate PRs.
- Cross-link: webhooks (#v0.3) will reuse the event-detection layer.
What
Send email notifications to interested parties when relevant activity happens on a post — specifically: new comments on a post you authored or commented on, and status changes on a post you authored.
Why it matters
Without notifications, users have to poll the board to know if their feedback got a response or moved status. That's a poor feedback loop — the people who care most about a post have no way to learn it was updated. Email is the universal lowest-friction channel for this.
Scope
Events → recipients
Backend
SMTP_HOST,SMTP_PORT,SMTP_USER,SMTP_PASSWORD,SMTP_FROM. Document indocs/configuration.md. Provide a log sink mode (SMTP_DRIVER=log) for dev/CI that writes the rendered email to tracing instead of sending.lettre's built-in). Localize subject/body around the post title and a deep link.subscriptionstable for v0.2). A user is "subscribed" by authoring or commenting.APP_SECRET, like the OAuth redirect cookie).GET /api/notifications/unsubscribe?token=…sets a per-usernotifications_opt_outflag (new column).tokio::spawnfire-and-forget job per event. Don't block the request. Note in docs that this is not durable and a real queue is deferred to v0.3 (Redis-backed or DB-backed).Frontend
notifications_opt_out).Tests
Docs
docs/configuration.md— SMTP env vars + log-sink mode.docs/features/notifications.md— new page explaining what triggers an email, how to opt out, how admins configure SMTP.Non-goals
Migration
users.notifications_opt_out BOOLEAN NOT NULL DEFAULT 0to both SQLite and Postgres migrations.Context
v0.2.0 Polish→ "Email notifications (new comments, status changes)".