Skip to content

feat(newsletters): full HTTP layer + engine services (Go)#69

Open
mpge wants to merge 4 commits into
mainfrom
feat/newsletter-http-layer
Open

feat(newsletters): full HTTP layer + engine services (Go)#69
mpge wants to merge 4 commits into
mainfrom
feat/newsletter-http-layer

Conversation

@mpge

@mpge mpge commented Jun 2, 2026

Copy link
Copy Markdown
Member

What

Brings escalated-go from schema+renderer-only to full newsletter parity. Go had the 5 tables (in migrationStatements()) + models + only the Renderer service. This ports the remaining engine + the entire HTTP layer.

Part of the full-parity program (mirrors the Laravel + NestJS references against escalated/docs/superpowers/specs/2026-06-02-newsletter-http-parity-contract.md).

Added

  • 5 engine services (services/newsletter/services.go + sqlstore.go): BounceSuppressionStore, ContactSegmentResolver (allowlisted fields/ops + parameterized query builder — no injection), NewsletterPlanner, NewsletterDispatcher (DispatchBatch with the 4 fleet behaviors: rate-limit/minute, retry backoff via next_attempt_at, auto-pause over first-N, stuck-row reclaim), NewsletterTracker.
  • HTTP layer (handlers/newsletter.go, router/newsletter.go): admin (campaigns/lists/templates/settings), public (open-pixel, click, unsubscribe show/store, view-in-browser), ESP webhook (postmark/mailgun/ses/sendgrid), wired into BOTH routers (chi.go + stdlib.go).
  • Dispatch worker: gated background worker invoking DispatchBatch.
  • Enabled gate: EnableNewsletters added to config; routes + worker gated.
  • Permissions: newsletters.manage (admin) / newsletters.send (send actions) enforced.

Residual bug fixed

Verification

  • go build ./...: pass. go test ./...: all packages pass (services + handlers + migrations).

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