{"id":"69cd7f79f4bae6a5c5e8e2c2","title":"2026 04 01 Issue 207","path":"how-to/committee/release-notes/2026-04-01-issue-207","contentMarkdown":"# 01-Apr-2026 — Add MX record management for subdomain email routing [#207](https://github.com/nbarrett/ngx-ramblers/issues/207)\n\n## [build 573](https://github.com/nbarrett/ngx-ramblers/actions/runs/23868774282) — [commit 4549a14](https://github.com/nbarrett/ngx-ramblers/commit/4549a142dff928cd8522e2e6c8d7966cd50d81bb)\n\n_____\n\n### MX Record Status on Mail Settings Page\nThe **Senders** tab on the Mail Settings page (`/admin/mail-settings?tab=senders`)\nnow includes an **MX Records** section that shows:\n- Whether the required Cloudflare MX records are configured for your environment's domain\n- A status table listing each required mail server with a check or cross indicator\n- An **Add Missing MX Records** button that appears when records are missing,\nallowing you to fix the configuration with a single click\nThis makes it easy for site administrators to diagnose and resolve email delivery\nissues without needing direct access to Cloudflare.\n### Automatic MX Records for New Environments\nWhen a new environment is provisioned via the environment setup workflow, the\nrequired MX records are now created automatically alongside the existing A and\nAAAA DNS records. This prevents the email routing gap that previously affected\nall new subdomain deployments.\n### Background\nEmails sent to `*.ngx-ramblers.org.uk` subdomain addresses were bouncing with\nerror `5.4.0 (network or routing status)` because no MX records existed to tell\nsending mail servers where to deliver email. The root domain and all custom\ndomains (e.g. `ekwg.co.uk`) had correct MX records, but subdomains like\n`kent.ngx-ramblers.org.uk` were missing them entirely.\nThe three required MX records point to Cloudflare's email routing servers:\n- `route1.mx.cloudflare.net` (priority 16)\n- `route2.mx.cloudflare.net` (priority 99)\n- `route3.mx.cloudflare.net` (priority 2)\n---\n### Before Fix\n\n![](https://ngx-ramblers.org.uk/api/aws/s3/site-content/cf98f92a-231f-46ab-8d7f-a66041380c88.jpeg)\n\n---\n### After Fix\n\n![](https://ngx-ramblers.org.uk/api/aws/s3/site-content/433b4657-9bc3-4f25-8dac-0c3c3403f8ae.jpeg)\n\n---\n## Technical Details\n### Server-side changes\n- **`server/lib/cloudflare/cloudflare.model.ts`** — Added `priority` field to\n`DnsRecord` and `DnsRecordResult` interfaces. Added `MxRecordDetail` and\n`MxRecordStatus` interfaces for the status API response.\n- **`server/lib/cloudflare/cloudflare-dns.ts`** — Updated `createDnsRecord()` to\nconditionally include `priority` in the Cloudflare API POST body when present\n(required for MX record creation).\n- **`server/lib/cloudflare/cloudflare-email-routing-routes.ts`** — Added two new\nauthenticated API endpoints:\n- `GET /api/cloudflare/email-routing/mx-records` — returns MX record status\nfor the current environment's subdomain\n- `POST /api/cloudflare/email-routing/mx-records` — creates any missing MX\nrecords and returns updated status\n- **`server/lib/cli/commands/subdomain.ts`** — Updated\n`setupSubdomainForEnvironment()` to create MX records after A/AAAA records,\nwith duplicate detection matching the existing pattern.\n### Client-side changes\n- **`projects/ngx-ramblers/src/app/models/cloudflare-email-routing.model.ts`** —\nAdded `MxRecordStatus`, `MxRecordDetail`, and `MxExistingRecord` interfaces.\n- **`projects/ngx-ramblers/src/app/services/cloudflare/cloudflare-email-routing.service.ts`** —\nAdded `queryMxRecordStatus()` and `createMissingMxRecords()` service methods.\n- **`projects/ngx-ramblers/src/app/pages/admin/system-settings/mail/mail-senders-list.ts`** —\nAdded MX record status section to the template with status badge, record table,\nerror display, and create button. Added `loadMxRecordStatus()` and\n`createMissingMxRecords()` component methods.\n\n### **lint**: replace native confirm() with inline UI and fix ESLint dialog rules\n\nReplace native confirm() in committee settings with inline Confirm/Cancel\nbuttons. Refine ESLint confirm() selector to match only Literal and\nTemplateLiteral arguments. Move nativeBrowserDialogRestrictions to\nfrontend-only config block. Exclude CLI files that legitimately use\n@inquirer/prompts confirm() from dialog restrictions.","contentHtml":"<h1>01-Apr-2026 — Add MX record management for subdomain email routing <a href=\"https://github.com/nbarrett/ngx-ramblers/issues/207\">#207</a></h1>\n<h2><a href=\"https://github.com/nbarrett/ngx-ramblers/actions/runs/23868774282\">build 573</a> — <a href=\"https://github.com/nbarrett/ngx-ramblers/commit/4549a142dff928cd8522e2e6c8d7966cd50d81bb\">commit 4549a14</a></h2>\n<hr>\n<h3>MX Record Status on Mail Settings Page</h3>\n<p>The <strong>Senders</strong> tab on the Mail Settings page (<code>/admin/mail-settings?tab=senders</code>)\nnow includes an <strong>MX Records</strong> section that shows:</p>\n<ul>\n<li>Whether the required Cloudflare MX records are configured for your environment&#39;s domain</li>\n<li>A status table listing each required mail server with a check or cross indicator</li>\n<li>An <strong>Add Missing MX Records</strong> button that appears when records are missing,\nallowing you to fix the configuration with a single click\nThis makes it easy for site administrators to diagnose and resolve email delivery\nissues without needing direct access to Cloudflare.</li>\n</ul>\n<h3>Automatic MX Records for New Environments</h3>\n<p>When a new environment is provisioned via the environment setup workflow, the\nrequired MX records are now created automatically alongside the existing A and\nAAAA DNS records. This prevents the email routing gap that previously affected\nall new subdomain deployments.</p>\n<h3>Background</h3>\n<p>Emails sent to <code>*.ngx-ramblers.org.uk</code> subdomain addresses were bouncing with\nerror <code>5.4.0 (network or routing status)</code> because no MX records existed to tell\nsending mail servers where to deliver email. The root domain and all custom\ndomains (e.g. <code>ekwg.co.uk</code>) had correct MX records, but subdomains like\n<code>kent.ngx-ramblers.org.uk</code> were missing them entirely.\nThe three required MX records point to Cloudflare&#39;s email routing servers:</p>\n<ul>\n<li><code>route1.mx.cloudflare.net</code> (priority 16)</li>\n<li><code>route2.mx.cloudflare.net</code> (priority 99)</li>\n<li><code>route3.mx.cloudflare.net</code> (priority 2)</li>\n</ul>\n<hr>\n<h3>Before Fix</h3>\n<p><img src=\"https://ngx-ramblers.org.uk/api/aws/s3/site-content/cf98f92a-231f-46ab-8d7f-a66041380c88.jpeg\" alt=\"\"></p>\n<hr>\n<h3>After Fix</h3>\n<p><img src=\"https://ngx-ramblers.org.uk/api/aws/s3/site-content/433b4657-9bc3-4f25-8dac-0c3c3403f8ae.jpeg\" alt=\"\"></p>\n<hr>\n<h2>Technical Details</h2>\n<h3>Server-side changes</h3>\n<ul>\n<li><strong><code>server/lib/cloudflare/cloudflare.model.ts</code></strong> — Added <code>priority</code> field to\n<code>DnsRecord</code> and <code>DnsRecordResult</code> interfaces. Added <code>MxRecordDetail</code> and\n<code>MxRecordStatus</code> interfaces for the status API response.</li>\n<li><strong><code>server/lib/cloudflare/cloudflare-dns.ts</code></strong> — Updated <code>createDnsRecord()</code> to\nconditionally include <code>priority</code> in the Cloudflare API POST body when present\n(required for MX record creation).</li>\n<li><strong><code>server/lib/cloudflare/cloudflare-email-routing-routes.ts</code></strong> — Added two new\nauthenticated API endpoints:</li>\n<li><code>GET /api/cloudflare/email-routing/mx-records</code> — returns MX record status\nfor the current environment&#39;s subdomain</li>\n<li><code>POST /api/cloudflare/email-routing/mx-records</code> — creates any missing MX\nrecords and returns updated status</li>\n<li><strong><code>server/lib/cli/commands/subdomain.ts</code></strong> — Updated\n<code>setupSubdomainForEnvironment()</code> to create MX records after A/AAAA records,\nwith duplicate detection matching the existing pattern.</li>\n</ul>\n<h3>Client-side changes</h3>\n<ul>\n<li><strong><code>projects/ngx-ramblers/src/app/models/cloudflare-email-routing.model.ts</code></strong> —\nAdded <code>MxRecordStatus</code>, <code>MxRecordDetail</code>, and <code>MxExistingRecord</code> interfaces.</li>\n<li><strong><code>projects/ngx-ramblers/src/app/services/cloudflare/cloudflare-email-routing.service.ts</code></strong> —\nAdded <code>queryMxRecordStatus()</code> and <code>createMissingMxRecords()</code> service methods.</li>\n<li><strong><code>projects/ngx-ramblers/src/app/pages/admin/system-settings/mail/mail-senders-list.ts</code></strong> —\nAdded MX record status section to the template with status badge, record table,\nerror display, and create button. Added <code>loadMxRecordStatus()</code> and\n<code>createMissingMxRecords()</code> component methods.</li>\n</ul>\n<h3><strong>lint</strong>: replace native confirm() with inline UI and fix ESLint dialog rules</h3>\n<p>Replace native confirm() in committee settings with inline Confirm/Cancel\nbuttons. Refine ESLint confirm() selector to match only Literal and\nTemplateLiteral arguments. Move nativeBrowserDialogRestrictions to\nfrontend-only config block. Exclude CLI files that legitimately use\n@inquirer/prompts confirm() from dialog restrictions.</p>\n"}