Skip to content

ENG-1856 Store source identity metadata for Roam imported nodes#1218

Open
sid597 wants to merge 27 commits into
mainfrom
eng-1856-store-source-identity-metadata-for-roam-imported-nodes-v2
Open

ENG-1856 Store source identity metadata for Roam imported nodes#1218
sid597 wants to merge 27 commits into
mainfrom
eng-1856-store-source-identity-metadata-for-roam-imported-nodes-v2

Conversation

@sid597

@sid597 sid597 commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • store Roam imported-node provenance under discourse-graph.importedFrom
  • use sourceNodeRid as the canonical cross-app identity and keep sourceModifiedAt as refresh state
  • add consistent read, write, bulk lookup, and single-node lookup helpers
  • route Roam shared-node discovery through the shared bulk lookup helper
  • preserve sibling block props when imported metadata is written or refreshed

Why

Roam needs a stable way to recognize an imported shared node after its page title or content changes. Matching by display title would make duplicate prevention and refresh dependent on presentation and namespace decisions.

Obsidian already uses importedFromRid as the canonical imported identity and stores the imported source timestamp as lastModified. This implementation follows the same boundary in Roam:

  • sourceNodeRid is the identity
  • sourceModifiedAt is refresh state
  • source app, source space, and source-local ID are not duplicated because they are encoded by the RID
  • source title is not persisted as identity

This supersedes the closed v1 PR, #1161, and addresses its review feedback about the redundant six-field identity shape.

Implementation

The metadata is stored in page/block props rather than page content:

{
  "discourse-graph": {
    importedFrom: {
      sourceNodeRid,
      sourceModifiedAt,
    },
  },
}

Writing merges the existing discourse-graph object so unrelated metadata, including relation migration state, survives. Content replacement during import or refresh does not touch these block props.

The helper exposes:

  • parsing and reading imported source metadata
  • writing updated source metadata
  • collecting all imported source RIDs for discovery duplicate prevention
  • finding an imported local node UID by canonical source RID

Dependency

This PR is intentionally stacked on ENG-2019 / #1216, which is itself stacked on ENG-1855. ENG-1855 introduced the Roam discovery consumer and ENG-2019 extracted the cross-space listing logic while leaving already-imported detection app-side.

Once #1216 merges, this PR can be retargeted to main without changing the ENG-1856 implementation diff.

Validation

  • pnpm --filter roam test -- src/utils/__tests__/importedSourceIdentity.test.ts src/utils/__tests__/discoverSharedNodes.test.ts
    • 11 test files passed
    • 51 tests passed
  • pnpm --filter roam check-types
  • targeted ESLint for the changed files
  • Prettier
  • git diff --check

The local shell reports Node 20 while the repository declares Node 22+, but all checks above completed successfully.

sid597 added 8 commits July 10, 2026 11:51
Roam's command palette runs commands on Enter keyup, which landed as a
click on the dialog's autofocused close button and dismissed it
instantly. Disable autoFocus/enforceFocus like AdvancedSearchDialog and
restore outside-click close.

Also from review: use Tailwind classes instead of inline styles, drop
the unused ValidSharedSpace.id field, and unexport the file-internal
getImportedSourceRids.
Replaces the hand-rolled paging loop with the existing
@repo/database/lib/pagination helper, matching how
syncDgNodesToSupabase already reads ResourceAccess.
@linear-code

linear-code Bot commented Jul 10, 2026

Copy link
Copy Markdown

ENG-1856

@vercel

vercel Bot commented Jul 10, 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 Jul 24, 2026 4:16pm

Request Review

@supabase

supabase Bot commented Jul 10, 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 ↗︎.

@sid597

sid597 commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator Author

@codex review

@sid597
sid597 marked this pull request as ready for review July 10, 2026 17:37

@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

@sid597
sid597 force-pushed the eng-1856-store-source-identity-metadata-for-roam-imported-nodes-v2 branch from 39dc8cb to 9b7eaf7 Compare July 21, 2026 08:59
…ry loop

Remove the isRid(source_local_id) short-circuit — source_local_id is never a RID in current Roam/Obsidian flows, so rid is always derived via spaceUriAndLocalIdToRid; drop the RID-preservation test that asserted it.

Flatten the per-space discovery loop into a single chunked pass over deduped source_local_ids. buildSharedNodes already narrows by the composite (spaceId, sourceLocalId) key, so no per-space DB query is needed.
sid597 added 3 commits July 23, 2026 23:24
Per maparent (review on sharedNodes.ts:311/316): drop getGroupSharedResources and the chunked .in("source_local_id") lookup. my_concepts/my_contents already fold ResourceAccess into their RLS via my_accessible_resources(), so query the views directly with .neq("space_id", currentSpaceId). This makes the resources/sharedResourceKeys filter in buildSharedNodes redundant, so it and the two unit tests pinning it are removed.
Per mdroidian (sharedNodes.ts:92): the input is the shared node instances, so name it nodes. Row type stays SharedConcept; the CrossAppNode contract migration is deferred to the next project per the same comment.
@sid597
sid597 force-pushed the eng-1856-store-source-identity-metadata-for-roam-imported-nodes-v2 branch from 9b7eaf7 to 9eb8f9f Compare July 24, 2026 09:06
sid597 added 2 commits July 24, 2026 21:44
…ia contract alias, drop duplicate warn, validate query result
…-identity-metadata-for-roam-imported-nodes-v2

# Conflicts:
#	apps/roam/src/utils/discoverSharedNodes.ts
@sid597
sid597 changed the base branch from eng-2019-extract-shared-cross-space-node-discovery-into to main July 24, 2026 16:15
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