fix(kg): report a note's tags and give a nameless note a label - #2631
Merged
Conversation
Two things a note record failed to say about itself. Tags. The notes table has no tags column, so a caller's tags are stored under properties.tags, and the tag filter matches with a JSON extract on that path. A note returned from create, get or list therefore reported no tags at all while being findable by them, which reads as "this note has no tags" rather than "this projection does not look there". The shared note projection now lifts the stored array to the top level. Only an array is lifted, and an explicit top-level value wins, so a substrate that does carry its own tags is never overwritten. Name. A note's name is optional and nothing defaults it, so a listing keyed on name renders blank rows for notes carrying full paragraphs. The projection now emits display_name: the name when there is one, the first non-empty line of content otherwise, trimmed and capped. The stored name is untouched. Deriving a value into the name column would destroy the difference between a note someone titled and one nobody did, and that difference is real. Tests cover the arms that separate this from a plausible wrong version: a non-array properties.tags is not promoted, an explicit top-level tags wins, a whitespace-only name still derives, whitespace-only content yields no label rather than an empty one, and a long line is capped and marked.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two things a note record failed to say about itself, both on the read path, no schema change and no backfill.
Tags. The notes table has no tags column. A caller's tags are stored under
properties.tags, and the tag filter matches with a JSON extract on that same path. So a note returned from create, get or list reported no tags at all while being perfectly findable by them. A reader cannot tell that apart from a note that genuinely has none, and the workaround, readingproperties.tagsyourself, is exactly the detail the projection exists to hide.The shared note projection now lifts the stored array to the top level. Only an array is lifted, because promoting a string would hand callers a
tagsfield they still have to type-check, and an explicit top-level value wins, so a substrate that does carry its own tags is never overwritten by this.Name. A note's name is optional and nothing defaults it, so a listing keyed on
namerenders blank rows for notes carrying full paragraphs. The projection now emitsdisplay_name: the name when there is one, the first non-empty line of content otherwise, trimmed and capped at 120 characters with an ellipsis.The stored
nameis deliberately untouched. Deriving a value into that column would destroy the difference between a note someone titled and one nobody did, and that difference is real: it is the difference between a title and a first sentence. A label is a view; a name is a record.Tests. Each arm separates this from a plausible wrong implementation. A non-array
properties.tagsis not promoted. An explicit top-leveltagswins over the stored one. A whitespace-only name still derives, so an implementation testing only for null fails. Whitespace-only content yields no label rather than an empty one. A long line is capped and marked, and thenamefield is asserted still null in the same test, so an implementation that writes the derived label intonamefails.