Skip to content

feat(newsletters): newsletter schema + models + renderer (Wave 3, WordPress - partial)#57

Open
mpge wants to merge 1 commit into
mainfrom
feat/newsletter-system
Open

feat(newsletters): newsletter schema + models + renderer (Wave 3, WordPress - partial)#57
mpge wants to merge 1 commit into
mainfrom
feat/newsletter-system

Conversation

@mpge
Copy link
Copy Markdown
Member

@mpge mpge commented May 22, 2026

Summary

Wave 3 partial port of the newsletter engine to WordPress. Per the spec, WordPress is special-cased (WP options + WP-Cron + WP capabilities instead of the cross-framework settings table / cron tick / permission system).

  • 5 new tables created by extending Escalated\Activator::create_newsletter_tables() (wired into activate() + the upgrade path)
  • marketing_opt_out_at column added to escalated_contacts (via ALTER TABLE if missing)
  • 5 model wrappers under includes/Models/Newsletter/ (static $wpdb helpers, same pattern as existing Models)
  • Full renderer at includes/Services/Newsletter/NewsletterRenderer.php — Markdown → theme → click rewrite → pixel injection
  • Two starter PHP themes under templates/newsletter_themes/ (default + branded)
  • README documenting host integrator wiring (Markdown filter, themes dir filter, etc.)

Architecture notes

  • Markdown is host-pluggable via the escalated_newsletter_markdown_renderer WordPress filter (Parsedown, league/commonmark, etc.).
  • Themes are PHP files (not Twig/Blade) — the renderer captures their output via ob_start() / ob_get_clean(). Hosts can override the themes dir via the escalated_newsletter_themes_dir filter.
  • URL generation uses home_url() so it works on subdir/subdomain WP installs.
  • Schema migration uses dbDelta (the WP convention) and gates the ALTER TABLE on a column-existence check to make the upgrade idempotent.

Out of scope / follow-ups

  • WP-Cron registration for the dispatcher tick (a single wp_schedule_event('escalated_every_minute', 'escalated_newsletters_dispatch') call)
  • Planner / Dispatcher / Tracker services
  • REST API endpoints (/escalated/n/o/{token}.gif, /c/{token}, /u/{token}, /v/{token})
  • Admin pages (custom WP admin screens or via the Inertia frontend already embedded in this plugin)
  • ESP webhook handlers

Reviewer notes

  • Do not auto-merge. Hand back to Matthew for review.
  • The create_newsletter_tables method is intentionally public static (not private) so it can be re-run from a migration command in the future without touching the activator's main activate() flow.

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