Skip to content

Updated Audience Feedback to boot-owned initialization - #32169

Merged
ErisDS merged 1 commit into
mainfrom
codex/pla-546-audience-feedback-initializer
Oct 26, 2026
Merged

ErisDS merged 1 commit into
mainfrom
codex/pla-546-audience-feedback-initializer

Conversation

@ErisDS

@ErisDS ErisDS commented Oct 22, 2026 •

Copy link
Copy Markdown
Member

ref https://linear.app/ghost/issue/PLA-546

Publish Audience Feedback's repository, link service and controller together through defineService. Boot awaits readiness before Email captures the link service; request handlers retain their receivers. Permissions is injected from the root, while URL capture and feedback behavior stay unchanged.

This is one migration commit on main. It uses main's existing exact toPlain allowance and adds no dependency-policy changes.

Validation:

  • NX_PARALLEL=1 NX_DAEMON=false NX_TUI=false pnpm check passed, using normal Nx caching.
  • NX_PARALLEL=1 NX_DAEMON=false NX_TUI=false pnpm nx run ghost:test:unit test/unit/server/services/audience-feedback test/unit/server/services/email-service/email-service-wrapper.test.js test/unit/server/services/email-service/email-renderer.test.js test/unit/boot test/unit/server/services/service-inventory.test.ts --maxWorkers=1 passed 364 tests.
  • pnpm --dir tools/scripts exec node --test test/service-dependencies.test.ts test/oxlint.test.ts test/service-root-shape.test.ts passed 94 tests. Core types, lint, boundaries and the detailed dependency report are clean.
  • NX_PARALLEL=1 NX_DAEMON=false NX_TUI=false pnpm nx run ghost:test:e2e test/e2e-api/members/feedback.test.js --maxWorkers=1 passed all 14 HTTP cases.

@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between b6b96cb and 53599b9.

Files selected for processing: 2
  • .oxlintrc.json
  • ghost/core/server/services/service-inventory.yaml

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Recent review details
Context from checks skipped due to timeout: 19
  • GitHub Check: i18n
  • GitHub Check: Build E2E Public App Assets
  • GitHub Check: Unit tests (Node 24.20.0)
  • GitHub Check: Stripe fixture checks
  • GitHub Check: Acceptance tests (Node 24.20.0, mysql8)
  • GitHub Check: Unit tests (Node 22.23.4)
  • GitHub Check: Lint docs
  • GitHub Check: Check app version bump
  • GitHub Check: Acceptance tests (Node 22.23.4, mysql8)
  • GitHub Check: Typecheck
  • GitHub Check: Legacy tests (Node 22.23.4, mysql8)
  • GitHub Check: Build Docker Images
  • GitHub Check: Build Admin
  • GitHub Check: Check migration integrity
  • GitHub Check: Legacy tests (Node 24.20.0, mysql8)
  • GitHub Check: Lint
  • GitHub Check: Validate service inventory
  • GitHub Check: Detect Tinybird changes
  • GitHub Check: Analyze (javascript-typescript)
Additional context used
Code guidelines: 6
ghost/core/server/services/README.md — auto-discovered
tools/configs/eslint/README.md — auto-discovered
docs/codebase/monorepo-structure.md — configured
tools/README.md — configured
docs/codebase/jobs.md — configured
docs/practices/error-handling.md — configured
Path-based instructions: 8
Review new or changed service boundaries for explicit dependency ownership, deterministic/idempotent initialisation, boot ordering, transaction and event semantics, cache coherence, and restart/multi-instance safety.

CodeRabbit configuration file

Files:

  • ghost/core/server/services/service-inventory.yaml
Prioritise concrete correctness, security, data-integrity, compatibility, and regression risks.

CodeRabbit configuration file

Files:

  • ghost/core/server/services/service-inventory.yaml
Applicability reference: AGENTS.md: # AGENTS.md **Ghost Core:** use the [server map](docs/codebase/monorepo-structure.md#ghost-core) and read the [services guide](ghost/core/server/services/README.md) before Source excerpt...

CodeRabbit inference engine (ghost/core/server/services/README.md)

Files:

  • ghost/core/server/services/service-inventory.yaml
Applicability reference: AGENTS.md: # AGENTS.md **ESLint:** use the shared factories and dependency rules in the [ESLint configuration README](tools/configs/eslint/README.md).

CodeRabbit inference engine (tools/configs/eslint/README.md)

Files:

  • .oxlintrc.json
Applicability reference: AGENTS.md: # AGENTS.md Start with: [Monorepo structure](docs/codebase/monorepo-structure.md) AGENTS.md: # AGENTS.md **Ghost Core:** use the [server map](docs/codebase/monorepo-structure.md#ghost-core) Source excerpt...

CodeRabbit inference engine (docs/codebase/monorepo-structure.md)

Files:

  • ghost/core/server/services/service-inventory.yaml
Applicability reference: AGENTS.md: # AGENTS.md **Repository tooling:** read the [tooling ownership guide](tools/README.md) Source excerpt: These rules apply to every directory named `scripts`, including new directories at any depth.

CodeRabbit inference engine (tools/README.md)

Files:

  • ghost/core/server/services/service-inventory.yaml
Source excerpt: Jobs run in-process and share the main process's initialized services.

CodeRabbit inference engine (docs/codebase/jobs.md)

Files:

  • ghost/core/server/services/service-inventory.yaml
Source excerpt: Use that fallback when there is no safe, useful message.

CodeRabbit inference engine (docs/practices/error-handling.md)

Files:

  • ghost/core/server/services/service-inventory.yaml
Learnings: 1
Common learnings
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-10-19T15:25:36.037Z
Learning: Source excerpt:
# AGENTS.md

## Task routing and important warnings

- **Ghost Core:** use the [server map](docs/codebase/monorepo-structure.md#ghost-core)
  and read the [services guide](ghost/core/server/services/README.md) before
  adding or relocating a service root; apply its placement rules rather than
  inferring ownership from existing directory names. New standalone services
  use TypeScript; keep CommonJS only
  at existing `require()` boundaries. Boot owns service initialization; do not
  initialize on the first request.
Additional comments: 2
.oxlintrc.json: 1

203-203: LGTM!

ghost/core/server/services/service-inventory.yaml: 1

730-730: LGTM!

Also applies to: 743-743, 764-764, 770-770, 782-782, 790-790, 800-800, 809-809, 819-819, 846-846, 855-855, 863-863, 872-872, 893-893, 919-919, 932-932, 945-945, 958-958, 3175-3179, 15847-15847

Walkthrough

The Audience Feedback service now uses an initializer-based TypeScript root that constructs its repository, service, and controller. The controller receives permissions through its dependencies. Boot awaits initialization before starting the parallel service initializations. The API endpoint, email service, and member route use the nested service structure. Tests, lint configuration, and the service inventory reflect these changes.

Suggested reviewers: acburdine

Priority: Low

Change: Refactor

Merge Risk: Minimal · up to 53599

The migration preserves Audience Feedback behavior while ensuring its dependencies are initialized before consumers can use it.

Pre-merge checks: Passed 7
Check name Status Explanation
Title check Passed The title clearly summarizes the main change: Audience Feedback now uses boot-owned initialization.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Type-Safe Boundaries Passed The PR does not introduce an explicit type-safe-boundary failure. The new index.ts wires existing internal modules, models, and services through defineService; it adds no any, unchecked as, `@…
New Files Are Typescript Passed The PR adds no new .js, .jsx, .cjs, or .mjs source file. The diff adds ghost/core/server/services/audience-feedback/index.ts and deletes the pre-existing index.js; all other JavaScript files are m…
Tooling Ownership Passed All changed paths have appropriate owners. .oxlintrc.json is root lint configuration, and its new service-root entry matches the existing migrated-service rule. Runtime and inventory changes remain …
Description check Passed The pull request description directly describes the Audience Feedback migration, boot ordering, dependency injection, retained request-handler receivers, and validation results. These points match the…
Full details: Type-Safe Boundaries

Explanation

The PR does not introduce an explicit type-safe-boundary failure. The new index.ts wires existing internal modules, models, and services through defineService; it adds no any, unchecked as, @ts-nocheck, @ts-ignore, or hand-written type duplicating a Zod schema. The changed HTTP endpoint retains its existing framework validation, and the controller changes only dependency injection and service access. No new external boundary payload is consumed without validation.

Full details: New Files Are Typescript

Explanation

The PR adds no new .js, .jsx, .cjs, or .mjs source file. The diff adds ghost/core/server/services/audience-feedback/index.ts and deletes the pre-existing index.js; all other JavaScript files are modified, not added.

Full details: Tooling Ownership

Explanation

All changed paths have appropriate owners. .oxlintrc.json is root lint configuration, and its new service-root entry matches the existing migrated-service rule. Runtime and inventory changes remain under the owning Ghost Core service and its API/web consumers. Tests remain beside the service. No tools, ghost/scripts, ghost/bin, or new scripts path changed. The updated callers use the TypeScript service root through .default, and boot awaits initialization before Email uses the service, matching existing Core service conventions.

Full details: Description check

Explanation

The pull request description directly describes the Audience Feedback migration, boot ordering, dependency injection, retained request-handler receivers, and validation results. These points match the reported changes.

Finishing Touches
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@nx-cloud

nx-cloud Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

🤖 Nx Cloud AI Fix

Ensure the fix-ci command is configured to always run in your CI pipeline to get automatic fixes in future runs. For more information, please see https://nx.dev/ci/features/self-healing-ci


View your CI Pipeline Execution ↗ for commit 53599b9

Command Status Duration Result
nx run ghost:test:ci:integration ✅ Succeeded 1m 56s View ↗
nx run ghost:test:integration ✅ Succeeded 1m 29s View ↗
nx run ghost:test:ci:e2e ✅ Succeeded 3m 59s View ↗
nx run ghost:test:e2e ✅ Succeeded 2m 42s View ↗
nx run ghost:test:legacy ✅ Succeeded 2m 7s View ↗
nx run-many -t test:unit -p ghost,@internal/scr... ✅ Succeeded 1m 12s View ↗
nx run ghost:test:ci:unit ✅ Succeeded 1m 17s View ↗
nx run-many -t test:types -p ghost,@internal/sc... ✅ Succeeded 2s View ↗
Additional runs (6) ✅ Succeeded ... View ↗

💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗


☁️ Nx Cloud last updated this comment at 2026-10-26 09:28:02 UTC

@codecov

codecov Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.45455% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 85.59%. Comparing base (1e421b1) to head (53599b9).

Files with missing lines Patch % Lines
...host/core/server/api/endpoints/feedback-members.js 66.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #32169      +/-   ##
==========================================
+ Coverage   85.42%   85.59%   +0.16%     
==========================================
  Files        1399     1399              
  Lines       52415    52414       -1     
  Branches     9002     9001       -1     
==========================================
+ Hits        44775    44863      +88     
+ Misses       6544     6468      -76     
+ Partials     1096     1083      -13     
Flag Coverage Δ
e2e-tests 72.48% <90.90%> (-0.10%) ⬇️
unit-tests 68.26% <75.00%> (+0.08%) ⬆️

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

☔ View full report in Codecov by Harness.
📢 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.

@ErisDS
ErisDS force-pushed the codex/pla-546-audience-feedback-initializer branch from e7d431d to 01bfa1e Compare October 22, 2026 15:20
@ErisDS
ErisDS force-pushed the codex/pla-546-theme-fixture-isolation branch from 31f2ff0 to 7f49eda Compare October 22, 2026 15:20
@ErisDS

ErisDS commented Oct 24, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

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.

@ErisDS
ErisDS force-pushed the codex/pla-546-audience-feedback-initializer branch from 01bfa1e to c3ae8dd Compare October 24, 2026 14:26
@ErisDS

ErisDS commented Oct 24, 2026 •

Copy link
Copy Markdown
Member Author

Applied the same boundary-test improvement identified in the Theme Settings review: assert every rejected target alongside rule/source. The Email inventory now also describes awaited Audience Feedback readiness. Native suites pass 39 tests; tooling types/lint and all 87 inventory cases pass.

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

@ErisDS I’ll review the latest changes, with attention to the rejected-target assertions and the Email inventory’s description of awaited Audience Feedback readiness.


🧠 Learnings used
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: docs/contributing/testing.md:0-0
Timestamp: 2026-10-19T15:30:09.299Z
Learning: Applicability reference:
AGENTS.md: # AGENTS.md
Start with:

- [Testing](docs/contributing/testing.md)

Source excerpt:
# Testing Ghost

## Before Opening a Pull Request

If a full suite is impractical locally, run the most relevant focused tests and
state exactly what you ran in the pull request.
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: docs/contributing/testing.md:0-0
Timestamp: 2026-10-19T15:30:09.299Z
Learning: Applicability reference:
AGENTS.md: # AGENTS.md
Start with:

- [Testing](docs/contributing/testing.md)

Source excerpt:
# Testing Ghost

Ghost has several test suites across the monorepo. Start with the suite closest
to the behavior you changed, then run the broader checks before submitting your
pull request.
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: docs/contributing/testing.md:0-0
Timestamp: 2026-10-19T15:30:09.299Z
Learning: Applicability reference:
AGENTS.md: # AGENTS.md
Start with:

- [Testing](docs/contributing/testing.md)

Source excerpt:
# Testing Ghost

## Write Useful Tests

- Test observable behaviour rather than private implementation details. A
  refactor that preserves behaviour should not require unrelated test changes.
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: docs/practices/error-handling.md:0-0
Timestamp: 2026-10-19T15:29:01.919Z
Learning: Source excerpt:
# Error Handling

## Testing error handling

Test the designed behavior at each relevant boundary:
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: docs/contributing/testing.md:0-0
Timestamp: 2026-10-19T15:30:09.299Z
Learning: Applicability reference:
AGENTS.md: # AGENTS.md
Start with:

- [Testing](docs/contributing/testing.md)

Source excerpt:
# Testing Ghost

## Write Useful Tests

- Assert the result a user or caller depends on, including important side
  effects. Avoid assertions that merely repeat how the implementation works.
✅ Action performed

Review finished.

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.

@coderabbitai

coderabbitai Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor
⚠️ Action not completed

Already reviewed the last commit. Use @coderabbitai full review to rerun a review of the entire changeset.

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.

@ErisDS
ErisDS force-pushed the codex/pla-546-audience-feedback-initializer branch from c3ae8dd to 18ca8c3 Compare October 25, 2026 16:17
@ErisDS
ErisDS requested a review from EvanHahn as a code owner October 25, 2026 16:17
@ErisDS
ErisDS changed the base branch from codex/pla-546-theme-fixture-isolation to main October 25, 2026 16:18
ErisDS added a commit that referenced this pull request Oct 25, 2026
ref https://linear.app/ghost/issue/PLA-546

Boot awaits Member Attribution before Staff, Members and Email retain
its collaborators. The ready service owns its existing attribution
builder and constructor-wired outbound tagger. Parser URLs remain
captured at initialization; tracking and outbound tagging settings
remain live per operation.

This single migration commit targets main and includes exact allowances
for string utilities, referrer parsing, toPlain and link-replacer, with
a boundary regression. Source review found helpers operating on supplied
data without application-owned resources; sibling imports remain
restricted. The exact toPlain allowance also appears in #32169 because
both independent migrations need it. Staff, Members and Email inventory
descriptions record awaited attribution readiness.
@ErisDS
ErisDS force-pushed the codex/pla-546-audience-feedback-initializer branch from 18ca8c3 to b6b96cb Compare October 26, 2026 07:52
ref https://linear.app/ghost/issue/PLA-546

Publish the repository, link service and controller together during boot so Email captures a ready retained collaborator. Keep URL capture and request behavior while wiring permissions from the root.

Keep the stateless toPlain helper directly imported under the existing exact-file library allowance.
@ErisDS
ErisDS force-pushed the codex/pla-546-audience-feedback-initializer branch from b6b96cb to 53599b9 Compare October 26, 2026 09:20
@EvanHahn

Copy link
Copy Markdown
Contributor

I don't know much about this code area and it looks like I was only added automatically, so I'm recusing myself from review. Feel free to add me back.

@EvanHahn
EvanHahn removed their request for review October 26, 2026 12:50
@ErisDS
ErisDS merged commit 477001e into main Oct 26, 2026
60 checks passed
@ErisDS
ErisDS deleted the codex/pla-546-audience-feedback-initializer branch October 26, 2026 14:57
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.

2 participants