Skip to content

Add Email module with templates, SMTP/Log providers, and UI#63

Merged
antosubash merged 24 commits intomainfrom
claude/create-email-module-jpFoj
Apr 3, 2026
Merged

Add Email module with templates, SMTP/Log providers, and UI#63
antosubash merged 24 commits intomainfrom
claude/create-email-module-jpFoj

Conversation

@antosubash
Copy link
Copy Markdown
Owner

Summary

Introduces a complete Email module for SimpleModule with email sending capabilities, template management, and a web UI for managing email templates and viewing send history.

Key Changes

Core Email Service

  • EmailService: Main service implementing IEmailContracts with methods for:
    • Sending emails with status tracking (Queued → Sending → Sent/Failed)
    • Sending templated emails with variable rendering
    • CRUD operations for email templates
    • Retrieving email message history
  • Email Providers:
    • IEmailProvider interface with two implementations:
      • SmtpEmailProvider: Uses MailKit for SMTP delivery
      • LogEmailProvider: Logs emails instead of sending (for development)
  • EmailTemplateRenderer: Simple template variable replacement using {{variable}} syntax

Data Models & Configuration

  • Entities: EmailMessage and EmailTemplate with proper EF Core configurations
  • Value Objects: EmailMessageId and EmailTemplateId using Vogen
  • DbContext: EmailDbContext with schema management
  • Options: EmailModuleOptions for configurable provider, SMTP settings, and defaults

API Endpoints

  • Message endpoints: Send, Get All, Get By ID
  • Template endpoints: Create, Read, Update, Delete, Get All
  • All endpoints require appropriate permissions (ViewTemplates, ManageTemplates)

Web UI (React/TypeScript)

  • Templates page: List all templates with edit/delete actions
  • Create template page: Form to create new templates with slug, subject, body, and HTML flag
  • Edit template page: Update existing templates with delete confirmation dialog
  • History page: View sent emails with status badges and error messages
  • Endpoints: Server-side rendering endpoints for each view

Integration

  • Identity Integration: IdentityEmailSender implements IEmailSender<ApplicationUser> for ASP.NET Core Identity email confirmations and password resets
  • Event Publishing: Publishes EmailSentEvent and EmailFailedEvent for domain events
  • Module Registration: Full module setup with permissions, settings, and menu items
  • Error Handling: Graceful failure handling with retry count and error message storage

Testing

  • Comprehensive unit tests covering:
    • Email sending and status transitions
    • Template CRUD operations
    • Template rendering with variables
    • Event publishing
    • Error scenarios and not-found exceptions

Notable Implementation Details

  • Email messages track full lifecycle with timestamps and error messages
  • Template variables use simple regex-based replacement pattern
  • SMTP provider supports optional authentication
  • Database schema properly isolated to "Email" module schema
  • Permissions-based access control on all endpoints
  • TypeScript types auto-generated from DTOs

https://claude.ai/code/session_01913Uy1JyE2sgbVjqpr9FV2

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Apr 3, 2026

Deploying simplemodule-website with  Cloudflare Pages  Cloudflare Pages

Latest commit: 07c5c45
Status: ✅  Deploy successful!
Preview URL: https://449cf04b.simplemodule-website.pages.dev
Branch Preview URL: https://claude-create-email-module-j.simplemodule-website.pages.dev

View logs

@antosubash antosubash marked this pull request as draft April 3, 2026 10:30
Production email sending capability with pluggable providers (SMTP via MailKit,
Log for development). Includes template engine with {{variable}} placeholders,
email history tracking with delivery status, and Identity integration to replace
ConsoleEmailSender. Admin UI provides template management and send history views.
Covers pagination/filtering, request validation, ReplyTo support,
background sending with retry via BackgroundJobs, audit logging,
template variable validation with HTML escaping, and stats dashboard.
15 tasks across 7 chunks: contracts/entities, validators/template safety,
pagination/stats/audit events, background jobs, endpoints, React views,
and final verification.
Replaces unbounded GetAllMessagesAsync/GetAllTemplatesAsync with paginated
QueryMessagesAsync/QueryTemplatesAsync, adds EmailStats/ErrorSummary/DailyCount
DTOs, and adds GetEmailStatsAsync to IEmailContracts.
…velope

Introduce EmailEnvelope record to encapsulate all send parameters,
update IEmailProvider, SmtpEmailProvider, LogEmailProvider, and
EmailService to use the new type. Add ReplyTo to message creation
and stub QueryMessagesAsync/QueryTemplatesAsync/GetEmailStatsAsync
on EmailService to satisfy the updated IEmailContracts interface.
Update endpoints and view endpoints to use the new query methods.
Add ExtractVariables to EmailTemplateRenderer, update Render to accept isHtml for XSS-safe encoding, and validate missing template variables in SendTemplatedEmailAsync before rendering.
Replace NotImplementedException stubs in QueryMessagesAsync, QueryTemplatesAsync,
and GetEmailStatsAsync with real EF Core implementations. DailyVolume grouping
uses client-side evaluation for SQLite compatibility. Adds 5 new unit tests.
…endpoints

- Update HistoryEndpoint and TemplatesEndpoint to accept [AsParameters] query bindings and pass result + filters to React views
- Add GetStatsEndpoint (GET /stats) returning EmailStats JSON
- Add DashboardEndpoint (GET /dashboard) rendering Email/Dashboard view with stats
- Add Email Dashboard menu item (order 49) before Email Templates in sidebar
…ering

- Set DefaultReplyTo in CreateTemplateAsync and UpdateTemplateAsync
- Render email subject with isHtml: false (subjects are always plain text)
- SendEmailJob: catch MailKit-specific exceptions (SmtpCommandException,
  AuthenticationException, SslHandshakeException) alongside IO exceptions
- QueryMessagesAsync: sort by CreatedAt (not Id) for default sort column
- RetryFailedEmailsJob: batch SaveChangesAsync outside foreach loop
- EmailJobRegistrationHostedService: add error handling for invalid cron
- GetEmailStatsAsync: consolidate 6 DB queries down to 3 by deriving
  24h/7d counts from the recentMessages in-memory list
- Templates.tsx: fix cross-namespace i18n key references (History.Of → Templates.Of)
- Add missing Templates.Of and Templates.FilterApply locale keys
- BackgroundJobs Detail.tsx: use log.timestamp as key instead of array index
- Marketplace Browse.tsx/Detail.tsx: add aria-hidden to decorative SVGs
- theme.css: suppress intentional descending specificity and !important warnings
- Email en.json/keys.ts: fix Dashboard.TopErrors key collision (leaf + branch)
@antosubash antosubash force-pushed the claude/create-email-module-jpFoj branch from 885c6fe to f4352f8 Compare April 3, 2026 13:35
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Apr 3, 2026

Deploying simplemodule-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: f4352f8
Status: ✅  Deploy successful!
Preview URL: https://59d41659.simplemodule.pages.dev
Branch Preview URL: https://claude-create-email-module-j.simplemodule.pages.dev

View logs

The gradient-text CSS class uses -webkit-text-fill-color: transparent,
which causes Playwright toBeVisible to report the heading as hidden
despite being in the DOM. Use toBeAttached instead.
@antosubash antosubash marked this pull request as ready for review April 3, 2026 13:58
@antosubash antosubash merged commit 8280704 into main Apr 3, 2026
4 checks passed
@antosubash antosubash deleted the claude/create-email-module-jpFoj branch April 3, 2026 13:58
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