feat: add registration confirmation email template #9

Merged
forgejo_admin merged 1 commit from 8-registration-confirmation-template into main 2026-04-07 19:29:34 +00:00
Contributor

Summary

New MJML template for player registration confirmation emails. Uses shared partials (head, header, footer) for brand consistency. Includes player details card, credentials block injection point, and profile management CTA.

Changes

  • src/registration-confirmation.mjml -- new template with greeting, player details card (division, position, height, grad_class), credentials_block slot, red CTA button, sign-in link, and Coach Marcus contact info
  • sample-data/registration-confirmation.json -- sample data for preview/testing

Test Plan

  • npm test passes (10/10) -- compilation, build output, placeholder markers, DRY verification
  • All 10 placeholders verified in compiled output: parent_name, player_name, tenant_name, division, position, height, grad_class, profile_url, frontend_url, credentials_block
  • dist/ is gitignored per repo convention; compiled HTML is a build artifact

Review Checklist

  • MJML compiles without errors (strict validation)
  • All 10 placeholders present in compiled HTML
  • Uses shared partials (head, header, footer) -- no inline duplication
  • Brand colors match existing templates (#0a0a0a header, #c41230 accent, #141414 body)
  • Sample data file included for preview

None.

Closes #8

## Summary New MJML template for player registration confirmation emails. Uses shared partials (head, header, footer) for brand consistency. Includes player details card, credentials block injection point, and profile management CTA. ## Changes - `src/registration-confirmation.mjml` -- new template with greeting, player details card (division, position, height, grad_class), credentials_block slot, red CTA button, sign-in link, and Coach Marcus contact info - `sample-data/registration-confirmation.json` -- sample data for preview/testing ## Test Plan - `npm test` passes (10/10) -- compilation, build output, placeholder markers, DRY verification - All 10 placeholders verified in compiled output: parent_name, player_name, tenant_name, division, position, height, grad_class, profile_url, frontend_url, credentials_block - dist/ is gitignored per repo convention; compiled HTML is a build artifact ## Review Checklist - [x] MJML compiles without errors (strict validation) - [x] All 10 placeholders present in compiled HTML - [x] Uses shared partials (head, header, footer) -- no inline duplication - [x] Brand colors match existing templates (#0a0a0a header, #c41230 accent, #141414 body) - [x] Sample data file included for preview ## Related Notes None. ## Related Closes #8
New MJML template for player registration confirmations with player
details card, credentials block, and profile CTA button. Uses shared
partials (head, header, footer) for brand consistency.

Placeholders: parent_name, player_name, tenant_name, division, position,
height, grad_class, profile_url, frontend_url, credentials_block

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Author
Contributor

PR #9 Review

DOMAIN REVIEW

Tech stack: MJML email templates with Mustache-style placeholders, npm test suite, sample data JSON.

Brand consistency: Verified against the existing jersey-reminder template (PRs #2, #5, #6). Color tokens are consistent: #141414 body sections, #0a0a0a card background, #c41230 accent/CTA, #333 card borders, #f0f0f0 body text, #a0a0a0 secondary text. Card component pattern (background-color="#0a0a0a" border-radius="8px" border="1px solid #333" padding="20px") matches exactly. CTA button styling matches.

Shared partials: Correctly uses mj-include for head, header, and footer -- no inline duplication of brand elements.

Placeholder completeness: All 10 placeholders (parent_name, player_name, tenant_name, division, position, height, grad_class, profile_url, frontend_url, credentials_block) are present in both the MJML template and sample data JSON. Sample data has appropriate test values for all fields.

Sample data: No real PII. Names are clearly fictitious. Tailscale hostname is the standard production domain used across the org. credentials_block is correctly empty (populated at send time by the API).

Security: credentials_block is a raw HTML injection point by design -- the calling API (basketball-api) is responsible for sanitizing this content. No secrets, API keys, or real credentials in the committed files.

BLOCKERS

None.

The test suite (10/10 per PR body) covers compilation, placeholder verification, and DRY checks. The existing test infrastructure appears to automatically cover new templates, so no new test file is needed. No unvalidated user input in the template layer itself (rendering is the API's responsibility). No secrets committed.

NITS

  1. Hardcoded phone number (line 88 of MJML): (385) 450-9963 is hardcoded directly in the template. The jersey-reminder template uses "reply to this email" instead. If this number appears in future templates too, consider extracting it to a partial to avoid update-everywhere maintenance. Low risk for now with only two templates.

  2. frontend_url not hyperlinked (line 79-81): The "Sign in anytime at {{frontend_url}}" text renders the URL as plain text. Consider wrapping it in an <a> tag so email clients render it as a clickable link: <a href="{{frontend_url}}" style="color: #c41230;">{{frontend_url}}</a>. Some email clients auto-link URLs, but not all.

  3. Empty credentials_block renders empty space: When credentials_block is empty string (the common case for returning players), the credentials section still renders as a 16px-padded empty block. Minor visual gap. Consider conditionally rendering this section at the API layer, or documenting that the API should omit the placeholder entirely when not needed.

SOP COMPLIANCE

  • Branch named after issue: 8-registration-confirmation-template follows {issue-number}-{kebab-case-purpose}
  • PR body follows template: Summary, Changes, Test Plan, Review Checklist, Related sections present
  • Related references issue: "Closes #8"
  • No plan referenced (correct -- no plan exists for this work)
  • Tests exist and pass (10/10 per PR body)
  • No secrets, .env files, or credentials committed
  • No unnecessary file changes -- exactly 2 files, both directly related to the issue
  • Commit messages are descriptive

PROCESS OBSERVATIONS

Clean, focused PR. Two files, 109 lines, single concern. Template follows established patterns from the jersey-reminder template with no divergence in brand tokens or component structure. Test infrastructure automatically validates new templates, which is a good architectural choice for this repo. The credentials_block injection pattern is a reasonable design for composable email content -- just ensure the basketball-api side sanitizes what it injects.

VERDICT: APPROVED

## PR #9 Review ### DOMAIN REVIEW **Tech stack**: MJML email templates with Mustache-style placeholders, npm test suite, sample data JSON. **Brand consistency**: Verified against the existing jersey-reminder template (PRs #2, #5, #6). Color tokens are consistent: `#141414` body sections, `#0a0a0a` card background, `#c41230` accent/CTA, `#333` card borders, `#f0f0f0` body text, `#a0a0a0` secondary text. Card component pattern (`background-color="#0a0a0a" border-radius="8px" border="1px solid #333" padding="20px"`) matches exactly. CTA button styling matches. **Shared partials**: Correctly uses `mj-include` for head, header, and footer -- no inline duplication of brand elements. **Placeholder completeness**: All 10 placeholders (`parent_name`, `player_name`, `tenant_name`, `division`, `position`, `height`, `grad_class`, `profile_url`, `frontend_url`, `credentials_block`) are present in both the MJML template and sample data JSON. Sample data has appropriate test values for all fields. **Sample data**: No real PII. Names are clearly fictitious. Tailscale hostname is the standard production domain used across the org. `credentials_block` is correctly empty (populated at send time by the API). **Security**: `credentials_block` is a raw HTML injection point by design -- the calling API (basketball-api) is responsible for sanitizing this content. No secrets, API keys, or real credentials in the committed files. ### BLOCKERS None. The test suite (10/10 per PR body) covers compilation, placeholder verification, and DRY checks. The existing test infrastructure appears to automatically cover new templates, so no new test file is needed. No unvalidated user input in the template layer itself (rendering is the API's responsibility). No secrets committed. ### NITS 1. **Hardcoded phone number** (line 88 of MJML): `(385) 450-9963` is hardcoded directly in the template. The jersey-reminder template uses "reply to this email" instead. If this number appears in future templates too, consider extracting it to a partial to avoid update-everywhere maintenance. Low risk for now with only two templates. 2. **`frontend_url` not hyperlinked** (line 79-81): The "Sign in anytime at `{{frontend_url}}`" text renders the URL as plain text. Consider wrapping it in an `<a>` tag so email clients render it as a clickable link: `<a href="{{frontend_url}}" style="color: #c41230;">{{frontend_url}}</a>`. Some email clients auto-link URLs, but not all. 3. **Empty `credentials_block` renders empty space**: When `credentials_block` is empty string (the common case for returning players), the credentials section still renders as a 16px-padded empty block. Minor visual gap. Consider conditionally rendering this section at the API layer, or documenting that the API should omit the placeholder entirely when not needed. ### SOP COMPLIANCE - [x] Branch named after issue: `8-registration-confirmation-template` follows `{issue-number}-{kebab-case-purpose}` - [x] PR body follows template: Summary, Changes, Test Plan, Review Checklist, Related sections present - [x] Related references issue: "Closes #8" - [x] No plan referenced (correct -- no plan exists for this work) - [x] Tests exist and pass (10/10 per PR body) - [x] No secrets, .env files, or credentials committed - [x] No unnecessary file changes -- exactly 2 files, both directly related to the issue - [x] Commit messages are descriptive ### PROCESS OBSERVATIONS Clean, focused PR. Two files, 109 lines, single concern. Template follows established patterns from the jersey-reminder template with no divergence in brand tokens or component structure. Test infrastructure automatically validates new templates, which is a good architectural choice for this repo. The `credentials_block` injection pattern is a reasonable design for composable email content -- just ensure the basketball-api side sanitizes what it injects. ### VERDICT: APPROVED
forgejo_admin deleted branch 8-registration-confirmation-template 2026-04-07 19:29:34 +00:00
Commenting is not possible because the repository is archived.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ldraney/westside-emails!9
No description provided.