Moved the automations domain from the posts package into apps/admin - #29207
Conversation
ref https://linear.app/ghost/issue/PLA-221/posts-admin-move-tags-comments-automations - second domain to leave the posts package as it dissolves into apps/admin; automations is self-contained (no cross-domain or PostsAppContext dependency, its utils are internal), so it moves cleanly - the automations routes fold into the shell's own route table, preserving the hideAdminSidebar handle on the editor route (the Admin layout already honours it via sidebar-visibility) - MainLayout is replaced with shade Box + Container, matching the tags move; the rendered layout is unchanged - brings the migrated code up to Admin's stricter lint/tsconfig: exhaustiveness throws stringify the never value, react-query error callbacks and floating promises are voided/awaited correctly, the exhaustive-switch throw uses instanceof, non-component canvas helpers move to node-helpers.ts for react-refresh, and the module-mock hooks use vi.hoisted - adds a smoke e2e for the automations page, which previously had no e2e coverage
WalkthroughThe Automations feature is relocated from apps/posts to apps/admin with new routes, dependencies ( Suggested reviewers: 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
|
| Command | Status | Duration | Result |
|---|---|---|---|
nx run @tryghost/admin-x-settings:test:acceptance |
✅ Succeeded | 10m 30s | View ↗ |
nx run ghost:test:ci:integration |
✅ Succeeded | 2m 40s | View ↗ |
nx run-many --target=build --projects=tag:publi... |
✅ Succeeded | <1s | View ↗ |
nx run-many -t test:unit -p @tryghost/admin,@tr... |
✅ Succeeded | 26s | View ↗ |
nx run ghost:test:integration |
✅ Succeeded | 2m 44s | View ↗ |
nx run ghost:test:legacy |
✅ Succeeded | 2m 55s | View ↗ |
nx run ghost-monorepo:lint:boundaries |
✅ Succeeded | 6s | View ↗ |
nx run ghost:test:e2e |
✅ Succeeded | 2m 25s | View ↗ |
Additional runs (11) |
✅ Succeeded | ... | View ↗ |
💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗
☁️ Nx Cloud last updated this comment at 2026-07-09 17:12:41 UTC
There was a problem hiding this comment.
🧹 Nitpick comments (2)
apps/admin/package.json (1)
24-24: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMove
@xyflow/reactto the shared catalog
Add@xyflow/reacttopnpm-workspace.yamland switchapps/admin/package.json:24tocatalog:so it follows the workspace dependency convention.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/admin/package.json` at line 24, The `@xyflow/react` dependency in the admin package is still pinned directly instead of using the workspace catalog convention. Add `@xyflow/react` to the shared catalog in pnpm-workspace.yaml, then update the apps/admin package.json dependency entry to reference catalog: so it stays aligned with the rest of the workspace.Source: Coding guidelines
apps/admin/src/automations/utils.ts (1)
1-8: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueExtract the shared
LexicalState/LexicalNodetypes
apps/admin/src/automations/utils.tsandapps/admin/src/automations/components/email-modal/validation.tsboth define the same interfaces. Move them to a shared module so the parsing logic stays aligned.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/admin/src/automations/utils.ts` around lines 1 - 8, The LexicalNode and LexicalState interfaces are duplicated between the automation utils and the email modal validation logic, so extract them into a shared module and import them from both places. Update the parsing helpers that use these types, including the symbols LexicalNode, LexicalState, and any related JSON parsing functions, so both callers stay aligned on the same shape and future changes only happen in one place.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@apps/admin/package.json`:
- Line 24: The `@xyflow/react` dependency in the admin package is still pinned
directly instead of using the workspace catalog convention. Add `@xyflow/react` to
the shared catalog in pnpm-workspace.yaml, then update the apps/admin
package.json dependency entry to reference catalog: so it stays aligned with the
rest of the workspace.
In `@apps/admin/src/automations/utils.ts`:
- Around line 1-8: The LexicalNode and LexicalState interfaces are duplicated
between the automation utils and the email modal validation logic, so extract
them into a shared module and import them from both places. Update the parsing
helpers that use these types, including the symbols LexicalNode, LexicalState,
and any related JSON parsing functions, so both callers stay aligned on the same
shape and future changes only happen in one place.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: bb241af6-4ba8-4dfc-adb9-0217b941a345
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (44)
apps/admin/package.jsonapps/admin/src/automations/automations.test.tsxapps/admin/src/automations/automations.tsxapps/admin/src/automations/components/automation-header.tsxapps/admin/src/automations/components/automation-status-badge.tsxapps/admin/src/automations/components/automations-help-cards.tsxapps/admin/src/automations/components/automations-list.test.tsxapps/admin/src/automations/components/automations-list.tsxapps/admin/src/automations/components/canvas/add-step-edge.tsxapps/admin/src/automations/components/canvas/automation-canvas.tsxapps/admin/src/automations/components/canvas/controls.tsxapps/admin/src/automations/components/canvas/format-wait.test.tsapps/admin/src/automations/components/canvas/format-wait.tsapps/admin/src/automations/components/canvas/node-helpers.tsapps/admin/src/automations/components/canvas/nodes.tsxapps/admin/src/automations/components/canvas/step-picker.tsxapps/admin/src/automations/components/canvas/step-sidebar.tsxapps/admin/src/automations/components/email-modal/email-content-modal.tsxapps/admin/src/automations/components/email-modal/email-editor.tsxapps/admin/src/automations/components/email-modal/newsletter-emails.tsapps/admin/src/automations/components/email-modal/preview-frame.tsxapps/admin/src/automations/components/email-modal/sender-details.tsapps/admin/src/automations/components/email-modal/test-email-dropdown.tsxapps/admin/src/automations/components/email-modal/use-email-preview.tsapps/admin/src/automations/components/email-modal/use-link-suggestions.tsapps/admin/src/automations/components/email-modal/use-sender-details.tsapps/admin/src/automations/components/email-modal/validation.tsapps/admin/src/automations/components/types.tsapps/admin/src/automations/editor.test.tsxapps/admin/src/automations/editor.tsxapps/admin/src/automations/hooks/use-visible-automations.tsapps/admin/src/automations/hooks/use-welcome-email-sender-details.tsapps/admin/src/automations/types.tsapps/admin/src/automations/utils.tsapps/admin/src/automations/utils/default-welcome-email-values.tsapps/admin/src/automations/utils/newsletter-emails.tsapps/admin/src/automations/utils/welcome-email-sender-details.tsapps/admin/src/routes.tsxapps/posts/src/routes.tsxapps/posts/src/views/Automations/components/email-modal/koenig-lexical.d.tse2e/helpers/pages/admin/automations/automations-page.tse2e/helpers/pages/admin/automations/index.tse2e/helpers/pages/admin/index.tse2e/tests/admin/automations/automations.test.ts
💤 Files with no reviewable changes (1)
- apps/posts/src/views/Automations/components/email-modal/koenig-lexical.d.ts
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #29207 +/- ##
==========================================
+ Coverage 74.04% 74.07% +0.03%
==========================================
Files 1570 1570
Lines 136624 136624
Branches 16520 16524 +4
==========================================
+ Hits 101159 101202 +43
+ Misses 34460 34417 -43
Partials 1005 1005
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|

ref https://linear.app/ghost/issue/PLA-221/posts-admin-move-tags-comments-automations
Second domain to leave the
postspackage as it dissolves intoapps/admin(PLA-221), after tags. Automations is self-contained — no cross-domain orPostsAppContextdependency, itsutilsare internal — so it's a clean move.What changed
apps/posts/src/views/Automations/→apps/admin/src/automations/(32 files).apps/admin/src/routes.tsx), preserving thehideAdminSidebarhandle on the/automations/:ideditor route. Admin already honours that handle vialayout/sidebar-visibility.ts(covered bysidebar-visibility.test.tsx). Removed the automations block fromapps/posts/src/routes.tsx.MainLayout→ shadeBox+Container, matching the tags move; rendered layout unchanged.e2e/tests/admin/automations/) — automations was the only admin domain with no e2e coverage.Admin strictness
Admin's config is stricter than posts; the move surfaced 21 lint/tsc issues, all fixed at the source (no disables):
throwsites stringify thenevervalue (restrict-template-expressions)only-throw-error:throw error instanceof Error ? error : new Error(...)no-misused-promisesonClickwrapped, one spuriousasyncdroppednodeTypes,toApiAnchor) extracted tonode-helpers.ts(react-refresh/only-export-components)anyrouter-state spread narrowed; module-mock hooks usevi.hoisted(hoist-safe)Verification
tsc -b,eslint .(admin) — exit 0vitest run(admin) — 449 tests pass (incl. the 4 moved automations suites)@tryghost/postsbuild / lint / test — exit 0 (automations removed cleanly; posts import-sort re-fixed afterAdminRouteHandledropped from its imports)nx build @tryghost/admin— exit 0; automations code-splits into its own lazy chunks (list + editor)Note: I did not dev-drive the Beta (flag-gated) editor this round — the
hideAdminSidebarbehaviour it exercises is unit-tested and the route wiring is confirmed. Happy to boot dev and walk it if preferred.