fix(accounts): preserve legacy publication field names#29
fix(accounts): preserve legacy publication field names#29tomcasaburi wants to merge 4 commits intomasterfrom
Conversation
📝 WalkthroughWalkthroughIntroduces normalization/backfill utilities for mapping legacy Changes
Sequence Diagram(s)sequenceDiagram
participant Actions as Accounts Actions
participant Compat as plebbit-compat
participant Plebbit as PlebbitJS Client
participant Store as Local Store/DB
rect rgba(200,200,255,0.5)
Actions->>Compat: normalizePublicationOptionsForPlebbit(options)
Compat-->>Actions: normalizedOptions
end
rect rgba(200,255,200,0.5)
Actions->>Plebbit: createX(normalizedOptions)
Plebbit-->>Actions: createdPublication
end
rect rgba(255,200,200,0.5)
Actions->>Compat: backfillPublicationCommunityAddress(createdPublication, storedOptions)
Compat-->>Actions: backfilledPublication
Actions->>Store: persist(backfilledPublication)
Store-->>Actions: persistedConfirmation
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Comment |
|
Addressed the valid legacy-compat findings in the latest commit. This update (1) keeps communityAddress on locally stored account comments/votes/edits while still remapping wire payloads for legacy plebbit-js, and (2) makes communitiesStore accept legacy createSubplebbit/getSubplebbit clients for create/edit/delete flows. Local verification: yarn build, yarn test, focused accounts/communities store tests, and a full coverage rerun that now reaches the repo's existing 100% hooks/stores baseline failure rather than a regression in this patch. |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/stores/communities/communities-store.test.ts (1)
12-35: Consider reusing one legacy-only plebbit test fixture.This shim overlaps with
LegacyOnlyPlebbitinsrc/stores/accounts/accounts-actions.test.tslines145-197. Keeping two hand-rolled compatibility mocks in sync will get brittle as the mapping rules evolve.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/stores/communities/communities-store.test.ts` around lines 12 - 35, Replace the duplicated in-file shim by reusing the existing legacy-only plebbit fixture instead of redefining createLegacyOnlyAccount/LegacyOnlyPlebbit here: remove the local createLegacyOnlyAccount definition and import the shared fixture (or move it to a shared test-fixtures module if it isn't exported) and update tests to call that imported createLegacyOnlyAccount; ensure the symbol names (createLegacyOnlyAccount / LegacyOnlyPlebbit) are exported from the source module or the shared fixture module so tests can consume the same implementation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/lib/plebbit-compat.ts`:
- Around line 12-15: Replace the broad plebbitSupportsCommunityNaming heuristic
with per-operation detection or an explicit capability flag: stop using
plebbitSupportsCommunityNaming inside normalizePublicationOptionsForPlebbit and
normalizeCommunityEditOptionsForPlebbit and instead detect support for renamed
fields the same way getPlebbitCreateCommunity/getPlebbitGetCommunity do (or read
an explicit capability flag from the plebbit wrapper), then branch per-operation
to choose legacy subplebbit* field names or new community field names when
building publication and community-edit payloads; remove reliance on unrelated
methods like createCommunity/getCommunity/createCommunityEdit for this decision
and ensure each normalization function checks only the specific operation
capability before mutating field names.
---
Nitpick comments:
In `@src/stores/communities/communities-store.test.ts`:
- Around line 12-35: Replace the duplicated in-file shim by reusing the existing
legacy-only plebbit fixture instead of redefining
createLegacyOnlyAccount/LegacyOnlyPlebbit here: remove the local
createLegacyOnlyAccount definition and import the shared fixture (or move it to
a shared test-fixtures module if it isn't exported) and update tests to call
that imported createLegacyOnlyAccount; ensure the symbol names
(createLegacyOnlyAccount / LegacyOnlyPlebbit) are exported from the source
module or the shared fixture module so tests can consume the same
implementation.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: b558892b-4bd5-48da-949b-c51191b2ec5c
📒 Files selected for processing (5)
src/lib/plebbit-compat.tssrc/stores/accounts/accounts-actions.test.tssrc/stores/accounts/accounts-actions.tssrc/stores/communities/communities-store.test.tssrc/stores/communities/communities-store.ts
src/lib/plebbit-compat.ts
Outdated
| const plebbitSupportsCommunityNaming = (plebbit: any) => | ||
| typeof plebbit?.createCommunity === "function" || | ||
| typeof plebbit?.getCommunity === "function" || | ||
| typeof plebbit?.createCommunityEdit === "function"; |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
In @plebbit/plebbit-js, is support for communityAddress/communityEditguaranteed to ship in lockstep with thecreateCommunity/getCommunity/createCommunityEditrenames, or can publication APIs still requiresubplebbit* fields while some community lifecycle methods are already renamed?
💡 Result:
No—there’s no indication that communityAddress / communityEdit is guaranteed to ship in lockstep with any createCommunity / getCommunity / createCommunityEdit renames.
On current @plebbit/plebbit-js master (package version 0.0.11), the public docs and schemas still use subplebbit* terminology:
- The README “Schema” defines
Publication.subplebbitAddress(andSubplebbitEdit, etc.), notcommunityAddress/communityEdit. [1] - The Zod schema for publication creation (
CreatePublicationUserOptionsSchema) still requiressubplebbitAddress. [2]
Also, ongoing rename work is being done piecemeal and can be breaking: Issue #70 proposes renaming publication.subplebbitAddress → subplebbitPublicKey and explicitly calls it a “clean break” with “no backward compatibility shim,” which implies these changes aren’t necessarily coupled to higher-level method naming consistency. [3]
So yes: it’s entirely plausible (and consistent with the repo today) that some “community lifecycle” methods could be renamed while publication APIs still require subplebbit* fields, until the publication schemas are separately updated.
Sources: [1] [2] [3]
Replace the global capability heuristic with per-operation detection or an explicit feature flag.
The plebbitSupportsCommunityNaming helper infers naming conventions by checking for createCommunity, getCommunity, and createCommunityEdit. However, upstream rename work happens piecemeal: community lifecycle methods may be renamed while publication schemas still require subplebbit* fields. This risks publishing payloads with incorrect field names if a plebbit wrapper has partial support for the renamed APIs.
This file already implements per-operation detection elsewhere (e.g., getPlebbitCreateCommunity, getPlebbitGetCommunity). Use the same pattern for normalizePublicationOptionsForPlebbit and normalizeCommunityEditOptionsForPlebbit (lines 27–44 and 58–74), or rely on an explicit capability flag from the upstream library instead of inferring from unrelated methods.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/lib/plebbit-compat.ts` around lines 12 - 15, Replace the broad
plebbitSupportsCommunityNaming heuristic with per-operation detection or an
explicit capability flag: stop using plebbitSupportsCommunityNaming inside
normalizePublicationOptionsForPlebbit and
normalizeCommunityEditOptionsForPlebbit and instead detect support for renamed
fields the same way getPlebbitCreateCommunity/getPlebbitGetCommunity do (or read
an explicit capability flag from the plebbit wrapper), then branch per-operation
to choose legacy subplebbit* field names or new community field names when
building publication and community-edit payloads; remove reliance on unrelated
methods like createCommunity/getCommunity/createCommunityEdit for this decision
and ensure each normalization function checks only the specific operation
capability before mutating field names.
|
Addressed the substantive review findings in commit f1fe98d. This follow-up keeps legacy publication and community-edit wire payloads on subplebbit fields, but backfills returned publication and comment objects plus the internal update paths so stored account comments, votes, and edits still preserve the repo’s internal communityAddress shape. Local verification after this commit: yarn build, yarn test, focused accounts-actions, accounts-actions-internal, and hooks/accounts suites. yarn test:coverage:hooks-stores still reports the repo’s existing 100 percent baseline gaps outside this review fix. The remaining bot note about reusing a shared legacy-only test fixture is a non-blocking maintainability nit, not a correctness issue. |
|
Addressed the substantive review findings in . This follow-up keeps legacy publication/community-edit wire payloads on , but backfills returned publication/comment objects and internal update paths so stored account comments/votes/edits still preserve the repo’s internal shape. Local verification after this commit: yarn run v1.22.22 RUN v4.0.18 /Users/Tommaso/Desktop/bitsocial/bitsocial-react-hooks/src ✓ stores/accounts/accounts-store.test.ts (6 tests) 542ms Test Files 35 passed (35) JSON report written to /Users/Tommaso/Desktop/bitsocial/bitsocial-react-hooks/src/.vitest-reports/tests.json RUN v4.0.18 /Users/Tommaso/Desktop/bitsocial/bitsocial-react-hooks/src ✓ stores/accounts/accounts-store.test.ts (6 tests) 550ms Test Files 35 passed (35) JSON report written to /Users/Tommaso/Desktop/bitsocial/bitsocial-react-hooks/src/.vitest-reports/tests.json |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/lib/plebbit-compat.ts`:
- Around line 75-90: The helper backfillPublicationCommunityAddress incorrectly
returns early when publication.subplebbitAddress exists, skipping normalization;
fix by changing the early-return condition in
backfillPublicationCommunityAddress to only return if publication is falsy or
publication.communityAddress is already present (remove the
publication.subplebbitAddress check), then continue to compute communityAddress
from options?.communityAddress ?? options?.subplebbitAddress and assign
publication.communityAddress = communityAddress when it’s missing so legacy
subplebbitAddress entries get normalized.
In `@src/stores/accounts/accounts-actions.test.ts`:
- Around line 199-238: The partial-rename mock created by
createLegacyPublicationSchemaPlebbitMock is missing an override for
publishCommunityEdit (and/or createCommunityEdit/createSubplebbitEdit if those
are the actual method names used) so tests don't assert that
communityAddress/communityEdit are stripped; update the
LegacyPublicationSchemaPlebbit class to add an async publishCommunityEdit(opts:
any) method that throws if "communityAddress" or "communityEdit" (or
"communityEdit" and "communityAddress" as appropriate) exist in opts and
otherwise calls super.publishCommunityEdit(opts), and ensure the factory
createLegacyPublicationSchemaPlebbit still returns the instance and preserves
getShortAddress/getShortCid from PlebbitJsMock.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 9672a89e-2bdf-4be5-95c6-fae9a2a2d114
📒 Files selected for processing (5)
src/lib/plebbit-compat.tssrc/stores/accounts/accounts-actions-internal.test.tssrc/stores/accounts/accounts-actions-internal.tssrc/stores/accounts/accounts-actions.test.tssrc/stores/accounts/accounts-actions.ts
| function createLegacyPublicationSchemaPlebbitMock() { | ||
| class LegacyPublicationSchemaPlebbit extends BasePlebbit { | ||
| async createComment(opts: any) { | ||
| if ("communityAddress" in opts) { | ||
| throw new Error("createComment received communityAddress"); | ||
| } | ||
| return super.createComment(opts); | ||
| } | ||
|
|
||
| async createVote(opts: any) { | ||
| if ("communityAddress" in opts) { | ||
| throw new Error("createVote received communityAddress"); | ||
| } | ||
| return super.createVote(opts); | ||
| } | ||
|
|
||
| async createCommentEdit(opts: any) { | ||
| if ("communityAddress" in opts) { | ||
| throw new Error("createCommentEdit received communityAddress"); | ||
| } | ||
| if ("communityEdit" in opts) { | ||
| throw new Error("createCommentEdit received communityEdit"); | ||
| } | ||
| return super.createCommentEdit(opts); | ||
| } | ||
|
|
||
| async createCommentModeration(opts: any) { | ||
| if ("communityAddress" in opts) { | ||
| throw new Error("createCommentModeration received communityAddress"); | ||
| } | ||
| return super.createCommentModeration(opts); | ||
| } | ||
| } | ||
|
|
||
| const createLegacyPublicationSchemaPlebbit: any = async (...args: any[]) => | ||
| new LegacyPublicationSchemaPlebbit(...args); | ||
| createLegacyPublicationSchemaPlebbit.getShortAddress = PlebbitJsMock.getShortAddress; | ||
| createLegacyPublicationSchemaPlebbit.getShortCid = PlebbitJsMock.getShortCid; | ||
| return createLegacyPublicationSchemaPlebbit; | ||
| } |
There was a problem hiding this comment.
Cover publishCommunityEdit() in the partial-rename mock too.
This mock still inherits the default createCommunityEdit/createSubplebbitEdit behavior, so the suite below never proves that remote community edits were normalized away from communityAddress/communityEdit. A regression in normalizeCommunityEditOptionsForPlebbit() would still let Lines 971-977 pass.
Suggested test hardening
class LegacyPublicationSchemaPlebbit extends BasePlebbit {
async createComment(opts: any) {
if ("communityAddress" in opts) {
throw new Error("createComment received communityAddress");
}
return super.createComment(opts);
}
@@
async createCommentModeration(opts: any) {
if ("communityAddress" in opts) {
throw new Error("createCommentModeration received communityAddress");
}
return super.createCommentModeration(opts);
}
+
+ async createCommunityEdit(opts: any) {
+ if ("communityAddress" in opts) {
+ throw new Error("createCommunityEdit received communityAddress");
+ }
+ if ("communityEdit" in opts) {
+ throw new Error("createCommunityEdit received communityEdit");
+ }
+ return super.createCommunityEdit(opts);
+ }
+
+ async createSubplebbitEdit(opts: any) {
+ if ("communityAddress" in opts) {
+ throw new Error("createSubplebbitEdit received communityAddress");
+ }
+ if ("communityEdit" in opts) {
+ throw new Error("createSubplebbitEdit received communityEdit");
+ }
+ return super.createSubplebbitEdit(opts);
+ }
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| function createLegacyPublicationSchemaPlebbitMock() { | |
| class LegacyPublicationSchemaPlebbit extends BasePlebbit { | |
| async createComment(opts: any) { | |
| if ("communityAddress" in opts) { | |
| throw new Error("createComment received communityAddress"); | |
| } | |
| return super.createComment(opts); | |
| } | |
| async createVote(opts: any) { | |
| if ("communityAddress" in opts) { | |
| throw new Error("createVote received communityAddress"); | |
| } | |
| return super.createVote(opts); | |
| } | |
| async createCommentEdit(opts: any) { | |
| if ("communityAddress" in opts) { | |
| throw new Error("createCommentEdit received communityAddress"); | |
| } | |
| if ("communityEdit" in opts) { | |
| throw new Error("createCommentEdit received communityEdit"); | |
| } | |
| return super.createCommentEdit(opts); | |
| } | |
| async createCommentModeration(opts: any) { | |
| if ("communityAddress" in opts) { | |
| throw new Error("createCommentModeration received communityAddress"); | |
| } | |
| return super.createCommentModeration(opts); | |
| } | |
| } | |
| const createLegacyPublicationSchemaPlebbit: any = async (...args: any[]) => | |
| new LegacyPublicationSchemaPlebbit(...args); | |
| createLegacyPublicationSchemaPlebbit.getShortAddress = PlebbitJsMock.getShortAddress; | |
| createLegacyPublicationSchemaPlebbit.getShortCid = PlebbitJsMock.getShortCid; | |
| return createLegacyPublicationSchemaPlebbit; | |
| } | |
| function createLegacyPublicationSchemaPlebbitMock() { | |
| class LegacyPublicationSchemaPlebbit extends BasePlebbit { | |
| async createComment(opts: any) { | |
| if ("communityAddress" in opts) { | |
| throw new Error("createComment received communityAddress"); | |
| } | |
| return super.createComment(opts); | |
| } | |
| async createVote(opts: any) { | |
| if ("communityAddress" in opts) { | |
| throw new Error("createVote received communityAddress"); | |
| } | |
| return super.createVote(opts); | |
| } | |
| async createCommentEdit(opts: any) { | |
| if ("communityAddress" in opts) { | |
| throw new Error("createCommentEdit received communityAddress"); | |
| } | |
| if ("communityEdit" in opts) { | |
| throw new Error("createCommentEdit received communityEdit"); | |
| } | |
| return super.createCommentEdit(opts); | |
| } | |
| async createCommentModeration(opts: any) { | |
| if ("communityAddress" in opts) { | |
| throw new Error("createCommentModeration received communityAddress"); | |
| } | |
| return super.createCommentModeration(opts); | |
| } | |
| async createCommunityEdit(opts: any) { | |
| if ("communityAddress" in opts) { | |
| throw new Error("createCommunityEdit received communityAddress"); | |
| } | |
| if ("communityEdit" in opts) { | |
| throw new Error("createCommunityEdit received communityEdit"); | |
| } | |
| return super.createCommunityEdit(opts); | |
| } | |
| async createSubplebbitEdit(opts: any) { | |
| if ("communityAddress" in opts) { | |
| throw new Error("createSubplebbitEdit received communityAddress"); | |
| } | |
| if ("communityEdit" in opts) { | |
| throw new Error("createSubplebbitEdit received communityEdit"); | |
| } | |
| return super.createSubplebbitEdit(opts); | |
| } | |
| } | |
| const createLegacyPublicationSchemaPlebbit: any = async (...args: any[]) => | |
| new LegacyPublicationSchemaPlebbit(...args); | |
| createLegacyPublicationSchemaPlebbit.getShortAddress = PlebbitJsMock.getShortAddress; | |
| createLegacyPublicationSchemaPlebbit.getShortCid = PlebbitJsMock.getShortCid; | |
| return createLegacyPublicationSchemaPlebbit; | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/stores/accounts/accounts-actions.test.ts` around lines 199 - 238, The
partial-rename mock created by createLegacyPublicationSchemaPlebbitMock is
missing an override for publishCommunityEdit (and/or
createCommunityEdit/createSubplebbitEdit if those are the actual method names
used) so tests don't assert that communityAddress/communityEdit are stripped;
update the LegacyPublicationSchemaPlebbit class to add an async
publishCommunityEdit(opts: any) method that throws if "communityAddress" or
"communityEdit" (or "communityEdit" and "communityAddress" as appropriate) exist
in opts and otherwise calls super.publishCommunityEdit(opts), and ensure the
factory createLegacyPublicationSchemaPlebbit still returns the instance and
preserves getShortAddress/getShortCid from PlebbitJsMock.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/lib/plebbit-compat.ts (1)
75-90:⚠️ Potential issue | 🟠 MajorPrefer the returned publication’s legacy address when backfilling.
This still misses legacy responses where the only address lives on
publication.subplebbitAddress. That matters for flows likepublishCommunityEdit(address, opts), where the address can be passed separately andoptionsmay not carrycommunityAddress/subplebbitAddressat all. In that casecommunityAddressstays unset even though the returned publication already has the legacy field.Suggested fix
export const backfillPublicationCommunityAddress = < T extends Record<string, any> | undefined, O extends Record<string, any> | undefined, >( publication: T, options: O, ): T => { - const communityAddress = options?.communityAddress ?? options?.subplebbitAddress; if (!publication || publication.communityAddress) { return publication; } + const communityAddress = + publication.subplebbitAddress ?? options?.communityAddress ?? options?.subplebbitAddress; if (!communityAddress) { return publication; } publication.communityAddress = communityAddress; return publication; };🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/lib/plebbit-compat.ts` around lines 75 - 90, backfillPublicationCommunityAddress currently only uses options (communityAddress or subplebbitAddress) to backfill publication.communityAddress and misses cases where the returned publication already carries a legacy address in publication.subplebbitAddress; update the function so that if publication.communityAddress is unset you first derive communityAddress from options as now, but if that is falsy, fall back to publication.subplebbitAddress and assign that to publication.communityAddress; reference the function name backfillPublicationCommunityAddress and the symbol publication.subplebbitAddress when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/stores/accounts/accounts-actions.test.ts`:
- Around line 182-190: The community-edit test mocks (notably the
createSubplebbitEdit method which currently only throws on incoming
communityAddress/communityEdit and then calls
BasePlebbit.prototype.createCommunityEdit) must be updated to also return the
legacy shape that includes subplebbitAddress so the backfill path
backfillPublicationCommunityAddress used by publishCommunityEdit is exercised;
modify the mock(s) used around createSubplebbitEdit (and the analogous mocks
referenced at the 234-241 region) to sometimes return a legacy object with
subplebbitAddress (in addition to asserting rejection of inbound community*
fields), ensuring publishCommunityEdit triggers the
backfillPublicationCommunityAddress branch in tests.
---
Duplicate comments:
In `@src/lib/plebbit-compat.ts`:
- Around line 75-90: backfillPublicationCommunityAddress currently only uses
options (communityAddress or subplebbitAddress) to backfill
publication.communityAddress and misses cases where the returned publication
already carries a legacy address in publication.subplebbitAddress; update the
function so that if publication.communityAddress is unset you first derive
communityAddress from options as now, but if that is falsy, fall back to
publication.subplebbitAddress and assign that to publication.communityAddress;
reference the function name backfillPublicationCommunityAddress and the symbol
publication.subplebbitAddress when making the change.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: f09e2b65-4fa1-408a-8cde-4056b608e60a
📒 Files selected for processing (2)
src/lib/plebbit-compat.tssrc/stores/accounts/accounts-actions.test.ts
| async createSubplebbitEdit(opts: any) { | ||
| if ("communityAddress" in opts) { | ||
| throw new Error("legacy createSubplebbitEdit received communityAddress"); | ||
| } | ||
| if ("communityEdit" in opts) { | ||
| throw new Error("legacy createSubplebbitEdit received communityEdit"); | ||
| } | ||
| return BasePlebbit.prototype.createCommunityEdit.call(this, opts); | ||
| } |
There was a problem hiding this comment.
The community-edit mocks still don’t exercise the legacy return-shape backfill.
Unlike createComment() on Lines 205-207, these community-edit mocks only reject inbound community* fields; they never return a legacy object with subplebbitAddress. That means the suites below prove outbound normalization, but they still don’t cover the new backfillPublicationCommunityAddress() path for publishCommunityEdit(). A regression there would keep passing.
As per coding guidelines, src/stores/**/*.{ts,tsx} must "Maintain mandatory 100% test coverage for hooks and stores; every feature or bug fix must include/adjust tests to keep coverage at 100%, verified via node scripts/verify-hooks-stores-coverage.mjs."
Also applies to: 234-241
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/stores/accounts/accounts-actions.test.ts` around lines 182 - 190, The
community-edit test mocks (notably the createSubplebbitEdit method which
currently only throws on incoming communityAddress/communityEdit and then calls
BasePlebbit.prototype.createCommunityEdit) must be updated to also return the
legacy shape that includes subplebbitAddress so the backfill path
backfillPublicationCommunityAddress used by publishCommunityEdit is exercised;
modify the mock(s) used around createSubplebbitEdit (and the analogous mocks
referenced at the 234-241 region) to sometimes return a legacy object with
subplebbitAddress (in addition to asserting rejection of inbound community*
fields), ensuring publishCommunityEdit triggers the
backfillPublicationCommunityAddress branch in tests.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| const commentWithCid = comment; | ||
| const commentWithCid = addShortAddressesToAccountComment( | ||
| normalizeCommentCommunityAddress(comment) as any, | ||
| ); |
There was a problem hiding this comment.
Stored comments inconsistently retain subplebbitAddress after verification
Medium Severity
The challenge-verification and update-handler paths use normalizeCommentCommunityAddress to normalize stored comments, but that function only adds communityAddress without removing subplebbitAddress. In contrast, the initial store path at line 653 uses normalizePublicationOptionsForStore, which properly deletes subplebbitAddress. When a plebbit-js implementation sets subplebbitAddress on returned Comment objects (as LegacyPublicationSchemaPlebbit does), stored comments gain both fields after challenge verification or update events, contradicting the store's communityAddress-only convention.


Summary
Fix the publication compatibility layer so legacy plebbit-js instances still receive fields while newer implementations keep the renamed API.
Verification
Note
Medium Risk
Touches core publishing flows (comment/vote/edit/moderation/community edit) by rewriting payload field names and how data is stored, which could cause subtle regressions in publish/update behavior across different plebbit-js versions. Changes are compatibility-focused and covered by new legacy/mixed-version tests, reducing but not eliminating risk.
Overview
Improves plebbit-js compatibility by normalizing community field names differently for the wire vs local storage. Publication payloads sent to plebbit-js are now converted to legacy
subplebbit*fields (andcommunity*removed), while stored account data is normalized back tocommunityAddress(and legacy fields removed).Updates account publishing and comment-update flows to backfill
communityAddressonto returned publications when older plebbit-js objects only exposesubplebbitAddress, and ensures updated comments are normalized before adding short-address metadata. Community lifecycle operations now accept legacy-only plebbit instances by checking forcreateSubplebbit*methods.Adds tests covering legacy-only and mixed-schema plebbit-js implementations to ensure publish actions and community create/edit/delete work and that stored state consistently uses
communityAddresswithout leaking legacy fields.Written by Cursor Bugbot for commit 3feea56. This will update automatically on new commits. Configure here.
Summary by CodeRabbit
New Features
Bug Fixes
Tests