Skip to content

[ENG-1861] Add Roam refresh-all for imported nodes - #1286

Open
sid597 wants to merge 4 commits into
eng-1860-add-roam-manual-refresh-for-imported-nodesfrom
eng-1861-add-roam-refresh-all-for-imported-nodes
Open

[ENG-1861] Add Roam refresh-all for imported nodes#1286
sid597 wants to merge 4 commits into
eng-1860-add-roam-manual-refresh-for-imported-nodesfrom
eng-1861-add-roam-refresh-all-for-imported-nodes

Conversation

@sid597

@sid597 sid597 commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Adds a DG: Refresh all imported nodes command palette command (gated on node sharing, like the other sharing entry points) that refreshes every imported node with stored source identity and reports the outcome in a toast: N refreshed, N skipped, N failed.

Each node goes through the ENG-1860 single-node refresh path, so one failure doesn't abort the batch. To let the batch tally the three outcomes, refreshImportedNode now returns status: "refreshed" | "skipped" | "failed" instead of a boolean success, and takes a force option. The batch passes force: false so up-to-date imports are skipped instead of rewritten — that's where the skipped count comes from. The title button keeps force: true (default): an explicit click on one node still overwrites local edits even when the source is unchanged, per ENG-1860's behavior.

Nodes are fetched one at a time via getSharedNodeByRid rather than one bulk list because the ticket asks to reuse the single-node refresh path, and imported-node counts are small. Failure reporting is intentionally counts-only (each failure is still logged via internalError); actionable per-node reporting is ENG-1877.

The second commit fixes an adjacent violation of "imported nodes must not be synced": full sync selects nodes by title format + edit time only, so an imported page whose title matches a local node format was uploaded to Supabase as this space's own content, embeddings, and concepts — and import/refresh touching those pages re-triggered it. The fix filters pages with stored importedFrom identity out of the sync's node selection before the mode split, covering initial and incremental sync in both modes (shared-nodes-only mode was already safe via the shared source-local-id filter). Not covered here: the full-content path keys off explicit grants, which an imported page only enters via the publish title button that today also renders on imported pages — that publish-side exclusion is a separate follow-up.

Stacked on #1279 (ENG-1860).


Open in Devin Review

Add a command palette command that refreshes every imported node with
stored source identity by reusing the single-node refresh path without
force, so up-to-date imports are skipped, and report refreshed,
skipped, and failed counts in a toast.
@linear-code

linear-code Bot commented Aug 10, 2026

Copy link
Copy Markdown

ENG-1861

@vercel

vercel Bot commented Aug 10, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
discourse-graph Skipped Skipped Aug 10, 2026 9:42am

Request Review

@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 found 1 potential issue.

View 1 additional finding in Devin Review.

Open in Devin Review

renderDiscoverSharedNodesDialog({});
};

const refreshAllImportedNodesFromCommand = async () => {

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.

🟡 New command handler omits the required explicit return type

The new batch-refresh command handler is declared without an explicit return type (const refreshAllImportedNodesFromCommand = async () => { at apps/roam/src/utils/registerCommandPaletteCommands.ts:353), which the repository style guide requires for all functions.
Impact: Code style diverges from the repository's mandated TypeScript conventions.

Rule source: AGENTS.md TypeScript Guidelines

AGENTS.md states under TypeScript Guidelines: "Use explicit return types for functions". The other new functions added in this PR (getImportedNodeUids in apps/roam/src/utils/importedSourceIdentity.ts:77 and refreshAllImportedNodes in apps/roam/src/utils/refreshAllImportedNodes.ts:10-11) do declare them, so this one is inconsistent as well.

Suggested change
const refreshAllImportedNodesFromCommand = async () => {
const refreshAllImportedNodesFromCommand = async (): Promise<void> => {
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@supabase

supabase Bot commented Aug 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 ↗︎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1fcf370564

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if (isNodeSharingEnabled()) {
void addCommand(
"DG: Refresh all imported nodes",
() => void refreshAllImportedNodesFromCommand(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Prevent overlapping refresh-all runs

If this command is invoked twice quickly—or overlaps with the page-title refresh button—both asynchronous runs can refresh the same imported page concurrently because the callback is fire-and-forget and there is no shared in-flight guard. Both calls can observe the old source identity, and updateImportedPage can then have each call snapshot the same previous children, append a fresh copy of the source markdown, and delete only that shared snapshot, leaving duplicate imported content. Serialize refreshes per page or reject additional batch invocations until the active run completes.

Useful? React with 👍 / 👎.

Full sync selected nodes by title format and edit time only, so an
imported page whose title matched a local node format was upserted to
Supabase as this space's own content, embeddings, and concepts. Filter
out pages with stored importedFrom identity before the mode split so
both initial and incremental sync skip them; shared-nodes-only mode was
already safe via the shared source-local-id filter.
getImportedNodeUids now returns a Set for membership checks.
@graphite-app

graphite-app Bot commented Aug 10, 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

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