Skip to content

Added email_design_settings table migration#26973

Merged
cmraible merged 7 commits intomainfrom
chris-ny-1137-create-email_templates-table-migration
Mar 26, 2026
Merged

Added email_design_settings table migration#26973
cmraible merged 7 commits intomainfrom
chris-ny-1137-create-email_templates-table-migration

Conversation

@cmraible
Copy link
Copy Markdown
Collaborator

@cmraible cmraible commented Mar 26, 2026

closes https://linear.app/ghost/issue/NY-1137/create-email-design-settings-table-migration

Summary

Adds a new email_design_settings table to store email design/styling settings independently from newsletters. The table columns mirror the design-related columns from the newsletters table (background colors, fonts, button styles, image corners, etc.) with identical types, constraints, and defaults.

title_alignment and post_title_color are intentionally omitted — this table initially supports automated emails which don't use those columns. They can be added later if/when we extend templates for newsletters.

Changes

  • Added email_design_settings table definition in schema.js with isIn validations for enum fields
  • Added addTable migration for the new table
  • Added email_design_settings to the backup tables list in table-lists.js
  • Updated exporter test expectations and schema integrity hash

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 26, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 878e41de-1f11-4522-bd40-f0083ac570db

📥 Commits

Reviewing files that changed from the base of the PR and between b24b3ad and 3a83d24.

📒 Files selected for processing (2)
  • ghost/core/core/server/data/migrations/versions/6.24/2026-03-26-15-46-51-add-email-design-settings-table.js
  • ghost/core/core/server/data/schema/schema.js
✅ Files skipped from review due to trivial changes (2)
  • ghost/core/core/server/data/migrations/versions/6.24/2026-03-26-15-46-51-add-email-design-settings-table.js
  • ghost/core/core/server/data/schema/schema.js

Walkthrough

Adds a new email_design_settings database table (migration and schema) with id, unique slug, multiple email styling/configuration fields, created_at, and updated_at. The table is added to the backup table list. Tests were updated to include the new table in exports and the schema integrity MD5 was updated. Package versions in core and admin were bumped to 6.24.0-rc.0.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change—adding a new email_design_settings table migration—which aligns with the primary objective of this pull request.
Description check ✅ Passed The description is directly related to the changeset, providing context about the new table, its purpose, design decisions (omitted fields), and listing all the concrete changes made in the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chris-ny-1137-create-email_templates-table-migration

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added the migration [pull request] Includes migration for review label Mar 26, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 26, 2026

It looks like this PR contains a migration 👀
Here's the checklist for reviewing migrations:

General requirements

  • ⚠️ Tested performance on staging database servers, as performance on local machines is not comparable to a production environment
  • Satisfies idempotency requirement (both up() and down())
  • Does not reference models
  • Filename is in the correct format (and correctly ordered)
  • Targets the next minor version
  • All code paths have appropriate log messages
  • Uses the correct utils
  • Contains a minimal changeset
  • Does not mix DDL/DML operations
  • Tested in MySQL and SQLite

Schema changes

  • Both schema change and related migration have been implemented
  • For index changes: has been performance tested for large tables
  • For new tables/columns: fields use the appropriate predefined field lengths
  • For new tables/columns: field names follow the appropriate conventions
  • Does not drop a non-alpha table outside of a major version

Data changes

  • Mass updates/inserts are batched appropriately
  • Does not loop over large tables/datasets
  • Defends against missing or invalid data
  • For settings updates: follows the appropriate guidelines

@cmraible cmraible changed the title Chris ny 1137 create email templates table migration Added email_templates table migration Mar 26, 2026
@cmraible cmraible changed the base branch from main to improve-database-migration-skill March 26, 2026 02:30
Comment on lines +16 to +17
title_font_category: {type: 'string', maxlength: 191, nullable: false, defaultTo: 'sans_serif'},
title_font_weight: {type: 'string', maxlength: 50, nullable: false, defaultTo: 'bold'},
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: this is the heading font and weight field, named as "title_*" to match the newsletters table. for newsletters, these options apply to both the post title and the headings; for welcome emails, there is no title, so it only applies to headings.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah good call - came across this on the frontend and it felt kinda odd but better to keep the naming consistent

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be worth leaving a comment to this effect.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good shout, added an inline comment in the schema and migration files

@cmraible cmraible marked this pull request as ready for review March 26, 2026 03:26
@cmraible

This comment was marked as outdated.

@cmraible cmraible requested review from troyciesco and removed request for troyciesco March 26, 2026 04:01
@cmraible cmraible marked this pull request as draft March 26, 2026 05:02
@cmraible cmraible changed the title Added email_templates table migration Added email_design_settings table migration Mar 26, 2026
@cmraible cmraible marked this pull request as ready for review March 26, 2026 05:58
@cmraible cmraible requested a review from troyciesco March 26, 2026 06:11
@cmraible
Copy link
Copy Markdown
Collaborator Author

