ENG-1301: Import relations when a node is imported#847
ENG-1301: Import relations when a node is imported#847trangdoan982 wants to merge 16 commits intomainfrom
Conversation
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
maparent
left a comment
There was a problem hiding this comment.
Some of this we'll look at together. Let's plan a joint session.
a03a9e9 to
da9c498
Compare
da9c498 to
7a86600
Compare
| .from("my_concepts") | ||
| .select("id, source_local_id") | ||
| .in("id", [sourceSchemaId, destSchemaId]); | ||
| if (schemaRows && schemaRows.length === 2) { |
There was a problem hiding this comment.
🔴 length === 2 check silently skips triple creation for self-referencing or same-schema relations
In importRelationsForImportedNodes, the check conceptSchemas.length === 2 at line 287 fails when sourceData.id === destData.id (a self-referencing relation where both endpoints are the same concept), because .in('id', [X, X]) with duplicate IDs returns only 1 row. Similarly, schemaRows.length === 2 at line 300 fails when sourceSchemaId === destSchemaId (both endpoints share the same node type schema). This silently skips the findOrCreateTriple call, meaning no discourse relation triple is created in settings for these relations. The codebase explicitly supports self-referencing relations — see apps/obsidian/src/components/canvas/utils/relationJsonUtils.ts:91 which handles relation.sourceId === relation.destinationId.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Interesting; I am not sure we want to support that but we don't exclude it yet.
| @@ -0,0 +1,176 @@ | |||
| /** | |||
There was a problem hiding this comment.
this script is mostly for my local testing to create group quickly. i've been using it for a while and it doesn't touch any part of the codebase but happy to delete it as well
|
@maparent here are some big changes since the last time you reviewed:
Cases I tested:
|
maparent
left a comment
There was a problem hiding this comment.
Ok. Of my comments, two are real code change requests, and after that I'll approve.
Otherwise, thanks for all the great work with optimizations, and I like how you handled fallbacks within the QueryEngine.
I did some testing, that seems to work great.
In terms of behaviour... I'm actually not sure why we need the preview mode in most cases. We're asking people to confirm a choice they just made. There is one good reason: when we import a schema, because it has unfortunate consequences: We cannot edit or remove it. (Also unhappy with that.)
SO two recommendation:
- Make handling imported schemas a very high priority after this is merged.
- Could we skip the validation screen when there is no schema import?
The latter is a design decision, and may need to be validated with Joel, Johnny and/or Michael. So not sure we should block merge on it. But I think it's worth asking: I really don't see the point of that validation step if there's no schema change.
| .from("my_concepts") | ||
| .select("id, source_local_id") | ||
| .in("id", [sourceSchemaId, destSchemaId]); | ||
| if (schemaRows && schemaRows.length === 2) { |
There was a problem hiding this comment.
Interesting; I am not sure we want to support that but we don't exclude it yet.
| // Batch fetch schema_id for all endpoint concepts | ||
| const conceptIdToSchemaId = new Map<number, number>(); | ||
| if (allEndpointConceptIds.length > 0) { | ||
| const { data: conceptSchemas } = await client |
There was a problem hiding this comment.
I think that's right but checking: allConceptEndpointIds should be larger than selectedNotes, right?
I had a doubt because of the filter for local+imported nodes in L195.
(Otherwise I'd think about whether we could get the data for this by adding id to the select at line 86... but almost certainly overkill.)
There was a problem hiding this comment.
yes it should >= selectedNodes. you want to add the check here instead of >0 check?
|
|
||
| // Check if this triplet already exists in discourseRelations | ||
| // We need to check using the mapped local ids (match by id first, then by name) | ||
| const resolveLocalNodeTypeId = ( |
There was a problem hiding this comment.
Not vital, since not hitting the db, but I'd have cached this, it's still a search per instance. Oh well.
There was a problem hiding this comment.
not sure what you mean here?
|
I'm having second thoughts. I agreed, and I think it was the right call, that imported schemata should not be edited in the short term. But I think that schemata (imported or not) should be delete-able, as long as they have no live instances. Again, this would do much to mitigate the consequences of importation. We'd need buy-on on that, and I'm willing to help to code it, but I think that importing un-delete-able schemata is a design mistake. |
| const { mapNodeTypeIdToLocal } = await import("./importNodes.js"); | ||
| mappedSourceNodeTypeId = await mapNodeTypeIdToLocal({ | ||
| plugin, | ||
| client, | ||
| sourceSpaceId: spaceId, | ||
| sourceSpaceUri: spaceUri, | ||
| sourceNodeTypeId: remoteSourceNodeTypeId, | ||
| }); | ||
| mappedDestNodeTypeId = await mapNodeTypeIdToLocal({ | ||
| plugin, | ||
| client, | ||
| sourceSpaceId: spaceId, | ||
| sourceSpaceUri: spaceUri, | ||
| sourceNodeTypeId: remoteDestNodeTypeId, | ||
| }); | ||
| } |
There was a problem hiding this comment.
Incorrect Import Statement Inside Loop
The dynamic import statement is executed inside the relation processing loop:
const { mapNodeTypeIdToLocal } = await import("./importNodes.js");This will attempt to import the module on every iteration, which is inefficient and could cause issues. The import should be moved outside the function at the top of the file:
import { mapNodeTypeIdToLocal } from "./importNodes.js";Or if circular dependency is a concern, import it once before the loop starts.
| const { mapNodeTypeIdToLocal } = await import("./importNodes.js"); | |
| mappedSourceNodeTypeId = await mapNodeTypeIdToLocal({ | |
| plugin, | |
| client, | |
| sourceSpaceId: spaceId, | |
| sourceSpaceUri: spaceUri, | |
| sourceNodeTypeId: remoteSourceNodeTypeId, | |
| }); | |
| mappedDestNodeTypeId = await mapNodeTypeIdToLocal({ | |
| plugin, | |
| client, | |
| sourceSpaceId: spaceId, | |
| sourceSpaceUri: spaceUri, | |
| sourceNodeTypeId: remoteDestNodeTypeId, | |
| }); | |
| } | |
| mappedSourceNodeTypeId = await mapNodeTypeIdToLocal({ | |
| plugin, | |
| client, | |
| sourceSpaceId: spaceId, | |
| sourceSpaceUri: spaceUri, | |
| sourceNodeTypeId: remoteSourceNodeTypeId, | |
| }); | |
| mappedDestNodeTypeId = await mapNodeTypeIdToLocal({ | |
| plugin, | |
| client, | |
| sourceSpaceId: spaceId, | |
| sourceSpaceUri: spaceUri, | |
| sourceNodeTypeId: remoteDestNodeTypeId, | |
| }); | |
| } |
Spotted by Graphite
Is this helpful? React 👍 or 👎 to let us know.
There was a problem hiding this comment.
Actually this is worth fixing!
|
I approved but the checks are all failing. More annoying, the validate check passes locally, and the error message is obviously wrong. |
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
3bc25c4 to
3479f98
Compare
|
The build error was fixed by rebasing on main. It seems the CI does its own flawed rebasing. |
|
Ok still approved but do address the graphite comment, and the lint issue. |
|
yes thank you |


https://www.loom.com/share/407aff42d138483d9c59e20d55a24aec
https://www.loom.com/share/f299d265128d4fe4b79db9c7542e7fcb