Skip to content

ENG-1291: Port discourse node specification#765

Merged
sid597 merged 4 commits intoeng-1280-discourse-node-query-builder-and-specification-setting-v2from
eng-1291-port-discourse-node-specificationv1
Feb 24, 2026
Merged

ENG-1291: Port discourse node specification#765
sid597 merged 4 commits intoeng-1280-discourse-node-query-builder-and-specification-setting-v2from
eng-1291-port-discourse-node-specificationv1

Conversation

@sid597
Copy link
Collaborator

@sid597 sid597 commented Feb 11, 2026

https://www.loom.com/share/ec0987fd82474127ad994237104f9b9e


Open with Devin

Summary by CodeRabbit

  • Refactor
    • Enhanced query settings interface with improved flag-based controls for managing query specifications
    • Reorganized settings data structure to support explicit enable/disable states and clearer configuration options

@linear
Copy link

linear bot commented Feb 11, 2026

@sid597
Copy link
Collaborator Author

sid597 commented Feb 11, 2026

@coderabbitai full review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 11, 2026

✅ Actions performed

Full review triggered.

devin-ai-integration[bot]

This comment was marked as resolved.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 11, 2026

📝 Walkthrough

Walkthrough

A settingKey prop is added to query components (QueryBuilder, QueryEditor) to specify which settings object path to use ("index" or "specification"). The zod schema is restructured so that specification changes from an array to an object with an enabled flag and nested query object. DiscourseNodeSpecification component is refactored to use DiscourseNodeFlagPanel and manages block creation/removal for enable/disable state.

Changes

Cohort / File(s) Summary
Component Props Threading
apps/roam/src/components/QueryBuilder.tsx, apps/roam/src/components/QueryEditor.tsx
Added optional settingKey prop ("index" | "specification") threaded through components. QueryEditor uses settingKey to determine dynamic path for syncing settings via setDiscourseNodeSetting and guards effect with settingKey presence.
Settings Schema Restructure
apps/roam/src/components/settings/utils/zodSchema.ts, apps/roam/src/components/settings/utils/zodSchema.example.ts
Changed DiscourseNodeSchema.specification from array to object with enabled flag and nested query structure. Added returnNode field to IndexSchema. Updated default transformations to match new nested shape.
Component Implementation Updates
apps/roam/src/components/settings/DiscourseNodeIndex.tsx, apps/roam/src/components/settings/DiscourseNodeSpecification.tsx
DiscourseNodeIndex passes settingKey="index" to QueryBuilder and initializes settings with custom and returnNode. DiscourseNodeSpecification replaces Checkbox-based UI with DiscourseNodeFlagPanel, adds block creation/removal logic for enable/disable, and passes settingKey="specification" to nested components.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'ENG-1291: Port discourse node specification' directly describes the main change: porting (implementing/migrating) the discourse node specification feature.
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.

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


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.

❤️ Share

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

Copy link
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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/roam/src/components/QueryEditor.tsx (1)

491-518: ⚠️ Potential issue | 🔴 Critical

Critical bug confirmed: returnNode is excluded from the sync payload, causing it to be reset to "" whenever conditions/selections/custom change.

The stripped object (line 494–498) contains only { conditions, selections, custom }. When IndexSchema.safeParse validates it, the missing returnNode field defaults to "" (per the schema definition at zodSchema.ts:56). This overrides the returnNode initially set by:

  • DiscourseNodeIndex.tsx (line 53: returnNode: DEFAULT_RETURN_NODE)
  • DiscourseNodeSpecification.tsx (line 77: returnNode: node.text)

The overwrite occurs ~250ms after mount when the sync effect fires on any change to conditions, selections, or custom.

Since returnNode is not stored as state in QueryEditor (only extracted once from parseQuery result but not destructured), there is no way to persist it through subsequent syncs. Include returnNode in the state and sync payload to fix this.

🧹 Nitpick comments (3)
apps/roam/src/components/settings/utils/zodSchema.ts (1)

106-113: Consider extracting the default specification value to avoid duplication with IndexSchema defaults.

Line 113 manually spells out the full default for query ({ conditions: [], selections: [], custom: "", returnNode: "" }), which duplicates the defaults already declared in IndexSchema (lines 53–57). If IndexSchema gains a new field with a default, this transform will silently become stale.

