Skip to content

Added an opt-in contentType identity option to createAlgoliaRecords - #371

Merged
aileen merged 2 commits into
mainfrom
aileen/fragmenter-content-identity
Nov 5, 2026
Merged

aileen merged 2 commits into
mainfrom
aileen/fragmenter-content-identity

Conversation

@aileen

@aileen aileen commented Nov 5, 2026

Copy link
Copy Markdown
Member

ref TryGhost/algolia#213, TryGhost/algolia#4

What

The dormant Ghost content identity primitive for the fragmenter, the first half of the page-capable library primitives slice in the PRD:

  • createAlgoliaRecords accepts an opt-in contentType: 'post' | 'page' option declaring which Ghost Content API resource the batch came from.
  • When supplied, every derived record — fragment, continuation, and fallback — repeats the protected contentId (the stable Ghost ID) and contentType fields, measured inside the 9,999-byte complete-record ceiling.
  • contentId and contentType join the protected record names, so projection and ranking aliases can no longer occupy them.
  • Invalid values are rejected as INVALID_POLICY before any Ghost content is read.

What stays the same

Without the option, records are byte-identical to today, so the CLI, the Netlify handlers, and the deprecated wrappers are unaffected. No adapter is activated; posts-only defaults and slug APIs are untouched, per the dormant-release gate in the PRD.

Release notes

  • Behavior change: none for existing configuration; the only observable change without opting in is that a projection alias named contentId or contentType is now rejected deterministically before network access.
  • Version plan: one minor for @tryghost/algolia-fragmenter.
  • Rollback: revert the release adoption in consumers; no index or settings contract is touched.

Verification

  • pnpm test at the root: 531 tests, strict typecheck, lint, and format all pass, including the packed-package acceptance suite and the exact deprecated-wrapper non-regression tests.
  • New tests at the public createAlgoliaRecords seam cover identity repetition across fragment/continuation/fallback records, the dormant default, invalid content types, protected-name collisions, and a calibrated byte-boundary case proving identity bytes count toward the ceiling.

ref [#213](#213), [#4](#4)

Indexing Ghost pages beside posts needs an identity that does not collapse when a post and a page share a slug, and the planned index migration needs every managed record to carry it. This adds the dormant library primitive: a caller that declares its batch as `'post'` or `'page'` content gets the protected `contentId` (the stable Ghost ID) and `contentType` fields repeated in every derived record — fragment, continuation, and fallback alike — measured inside the 9,999-byte record ceiling. Without the option the output stays byte-identical, so the CLI, the Netlify handlers, and the deprecated wrappers are unaffected until they adopt identity after the guarded migration. The two field names are protected in projection validation from now on, so no projection alias can occupy them before identity is switched on.
@netlify

netlify Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for alg-helpcenter ready!

Name Link
🔨 Latest commit d3abea5
🔍 Latest deploy log https://app.netlify.com/projects/alg-helpcenter/deploys/6aec373cdf234bedda035c0f
😎 Deploy Preview https://deploy-preview-371--alg-helpcenter.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

Explain Change →

Warning

Review limit reached

  • Run on-demand review

This review includes 2 billable files and costs up to $0.50.

  • Ask an admin to make reviews automatic

Open in CodeRabbit

Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing.

Or wait 27 minutes for your next included review.

Check out review usage here.

View limit details

Limit details: You’ve used all 2 included reviews currently available. Your 50 included PR review attempts over the past 7 days set your current allowance at 2 reviews per hour.

Learn how review limits work.

Review configuration:

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: ad771d42-c3ed-4980-98bb-b872b4d5184b
Commits

Reviewing files that changed from the base of the PR and between f24932d and d3abea5.

Files selected for processing: 2

  • .nx/version-plans/version-plan-1793863387142.md
  • packages/algolia-fragmenter/README.md

No actionable comments were generated in the recent review.

Walkthrough

The change adds an optional contentType setting to createAlgoliaRecords, with accepted values 'post' and 'page'. When set, each derived record includes protected contentId and contentType fields. When omitted, the record shape remains unchanged. The change also updates public type exports, policy validation, documentation, and tests for alias collisions, fallback and continuation records, and the record byte limit.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: Minimal · previous review f2493

No actionable merge-blocking risk remains from the reviewed changes.

Pre-merge checks: Passed 5

Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: adding an opt-in contentType identity option to createAlgoliaRecords.
Description check Passed The description is directly related to the changeset and explains the new contentType option, identity fields, validation, protected names, compatibility behavior, release plan, and verification.
Docstring Coverage Passed No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
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.
Full details: Docstring Coverage

Explanation

No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 0 functions across 11 files. (2 skipped: 2 unsupported.)

Finishing Touches

Generate docstrings

  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)

  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Recent review info

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: accf1821-839b-4e25-8763-db2649424288
Commits

Reviewing files that changed from the base of the PR and between c345004 and f24932d.

Files ignored due to path filters: 8

  • packages/algolia-fragmenter/lib/index.d.mts.map is excluded by !**/*.map
  • packages/algolia-fragmenter/lib/index.mjs.map is excluded by !**/*.map
  • packages/algolia-fragmenter/lib/policy.d.mts.map is excluded by !**/*.map
  • packages/algolia-fragmenter/lib/policy.mjs.map is excluded by !**/*.map
  • packages/algolia-fragmenter/lib/projection.d.mts.map is excluded by !**/*.map
  • packages/algolia-fragmenter/lib/projection.mjs.map is excluded by !**/*.map
  • packages/algolia-fragmenter/lib/records.d.mts.map is excluded by !**/*.map
  • packages/algolia-fragmenter/lib/records.mjs.map is excluded by !**/*.map
Files selected for processing: 13

  • .nx/version-plans/version-plan-1793863387142.md
  • packages/algolia-fragmenter/README.md
  • packages/algolia-fragmenter/lib/index.d.mts
  • packages/algolia-fragmenter/lib/policy.d.mts
  • packages/algolia-fragmenter/lib/policy.mjs
  • packages/algolia-fragmenter/lib/projection.d.mts
  • packages/algolia-fragmenter/lib/projection.mjs
  • packages/algolia-fragmenter/lib/records.mjs
  • packages/algolia-fragmenter/src/index.mts
  • packages/algolia-fragmenter/src/policy.mts
  • packages/algolia-fragmenter/src/projection.mts
  • packages/algolia-fragmenter/src/records.mts
  • packages/algolia-fragmenter/test/create-algolia-records.test.mts

Included review availability: This review used your included allowance. 0 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 2 reviews per hour.

Independent review flagged that the version plan and README claimed existing consumers were unaffected while the release also reserves `contentId` and `contentType` as protected names, so a configuration that aliased a projection or ranking field to either name starts failing validation after the upgrade. Both now state the contract change and tell affected consumers to rename the alias before upgrading.
@aileen
aileen merged commit 7e06cb4 into main Nov 5, 2026
14 checks passed
@aileen
aileen deleted the aileen/fragmenter-content-identity branch November 5, 2026 08:12
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.

1 participant