Skip to content

[ENG-1849] Persist Roam node type schema labels#1131

Merged
sid597 merged 4 commits into
mainfrom
eng-1849-sync-roam-node-type-schema-metadata-for-shared-nodes
Jun 24, 2026
Merged

[ENG-1849] Persist Roam node type schema labels#1131
sid597 merged 4 commits into
mainfrom
eng-1849-sync-roam-node-type-schema-metadata-for-shared-nodes

Conversation

@sid597

@sid597 sid597 commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator

Summary

Re-scopes ENG-1849 against the final merged ENG-1847 contract baseline.

The old fixture-based patch was built on a draft ENG-1847 artifact that no longer exists on main. Final ENG-1847 intentionally keeps the public surface to @repo/database/crossAppNodeContract and @repo/database/lib/rid, with typed examples only and no exported DB fixture API.

This PR now updates the actual Roam producer path instead: discourseNodeSchemaToLocalConcept always persists literal_content.label for node-type schema Concepts, including node types with no template. When a template exists, the existing literal_content.template behavior is preserved.

Why this is the ENG-1849 fix

Roam already syncs node-type schema Concepts through the existing sync loop:

  • schema Concepts use stable source_local_id = node.type
  • schema Concepts are persisted with is_schema: true
  • node instances still reference their schema via schema_represented_by_local_id
  • dependency ordering already upserts schemas before instances

The remaining gap was that literal_content.label was only written when node.template !== undefined. Template-less node types, especially via the new settings store where empty templates become undefined, could sync without an explicit label field. ENG-1849 requires stable source identity plus label/name metadata for downstream mapping, so the label now becomes unconditional.

Out of scope

  • No shared contract expansion
  • No recreated packages/database/src/fixtures/crossAppNodes.ts
  • No destination-side schema mapping/materialization
  • No relation schema or relation instance behavior

Validation

  • pnpm --filter @repo/database check-types
  • pnpm --filter roam exec eslint src/utils/conceptConversion.ts
  • git diff --check origin/main...HEAD

Full pnpm --filter roam check-types is currently blocked by unrelated merged-main Roam API typing errors in src/utils/discourseNodeSearchProviders.ts (semanticSearchEnabled / semanticSearch), not by this diff.

sid597 added 2 commits June 18, 2026 14:35
The cross-app node contract (ENG-1847) carries nodeType = { sourceLocalId, label } and the instance Concept references it via schema_represented_by_local_id, but the fixtures persisted no is_schema:true schema Concept for that id. Add the required schemaConcept (Roam Claim, Obsidian Evidence) carrying stable source identity + label only -- no source_data/format/color/tag, per the contract's "without redefining schema shape".

Roam's existing 5-min sync already persists the schema Concept per contract (convertDgToSupabaseConcepts -> discourseNodeSchemaToLocalConcept; all types on initial sync, edited types incrementally via nodeTypeSince), so no Roam sync code change is needed for F4/F9/F13. Stacked on eng-1847 (PR #1129, unmerged).
@linear-code

linear-code Bot commented Jun 19, 2026

Copy link
Copy Markdown

ENG-1849

@supabase

supabase Bot commented Jun 19, 2026

Copy link
Copy Markdown

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 ↗︎.

@vercel

vercel Bot commented Jun 19, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
discourse-graph Ready Ready Preview, Comment Jun 21, 2026 9:09pm

Request Review

@sid597

sid597 commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

CrossAppNodeFixture gains a schemaConcept: LocalConceptDataInput field. Both exported fixtures (roamOriginNode and obsidianOriginNode) are updated to populate this field with schema-concept metadata (is_schema: true, source_local_id, literal_content, timestamps).

Changes

CrossAppNodeFixture schemaConcept extension

Layer / File(s) Summary
Type contract and fixture data
packages/database/src/fixtures/crossAppNodes.ts
CrossAppNodeFixture gains schemaConcept: LocalConceptDataInput; roamOriginNode populates it for a Claim schema concept and obsidianOriginNode populates it for an Evidence schema concept, each with is_schema: true, source_local_id, literal_content, and timestamps.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Possibly related PRs

  • DiscourseGraphs/discourse-graph#220: Introduces conversion utilities that produce LocalConceptDataInput for node/relation schema data, directly matching the type now added to CrossAppNodeFixture.
  • DiscourseGraphs/discourse-graph#720: Constructs LocalConceptDataInput for node schemas (e.g., discourseNodeSchemaToLocalConcept) with ISO timestamps and literal_content, the same shape now populated in both fixtures.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title references a specific feature (persisting Roam node type schema labels) that aligns with the PR's core objective of adding schemaConcept field to cross-app node fixtures to complete the node contract, though it slightly emphasizes Roam when the changes affect both Roam and Obsidian fixtures equally.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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.

sid597 added 2 commits June 22, 2026 02:34
…de-type-schema-metadata-for-shared-nodes

# Conflicts:
#	packages/database/package.json
#	packages/database/src/crossAppNodeContract.ts
#	packages/database/src/lib/rid.ts
@graphite-app

graphite-app Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

PR size/scope check

This PR is over our review-size guideline.

  • Recommended: ~200 lines changed
  • Acceptable limit: up to 400 lines when well-scoped/self-contained
  • Preferred file count: fewer than 5 files

Please split this into smaller PRs unless there is a clear reason the changes need to land together.

If keeping it as one PR, please add a brief justification covering:

  • What single problem this PR solves
  • Why the files/changes are coupled

@sid597 sid597 changed the title [ENG-1849] Add node-type schema dependency to cross-app node fixtures [ENG-1849] Persist Roam node type schema labels Jun 21, 2026
@sid597 sid597 changed the base branch from eng-1847-define-shared-cross-app-node-content-contract to main June 21, 2026 21:09
node: DiscourseNode,
): LocalConceptDataInput => {
const titleParts = node.text.split("/");
const label = titleParts[titleParts.length - 1] ?? node.text;

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Before a template-less node types could have name, but not the explicit literal_content.label field.

@sid597 sid597 requested review from maparent and mdroidian June 23, 2026 10:21
@sid597 sid597 merged commit 06aeae4 into main Jun 24, 2026
12 checks passed
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.

3 participants