♻️ Suggested refactor
+const DEFAULT_SPECIFICATION = {
+  enabled: false,
+  query: { conditions: [], selections: [], custom: "", returnNode: "" },
+} as const;
+
 export const DiscourseNodeSchema = z.object({
   ...
   specification: z
     .object({
       enabled: z.boolean().default(false),
       query: IndexSchema.default({}),
     })
     .nullable()
     .optional()
-    .transform((val) => val ?? { enabled: false, query: { conditions: [], selections: [], custom: "", returnNode: "" } }),
+    .transform((val) => val ?? DEFAULT_SPECIFICATION),

This keeps the default in one place and shortens the line.

apps/roam/src/components/settings/DiscourseNodeSpecification.tsx (2)

96-111: Potential race: disable path deletes scratch children then resets block props — ensure ordering is safe.

Lines 99–107 delete all scratch children, then in .then() reset the block props. This ordering is fine for the happy path. However, if the user rapidly toggles enabled → disabled → enabled, the effect on line 32 will fire for both states. The cleanup function (lines 112–114) only calls refreshConfigTree() and doesn't cancel the in-flight Promise.all or createBlock chains, so interleaved create/delete operations could leave inconsistent state.

Consider adding a cancelled flag or using an AbortController pattern in the effect to avoid races on rapid toggles.


119-121: CSS overrides to hide the query button and restyle the checkbox are fine but fragile.

These selectors (.bp3-button.bp3-intent-primary, .bp3-checkbox, .bp3-control-indicator) are tied to BlueprintJS 3 class names. Consider adding a brief comment explaining why these overrides are needed, so future maintainers don't accidentally remove them.

@sid597 sid597 requested a review from mdroidian February 15, 2026 17:10
@sid597 sid597 force-pushed the eng-1280-discourse-node-query-builder-and-specification-setting-v2 branch from 898a0bd to adab8d8 Compare February 15, 2026 18:24
@sid597 sid597 force-pushed the eng-1291-port-discourse-node-specificationv1 branch from 1c7af7a to 6bed1ba Compare February 15, 2026 18:24
devin-ai-integration[bot]

This comment was marked as resolved.

Copy link
Contributor

@mdroidian mdroidian left a comment

Choose a reason for hiding this comment

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

Image

@sid597 sid597 force-pushed the eng-1280-discourse-node-query-builder-and-specification-setting-v2 branch from adab8d8 to cc9fd40 Compare February 16, 2026 08:25
@sid597 sid597 force-pushed the eng-1291-port-discourse-node-specificationv1 branch from 6bed1ba to 39d97bf Compare February 16, 2026 08:25
@sid597 sid597 force-pushed the eng-1280-discourse-node-query-builder-and-specification-setting-v2 branch from cc9fd40 to 3be01d4 Compare February 17, 2026 05:16
@sid597 sid597 force-pushed the eng-1291-port-discourse-node-specificationv1 branch from 39d97bf to 09f158c Compare February 17, 2026 05:16
@sid597 sid597 force-pushed the eng-1291-port-discourse-node-specificationv1 branch from 09f158c to 7b96a6d Compare February 17, 2026 15:07
@sid597 sid597 force-pushed the eng-1280-discourse-node-query-builder-and-specification-setting-v2 branch 2 times, most recently from 72de51b to 28d44a4 Compare February 17, 2026 15:37
@sid597 sid597 force-pushed the eng-1291-port-discourse-node-specificationv1 branch 2 times, most recently from 7a25648 to fde2738 Compare February 17, 2026 16:04
@sid597 sid597 force-pushed the eng-1280-discourse-node-query-builder-and-specification-setting-v2 branch from 28d44a4 to 5a3bbba Compare February 17, 2026 16:04
@sid597 sid597 changed the base branch from graphite-base/765 to eng-1280-discourse-node-query-builder-and-specification-setting-v2 February 23, 2026 10:27
devin-ai-integration[bot]

This comment was marked as resolved.

@sid597 sid597 deleted the branch eng-1280-discourse-node-query-builder-and-specification-setting-v2 February 23, 2026 10:41
@sid597 sid597 closed this Feb 23, 2026
@sid597 sid597 deleted the eng-1291-port-discourse-node-specificationv1 branch February 23, 2026 10:42
@sid597 sid597 restored the eng-1291-port-discourse-node-specificationv1 branch February 23, 2026 11:00
@sid597 sid597 reopened this Feb 23, 2026
@supabase
Copy link

supabase bot commented Feb 23, 2026

This pull request has been ignored for the connected project zytfjzqyijgagqxrzbmz because there are no changes detected in packages/database/supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@sid597 sid597 force-pushed the eng-1280-discourse-node-query-builder-and-specification-setting-v2 branch from ff23661 to c704afc Compare February 23, 2026 13:51
@sid597 sid597 force-pushed the eng-1291-port-discourse-node-specificationv1 branch from 7a086b1 to 433277c Compare February 23, 2026 13:51
@sid597 sid597 requested a review from mdroidian February 23, 2026 13:55
@sid597 sid597 force-pushed the eng-1291-port-discourse-node-specificationv1 branch from 433277c to af25640 Compare February 23, 2026 16:40
const existingProps = getBlockProps(uid);
if (!existingProps || Object.keys(existingProps).length === 0) {
// TODO: Overwriting on safeParse failure is a temporary fix for schema shape changes
// (e.g. specification: [] -> {enabled, query}). Replace with proper versioned migrations.
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need this already if this is our first version? As in, we don't have any other versions/migrations?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

we already have merged code in main that would have created the previous specification structure in graphs that have main version of roam plugin and so we need to migrate for those graphs.

hideCustomSwitch,
showAlias,
discourseNodeType,
settingKey, // eslint-disable-line react/prop-types
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need to resort to this disable? What did you try to properly fix it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

not under scope of this pr every other key also has the same problem and in multiple places in the codebase

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

fixing it properly would result in more touch points and get out of scope for this pr

@sid597 sid597 force-pushed the eng-1280-discourse-node-query-builder-and-specification-setting-v2 branch from 3678893 to 89a82ea Compare February 24, 2026 05:46
@sid597 sid597 force-pushed the eng-1291-port-discourse-node-specificationv1 branch from af25640 to b08670d Compare February 24, 2026 05:46
@sid597 sid597 force-pushed the eng-1291-port-discourse-node-specificationv1 branch from b08670d to 6ad633e Compare February 24, 2026 05:48
@sid597 sid597 force-pushed the eng-1280-discourse-node-query-builder-and-specification-setting-v2 branch from 89a82ea to 33c45e6 Compare February 24, 2026 05:48
@sid597 sid597 merged commit d9c0d00 into eng-1280-discourse-node-query-builder-and-specification-setting-v2 Feb 24, 2026
13 checks passed
sid597 added a commit that referenced this pull request Feb 24, 2026
  These PRs were squash-merged into parent branches instead of main
  due to a Graphite stack merge race condition. Their changes never
  landed on main despite showing as merged in Graphite.

  Includes:
  - #764 ENG-1280: Port query builder/editor for block props
  - #765 ENG-1291: Port discourse node specification (dual-write)
  - #769 ENG-1290: Port discourse node config panel
  - #793 ENG-1440: Port page groups settings in suggestive mode
  - #794 ENG-1438: Port keyboard shortcut keys/triggers
  - #805 ENG-1328: Port small blueprint misc settings
sid597 added a commit that referenced this pull request Feb 24, 2026
  specification, config panel)

  The initial recovery commit claimed to include these but only
  contained
  Chain 2 (#793, #794, #805, #804). Chain 1 lives on separate
  branches
  that weren't in the merge source.

  Applied using `gh pr diff` for each PR in order (#764#765#769).
  init.ts required manual merge — #765 and #769 both modified it
  from the
  same base. Kept #765's safeParse checks inside #769's
  restructured
  initializeSettingsBlockProps.

  - #764 ENG-1280: Port query builder and editor component for
  block props
  - #765 ENG-1291: Port discourse node specification
  - #769 ENG-1290: Port discourse node config panel
sid597 added a commit that referenced this pull request Feb 25, 2026
…#826)

* Land orphaned Graphite stack PRs (#764, #765, #769, #793, #794, #805)

  These PRs were squash-merged into parent branches instead of main
  due to a Graphite stack merge race condition. Their changes never
  landed on main despite showing as merged in Graphite.

  Includes:
  - #764 ENG-1280: Port query builder/editor for block props
  - #765 ENG-1291: Port discourse node specification (dual-write)
  - #769 ENG-1290: Port discourse node config panel
  - #793 ENG-1440: Port page groups settings in suggestive mode
  - #794 ENG-1438: Port keyboard shortcut keys/triggers
  - #805 ENG-1328: Port small blueprint misc settings

* Add #804 ENG-1217: Port section component in left sidebar

* Add #764, #765, #769 (Chain 1 orphaned PRs: query builder,
  specification, config panel)

  The initial recovery commit claimed to include these but only
  contained
  Chain 2 (#793, #794, #805, #804). Chain 1 lives on separate
  branches
  that weren't in the merge source.

  Applied using `gh pr diff` for each PR in order (#764#765#769).
  init.ts required manual merge — #765 and #769 both modified it
  from the
  same base. Kept #765's safeParse checks inside #769's
  restructured
  initializeSettingsBlockProps.

  - #764 ENG-1280: Port query builder and editor component for
  block props
  - #765 ENG-1291: Port discourse node specification
  - #769 ENG-1290: Port discourse node config panel

* fix lint

* prettier
sid597 added a commit that referenced this pull request Feb 25, 2026
  These PRs were squash-merged into parent branches instead of main
  due to a Graphite stack merge race condition. Their changes never
  landed on main despite showing as merged in Graphite.

  Includes:
  - #764 ENG-1280: Port query builder/editor for block props
  - #765 ENG-1291: Port discourse node specification (dual-write)
  - #769 ENG-1290: Port discourse node config panel
  - #793 ENG-1440: Port page groups settings in suggestive mode
  - #794 ENG-1438: Port keyboard shortcut keys/triggers
  - #805 ENG-1328: Port small blueprint misc settings
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