@troyciesco you may notice that I've changed the name from email_templates to email_design_settings. I think this is more precise since this table should strictly be for design related settings. After getting my hands in the code, email_templates started to feel a bit too vague.

@cmraible cmraible requested a review from EvanHahn March 26, 2026 06:27
@cmraible
Copy link
Copy Markdown
Collaborator Author

@CodeRabbit review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 26, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
ghost/core/test/integration/exporter/exporter.test.js (1)

42-44: Alphabetical ordering is inconsistent.

The table list appears to be alphabetically sorted, but email_design_settings should come before email_spam_complaint_events (since 'd' < 's').

Suggested fix
                 'email_batches',
+                'email_design_settings',
                 'email_recipient_failures',
                 'email_recipients',
                 'email_spam_complaint_events',
-                'email_design_settings',
                 'emails',
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ghost/core/test/integration/exporter/exporter.test.js` around lines 42 - 44,
The table list in exporter.test.js is out of alphabetical order; move the
'email_design_settings' entry so it appears before 'email_spam_complaint_events'
in the array (the entries 'email_spam_complaint_events',
'email_design_settings', 'emails' should be reordered to be alphabetically
consistent), ensuring any test expectations that rely on ordering reference the
updated array.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@ghost/core/core/server/data/schema/schema.js`:
- Around line 1146-1168: The schema defines an email_design_settings table but
there is no corresponding Bookshelf model; create a new Bookshelf model file
named email-design-settings.js that follows the same pattern as existing models
(e.g., automated-email.js, settings.js): export a Bookshelf model with tableName
set to 'email_design_settings', set hasTimestamps or timestamp fields for
created_at/updated_at, include any relevant visibility/serializers/defaults
consistent with other design/settings models, and register/require it where
other models are loaded so the app can access email_design_settings via the
standard model layer.

---

Nitpick comments:
In `@ghost/core/test/integration/exporter/exporter.test.js`:
- Around line 42-44: The table list in exporter.test.js is out of alphabetical
order; move the 'email_design_settings' entry so it appears before
'email_spam_complaint_events' in the array (the entries
'email_spam_complaint_events', 'email_design_settings', 'emails' should be
reordered to be alphabetically consistent), ensuring any test expectations that
rely on ordering reference the updated array.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ba369fc9-ab6c-4ac6-b8ac-3020c02f7683

📥 Commits

Reviewing files that changed from the base of the PR and between 3385103 and c6f60ef.

📒 Files selected for processing (5)
  • ghost/core/core/server/data/exporter/table-lists.js
  • ghost/core/core/server/data/migrations/versions/6.23/2026-03-26-01-56-35-add-email-design-settings-table.js
  • ghost/core/core/server/data/schema/schema.js
  • ghost/core/test/integration/exporter/exporter.test.js
  • ghost/core/test/unit/server/data/schema/integrity.test.js

Comment on lines +16 to +17
title_font_category: {type: 'string', maxlength: 191, nullable: false, defaultTo: 'sans_serif'},
title_font_weight: {type: 'string', maxlength: 50, nullable: false, defaultTo: 'bold'},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah good call - came across this on the frontend and it felt kinda odd but better to keep the naming consistent

Copy link
Copy Markdown
Contributor

@EvanHahn EvanHahn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Three non-blocking comments.

