Skip to content

DAO email alert subscriptions and poll funding requests - #39

Open
EightRice wants to merge 1 commit into
feat/testsfrom
feat/dao-alerts
Open

EightRice wants to merge 1 commit into
feat/testsfrom
feat/dao-alerts

Conversation

@EightRice

Copy link
Copy Markdown
Contributor

What

Two additions to the lite backend, both aimed at shortening the Ecosystem DAO grant cycle (poll on Homebase, then an on-chain transfer proposal, then keyholder votes).

DAO email alerts

  • POST /subscriptions with { email, daoAddress, network, daoName? } creates a per-DAO subscription and sends a confirmation email (double opt-in). Always answers 200 { ok: true } for well-formed input so the endpoint cannot be used to check whether an address is subscribed. In-memory throttle of 5 requests per email per hour.
  • GET /subscriptions/confirm/:token and GET /subscriptions/unsubscribe/:token redirect back to the app with ?alerts=confirmed|unsubscribed|invalid.
  • New Subscription model (collection Subscriptions), unique on email + DAO + network.
  • services/mailer.service.js wraps nodemailer and is a no-op until SMTP_HOST is set, so nothing changes for environments without mail configured.
  • The confirmation subject carries a timestamp so Gmail does not thread repeated confirmations together, and the confirm token stays stable across repeat requests (a rotated token turned the visible link into a dead one during testing).

The emails themselves (proposal created, voting closes soon, passed, executable, executed, dropped, expired) are sent by a separate watcher that reads the indexer and this collection.

Poll funding requests

  • /poll/add accepts an optional fundingRequest: { recipient, amount }, validated as a Tezos address and a positive XTZ amount with up to 6 decimals.
  • POST /polls/:id/link-proposal (signed like every other write) records the on-chain proposal a poll was promoted to. Allowed for the poll author or the community admin.

Config

New optional env vars, documented in config.env.example: SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, MAIL_FROM, APP_URL, PUBLIC_API_URL. They need to be set on the Netlify site before this is useful in production.

Tests

npx jest routes/subscriptions.test.js routes/polls.test.js: 35 passing. Verified end to end against the real SMTP sender: subscribe, confirmation email, confirm link, unsubscribe link, and a "proposal created" email after an on-chain proposal.

Notes

https://claude.ai/code/session_01UG9AFKKU31ba2d9QNLV44R

Email alerts:
- POST /subscriptions creates a per-DAO subscription (email, KT1 address, network) and sends a confirmation email; always answers 200 so it cannot be used to probe addresses
- GET /subscriptions/confirm/:token and /unsubscribe/:token redirect back to the app with ?alerts=confirmed|unsubscribed|invalid
- Subscription model with unique email+DAO+network index, nodemailer mailer service that is a no-op until SMTP_HOST is set
- Confirmation subject carries a timestamp so mail clients do not thread repeated confirmations; the confirm token is kept stable across repeat requests

Polls:
- /poll/add accepts an optional fundingRequest {recipient, amount}, validated as a Tezos address and a positive XTZ amount
- POST /polls/:id/link-proposal (signed) records the on-chain proposal a poll was promoted to; allowed for the poll author or the community admin

Tests for both routes; config.env.example documents the new SMTP and URL variables.

Claude-Session: https://claude.ai/code/session_01UG9AFKKU31ba2d9QNLV44R
@netlify

netlify Bot commented Sep 14, 2026

Copy link
Copy Markdown

Deploy Preview for homebase-backend failed. Why did it fail? →

Name Link
🔨 Latest commit 1187322
🔍 Latest deploy log https://app.netlify.com/projects/homebase-backend/deploys/6aa7d18f3bcde50008c2a856

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant