ENG-1983 Define intermediate schemas for node, relations and schemas#1183
ENG-1983 Define intermediate schemas for node, relations and schemas#1183maparent wants to merge 1 commit into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
3badfb0 to
4bbf2f8
Compare
4bbf2f8 to
a8bc33d
Compare
a8bc33d to
47202b7
Compare
47202b7 to
66ebc78
Compare
| @@ -0,0 +1,92 @@ | |||
| import type { ContentType } from "@repo/content-model"; | |||
There was a problem hiding this comment.
@maparent
Let's only export types that are being used elsewhere. This adds positive signal and really helps navigate and grok the file.
When we export types that are not used, it adds a false positive and makes it harder to understand intent.
sid597
left a comment
There was a problem hiding this comment.
Some questions and suggestions, I read CrossApp... so many time that now I am confused what it even means lol
| full: { format: contentTypes.markdown, value: roamFullMarkdown }, | ||
| }, | ||
| sourceModifiedAt: "2026-06-12T14:00:00.000Z", | ||
| createdAt: new Date("2026-06-12T14:00:00.000Z"), |
There was a problem hiding this comment.
We removed the modifiedAt? example from both cases. Also why is it optional? I think keeping it optional makes downstream code like roamOriginNodeExmple.modifiedAt? and then dependent on that. We can make the initial modifiedAt same as createdAt iff its not present.
There was a problem hiding this comment.
I could add it back in the example. It's optional precisely for the reason you gave: it uses createdAt if absent.
| sourceApp: "Roam", | ||
| url: ROAM_SOURCE_SPACE_ID, | ||
| }, | ||
| local_id: ROAM_SOURCE_NODE_ID, |
There was a problem hiding this comment.
snake case -> camelCase
What do you think about naming, like appending source vs direct e.g
sourceLocalId, vslocalIdspace.sourceAppvsspace.app
There was a problem hiding this comment.
I have tended to remove source here, because everything was named sourceSomething, and it did not seem to add specific information (as you were remarking about CrossApp!) Maybe I missed something? Fully negotiable.
There was a problem hiding this comment.
+1 to camelCase for TypeScript-facing contract fields
| | { | ||
| localId: string; | ||
| // infer space from context if absent. | ||
| space?: SpaceRef; |
There was a problem hiding this comment.
Is this for future? Can space be absent in Obsidian <-> roam sync?
There was a problem hiding this comment.
This is for the case where we have a reference to a node in another space. It currently happens in Obsidian; the source or destination of a relation may be an imported node, in which case we give the reference to the original node (imported nodes are not materialized again.)
But yes, it can be absent and inferred from context in most cases.
| export type CrossAppRelationTripleSchema = CrossAppBase & { | ||
| label: string; | ||
| reverseLabel: string; | ||
| relation?: Ref | CrossAppRelationTypeSchema; |
There was a problem hiding this comment.
Sorry this is confusing like we already have the label, and reverseLabel is that like source space's version? and this one is for the target's space (or vice-versa)? If so can we name them to reflect that?
There was a problem hiding this comment.
reverseLabel is the label of the reverse relation. So nothing to do with source space or import.
There was a problem hiding this comment.
Ah, and I put it on the triple, which is redundant, because in Roam we don't have the relation as a separate object.
There was a problem hiding this comment.
Let's use complement here instead of reverseLabel
reverseLabel looks new in this PR, while complement is already the repo-wide term for the inverse/reverse relation label in both Roam and Obsidian. For example, Roam relation settings and query logic use label / complement, and Obsidian relation types also store label / complement.
| value: string; | ||
| localId?: string; | ||
| embedding?: CrossAppEmbedding; | ||
| author: CrossAppAccount | Ref; |
There was a problem hiding this comment.
When would author use Ref (specifically LocalRef)?
| }; | ||
|
|
||
| export type CrossAppAccount = { | ||
| account: string; |
There was a problem hiding this comment.
Is this intended to be accountLocalId?
account is ambiguous here: it could mean a display label, platform username, database account id, or the whole account object. Existing DB-facing shapes use account_local_id, and TypeScript-facing code generally uses accountLocalId.
| createdAt: Date; | ||
| modifiedAt?: Date; | ||
| author: CrossAppAccount | Ref; | ||
| contributors?: (CrossAppAccount | Ref)[]; |
There was a problem hiding this comment.
I don't believe contributors is actively used anywhere today, correct? I see the DB tables for it, but I don't see app/converter paths producing or consuming it.
If that's right, I'd prefer we wait to add this to the cross-app contract until we have a concrete use case and are actually wiring it through. Otherwise it adds another field to reason about without a clear behavior
https://linear.app/discourse-graphs/issue/ENG-1983/define-intermediate-schemas-for-node-relations-and-schemas