module.exports = addTable('email_design_settings', {
id: {type: 'string', maxlength: 24, nullable: false, primary: true},
slug: {type: 'string', maxlength: 191, nullable: false, unique: true},
background_color: {type: 'string', maxlength: 50, nullable: false, defaultTo: 'light'},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think 50 is a reasonable upper limit, but I could see lowering it given that we expect these values to be shorter. Same comment applies to the other color columns in this file. Feel free to ignore.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I considered this too and generally agree. Ultimately I decided to keep it 1:1 with the newsletters table to avoid any complications in migrating these settings from the newsletters table in the future.

Comment on lines +16 to +17
title_font_category: {type: 'string', maxlength: 191, nullable: false, defaultTo: 'sans_serif'},
title_font_weight: {type: 'string', maxlength: 50, nullable: false, defaultTo: 'bold'},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be worth leaving a comment to this effect.

show_header_title: {type: 'boolean', nullable: false, defaultTo: true},
footer_content: {type: 'text', maxlength: 1000000000, nullable: true},
button_color: {type: 'string', maxlength: 50, nullable: true, defaultTo: 'accent'},
button_corners: {type: 'string', maxlength: 50, nullable: false, defaultTo: 'rounded', validations: {isIn: [['square', 'rounded', 'pill']]}},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

General Ghost question: why don't we do these validations at the database level (possibly in addition)?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a good question but I don't really have an answer. If I had to speculate, I'd guess that it has something to do with compatibility between knex & mysql & sqlite not being consistent, at least back when migrations were first setup for Ghost.

Copy link
Copy Markdown
Contributor

@troyciesco troyciesco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

throwing request changes on here real quick bc 6.23 was released so we gotta move the migration!

@troyciesco troyciesco force-pushed the chris-ny-1137-create-email_templates-table-migration branch from 8bb74fc to 2bf276e Compare March 26, 2026 15:55
@troyciesco troyciesco requested a review from 9larsons as a code owner March 26, 2026 15:55
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 26, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 73.18%. Comparing base (e494949) to head (3a83d24).
⚠️ Report is 11 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #26973      +/-   ##
==========================================
- Coverage   73.21%   73.18%   -0.03%     
==========================================
  Files        1539     1540       +1     
  Lines      121718   121724       +6     
  Branches    14733    14711      -22     
==========================================
- Hits        89118    89087      -31     
- Misses      31568    31627      +59     
+ Partials     1032     1010      -22     
Flag Coverage Δ
admin-tests 54.35% <ø> (ø)
e2e-tests 73.18% <100.00%> (-0.03%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Base automatically changed from improve-database-migration-skill to main March 26, 2026 16:18
@cmraible cmraible removed the request for review from 9larsons March 26, 2026 16:24
ref NY-1137
Stores design settings for email templates, initially for welcome emails
ref NY-1137
Added isIn validations, fixed nullable on button_color/link_color, removed fieldtype from footer_content
@troyciesco troyciesco force-pushed the chris-ny-1137-create-email_templates-table-migration branch from 2bf276e to b24b3ad Compare March 26, 2026 16:32
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
ghost/core/core/server/data/schema/schema.js (1)

1146-1148: Add an inline note for intentionally omitted newsletter fields.

A short comment here would preserve intent and reduce future accidental “parity fixes” for fields intentionally excluded in this phase.

💡 Suggested tweak
+    // NOTE: intentionally excludes `title_alignment` and `post_title_color` for current automated-email scope
     email_design_settings: {
         id: {type: 'string', maxlength: 24, nullable: false, primary: true},
         slug: {type: 'string', maxlength: 191, nullable: false, unique: true},
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ghost/core/core/server/data/schema/schema.js` around lines 1146 - 1148, Add
an inline comment near the email_design_settings schema object to state that
newsletter-related fields were intentionally omitted in this phase to avoid
accidental "parity fixes" later; update the block around the
email_design_settings definition (referencing the email_design_settings object
and its properties id and slug) with a concise note explaining the omission and
linking to any relevant issue or migration plan if available.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@ghost/core/core/server/data/schema/schema.js`:
- Around line 1146-1148: Add an inline comment near the email_design_settings
schema object to state that newsletter-related fields were intentionally omitted
in this phase to avoid accidental "parity fixes" later; update the block around
the email_design_settings definition (referencing the email_design_settings
object and its properties id and slug) with a concise note explaining the
omission and linking to any relevant issue or migration plan if available.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6189f8e5-1e34-49f4-8184-2a1a69dc135d

📥 Commits

Reviewing files that changed from the base of the PR and between c6f60ef and b24b3ad.

📒 Files selected for processing (7)
  • ghost/admin/package.json
  • ghost/core/core/server/data/exporter/table-lists.js
  • ghost/core/core/server/data/migrations/versions/6.24/2026-03-26-15-46-51-add-email-design-settings-table.js
  • ghost/core/core/server/data/schema/schema.js
  • ghost/core/package.json
  • ghost/core/test/integration/exporter/exporter.test.js
  • ghost/core/test/unit/server/data/schema/integrity.test.js
✅ Files skipped from review due to trivial changes (5)
  • ghost/core/test/unit/server/data/schema/integrity.test.js
  • ghost/core/package.json
  • ghost/core/core/server/data/exporter/table-lists.js
  • ghost/admin/package.json
  • ghost/core/core/server/data/migrations/versions/6.24/2026-03-26-15-46-51-add-email-design-settings-table.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • ghost/core/test/integration/exporter/exporter.test.js

The title_font_category and title_font_weight fields are named to match
the newsletters table; they apply to headings (and post title in newsletters)
@sonarqubecloud
Copy link
Copy Markdown

@cmraible cmraible enabled auto-merge (squash) March 26, 2026 17:40
@cmraible cmraible merged commit 96f1c41 into main Mar 26, 2026
38 checks passed
@cmraible cmraible deleted the chris-ny-1137-create-email_templates-table-migration branch March 26, 2026 17:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

migration [pull request] Includes migration for review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants