Skip to content

Stripped redundant fields from public member offers endpoint#26737

Merged
mike182uk merged 1 commit intomainfrom
misc-remove-redundant-offer-fields
Mar 9, 2026
Merged

Stripped redundant fields from public member offers endpoint#26737
mike182uk merged 1 commit intomainfrom
misc-remove-redundant-offer-fields

Conversation

@mike182uk
Copy link
Copy Markdown
Member

no ref

The /members/api/member/offers/ endpoint was returning the full admin DTO but some of the fields were not are not needed by Portal. Added a PublicOfferDTO and toPublicDTO mapper that returns only the fields the public endpoint requires

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 9, 2026

Walkthrough

Adds a new PublicOfferDTO typedef and OfferMapper.toPublicDTO(offer) to produce a public-facing offer shape. listOffersAvailableToSubscription now maps offers with toPublicDTO and its JSDoc return type was updated to Promise<OfferMapper.PublicOfferDTO[]>. Tests were adjusted to expect only public fields (excluding name, code, currency_restriction, etc.) and to assert tier contains only id.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: removing unnecessary fields from the public member offers endpoint by introducing a PublicOfferDTO.
Description check ✅ Passed The description clearly explains the motivation and implementation of the changes, relating directly to the introduced PublicOfferDTO and toPublicDTO mapper.
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 (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch misc-remove-redundant-offer-fields

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

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/test/unit/server/services/offers/application/offers-api.test.js (1)

116-138: Assert the nested tier payload too.

This only validates top-level keys, so it would still pass if toPublicDTO() started leaking tier.name. Since the new contract is about stripping admin-only fields, please pin the nested shape as well.

Suggested assertion
             assert.deepEqual(keys.sort(), [
                 'amount',
                 'cadence',
                 'currency',
                 'display_description',
                 'display_title',
                 'duration',
                 'duration_in_months',
                 'id',
                 'redemption_type',
                 'status',
                 'tier',
                 'type'
             ]);
+
+            assert.deepEqual(result[0].tier, {id: tierId});
 
             assert.equal(result[0].name, undefined);
             assert.equal(result[0].code, undefined);
             assert.equal(result[0].currency_restriction, undefined);
             assert.equal(result[0].redemption_count, undefined);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ghost/core/test/unit/server/services/offers/application/offers-api.test.js`
around lines 116 - 138, The test currently only checks top-level keys; extend it
to assert the nested tier payload from the public DTO to prevent admin-only
fields leaking. Locate the returned object used in the test (result[0]) and add
assertions that check Object.keys(result[0].tier).sort() equals the expected
public tier keys (pin the exact allowed keys for the public contract) and also
assert result[0].tier.name === undefined (or any other admin-only fields are
undefined). Reference the public serialization path (toPublicDTO / the code that
produces result) and ensure the nested assertions explicitly validate the tier
shape and absence of admin-only properties.
🤖 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/test/unit/server/services/offers/application/offers-api.test.js`:
- Around line 116-138: The test currently only checks top-level keys; extend it
to assert the nested tier payload from the public DTO to prevent admin-only
fields leaking. Locate the returned object used in the test (result[0]) and add
assertions that check Object.keys(result[0].tier).sort() equals the expected
public tier keys (pin the exact allowed keys for the public contract) and also
assert result[0].tier.name === undefined (or any other admin-only fields are
undefined). Reference the public serialization path (toPublicDTO / the code that
produces result) and ensure the nested assertions explicitly validate the tier
shape and absence of admin-only properties.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 81d57db6-b1d0-4d9e-8bb6-10f26af69870

📥 Commits

Reviewing files that changed from the base of the PR and between be0ea50 and b9554bf.

📒 Files selected for processing (5)
  • ghost/core/core/server/services/offers/application/offer-mapper.js
  • ghost/core/core/server/services/offers/application/offers-api.js
  • ghost/core/test/e2e-api/members/member-offers.test.js
  • ghost/core/test/unit/server/services/members/members-api/controllers/router-controller.test.js
  • ghost/core/test/unit/server/services/offers/application/offers-api.test.js

no ref

The `/members/api/member/offers/` endpoint was returning the full admin DTO
but some of the fields were not are not needed by Portal. Added a
`PublicOfferDTO` and `toPublicDTO` mapper that returns only the fields the
public endpoint requires
@mike182uk mike182uk force-pushed the misc-remove-redundant-offer-fields branch from b9554bf to a808131 Compare March 9, 2026 14:11
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/services/offers/application/offer-mapper.js (1)

88-112: LGTM! Clean implementation of public DTO mapping.

The toPublicDTO method correctly maps only the fields intended for public consumption. The separation from toDTO provides clear intent and makes it easy to evolve each DTO independently.

Minor observation: There's duplicated logic for computing duration_in_months and currency between toDTO and toPublicDTO. If this mapper evolves further, consider extracting these computations into small private helpers. However, given the current scope and clarity of the code, this is purely optional.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ghost/core/core/server/services/offers/application/offer-mapper.js` around
lines 88 - 112, toPublicDTO duplicates logic present in toDTO for computing
duration_in_months and currency; extract those expressions into small private
helper functions (e.g., computeDurationInMonths(offer) and
computeCurrency(offer)) and replace the inline ternaries in both toPublicDTO and
toDTO with calls to those helpers so the duration_in_months and currency
calculations are centralized and avoid duplication.
🤖 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/services/offers/application/offer-mapper.js`:
- Around line 88-112: toPublicDTO duplicates logic present in toDTO for
computing duration_in_months and currency; extract those expressions into small
private helper functions (e.g., computeDurationInMonths(offer) and
computeCurrency(offer)) and replace the inline ternaries in both toPublicDTO and
toDTO with calls to those helpers so the duration_in_months and currency
calculations are centralized and avoid duplication.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e2cee779-9a39-48ec-9e95-36aae91a9458

📥 Commits

Reviewing files that changed from the base of the PR and between b9554bf and a808131.

📒 Files selected for processing (5)
  • ghost/core/core/server/services/offers/application/offer-mapper.js
  • ghost/core/core/server/services/offers/application/offers-api.js
  • ghost/core/test/e2e-api/members/member-offers.test.js
  • ghost/core/test/unit/server/services/members/members-api/controllers/router-controller.test.js
  • ghost/core/test/unit/server/services/offers/application/offers-api.test.js
🚧 Files skipped from review as they are similar to previous changes (3)
  • ghost/core/test/unit/server/services/offers/application/offers-api.test.js
  • ghost/core/test/unit/server/services/members/members-api/controllers/router-controller.test.js
  • ghost/core/core/server/services/offers/application/offers-api.js

Copy link
Copy Markdown
Contributor

@sagzy sagzy left a comment

Choose a reason for hiding this comment

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

LGTM

@mike182uk mike182uk merged commit 338e1bd into main Mar 9, 2026
30 checks passed
@mike182uk mike182uk deleted the misc-remove-redundant-offer-fields branch March 9, 2026 15:28
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