Claude: changes for issue #164 #168

Merged
Grandiras merged 1 commit from claude/issue-164 into main 2026-08-26 21:55:14 +00:00
Collaborator

Closes #164.

Closes #164.
Search the discussion as well as the card
All checks were successful
CI / build (pull_request) Successful in 32s
66cd7d601e
A decision that was only ever written down in a comment thread was not
findable. On a board whose descriptions are one-liners and whose argument
happens underneath them, that is most of the content.

The comments are a sixth SearchField, weighted 0.7 — below the description,
because a thread is longer than everything else on a card put together and a
word turns up in one by accident more often. They come from a second query and
never a third Include on Card, which is the cartesian blow-up the board read is
written to avoid; it projects two columns a comment and runs each thread into
one string. That query is started beside the card read rather than after it —
both are mostly decryption, on two connections and two threads.

Measured on a CI container, cold snapshot, median of 25:

  120 cards /    600 comments:  33 ms →  50 ms
  720 cards /  3,600 comments: 119 ms → 157 ms
  720 cards / 14,400 comments: 126 ms → 272 ms

Paid once, on the search that builds the snapshot; a later keystroke went from
~2.0 ms to ~3.0 ms at 720 cards, which the 160 ms debounce swallows. Sequential
rather than concurrent, the last two rows were 267 ms and 358 ms. The lazy
fallback the issue offered as an alternative — titles first, comments only when
nothing came back — was rejected: a card whose whole thread is about the word
would stay invisible *because* something else matched, so which cards a search
can reach would depend on what else it found.

A hit found that way says so, three words in the meta line: the row shows a
title and a line of the description, and without the marker a result holding
none of what was typed reads as the search having gone wrong.

Closes #164
Author
Collaborator

🤖 Reviewing this PR — follow along in the action run; the reply will link the full session transcript.

📜 Live transcript — updating every ~5 minutes while the task runs.

🤖 Reviewing this PR — follow along in [the action run](https://git.grandiras.net/Grandiras/claude-bot/actions/runs/393); the reply will link the full session transcript. <!-- claude-run:pr_review --> 📜 [Live transcript](https://git.grandiras.net/Grandiras/claude-bot/src/branch/claude-logs/transcripts/Grandiras/Ponente/pr-168/run-393.md) — updating every ~5 minutes while the task runs.
claude-reviewer left a comment

This adds comment/discussion indexing to search: a sixth SearchField at weight 0.7 (below description), a parallel DiscussionsAsync query run alongside the card read via Task.WhenAll (each on its own DbContext/connection, so no EF concurrency issue), an InComments flag on SearchHit that surfaces as a marker in the result row, and matching docs, changelog, and tests.

Verified end to end:

  • Comment.Card → Card.BoardColumn.BoardId navigation used in DiscussionsAsync's Where matches the actual entity model, and it reuses the same boardIds (already permission-filtered by BoardService.GetVisibleAsync) as the card query — no access-control gap.
  • SearchField enum order (Title, Tags, People, Place, Description, Comments) matches the new Weights array [3.0, 2.0, 1.6, 1.2, 1.0, 0.7], and the field loop scans in that order so > (strict) comparison correctly makes ties resolve to the earlier/higher-weighted field, matching the documented "ties go to the earlier field" behavior.
  • WhenAll before the two separate awaits is correct and matches the comment's stated reasoning (avoids an unobserved exception if the card query fails first).
  • The discussion string is built as one newline-joined haystack per card via a single ordered pass over (CardId, CreatedAt)-sorted comments — grouping logic is correct, and missing/no-comment cards fall back to `

Emitted as JSON this job could not parse, so it is not line-anchored; the raw object follows.

{"verdict": "approve", "summary": "This adds comment/discussion indexing to search: a sixth `SearchField` at weight 0.7 (below description), a parallel `DiscussionsAsync` query run alongside the card read via `Task.WhenAll` (each on its own `DbContext`/connection, so no EF concurrency issue), an `InComments` flag on `SearchHit` that surfaces as a marker in the result row, and matching docs, changelog, and tests.\n\nVerified end to end:\n- `Comment.Card` → `Card.BoardColumn.BoardId` navigation used in `DiscussionsAsync`'s `Where` matches the actual entity model, and it reuses the same `boardIds` (already permission-filtered by `BoardService.GetVisibleAsync`) as the card query — no access-control gap.\n- `SearchField` enum order (Title, Tags, People, Place, Description, Comments) matches the new `Weights` array `[3.0, 2.0, 1.6, 1.2, 1.0, 0.7]`, and the field loop scans in that order so `>` (strict) comparison correctly makes ties resolve to the earlier/higher-weighted field, matching the documented \"ties go to the earlier field\" behavior.\n- `WhenAll` before the two separate `await`s is correct and matches the comment's stated reasoning (avoids an unobserved exception if the card query fails first).\n- The discussion string is built as one newline-joined haystack per card via a single ordered pass over `(CardId, CreatedAt)`-sorted comments — grouping logic is correct, and missing/no-comment cards fall back to `""` via `TryGetValue`.\n- New unit tests (`CardSearchTests`) and the e2e additions (`comment-form`, `modal-close`, `comment-body`, `nav-search-hit-comment` selectors, and the `comments.submit` button text \"Comment\") all match real markup/locale strings in the repo — nothing in the test relies on non-existent selectors.\n- Docs (`data.md`, `search.md`) were updated in the same PR to describe the new second query, its measured cost, and the ranking rationale, consistent with the CLAUDE.md requirement to keep docs in sync.\n\nNo correctness, security, or omission issues found. This is a clean, well-documented implementation."}

⏱ 1m 13s · 13 turns · tokens: 48.7k in / 6.2k out (+611.7k cache-read)
📜 Full session transcript

This adds comment/discussion indexing to search: a sixth `SearchField` at weight 0.7 (below description), a parallel `DiscussionsAsync` query run alongside the card read via `Task.WhenAll` (each on its own `DbContext`/connection, so no EF concurrency issue), an `InComments` flag on `SearchHit` that surfaces as a marker in the result row, and matching docs, changelog, and tests. Verified end to end: - `Comment.Card` → `Card.BoardColumn.BoardId` navigation used in `DiscussionsAsync`'s `Where` matches the actual entity model, and it reuses the same `boardIds` (already permission-filtered by `BoardService.GetVisibleAsync`) as the card query — no access-control gap. - `SearchField` enum order (Title, Tags, People, Place, Description, Comments) matches the new `Weights` array `[3.0, 2.0, 1.6, 1.2, 1.0, 0.7]`, and the field loop scans in that order so `>` (strict) comparison correctly makes ties resolve to the earlier/higher-weighted field, matching the documented "ties go to the earlier field" behavior. - `WhenAll` before the two separate `await`s is correct and matches the comment's stated reasoning (avoids an unobserved exception if the card query fails first). - The discussion string is built as one newline-joined haystack per card via a single ordered pass over `(CardId, CreatedAt)`-sorted comments — grouping logic is correct, and missing/no-comment cards fall back to ` _Emitted as JSON this job could not parse, so it is not line-anchored; the raw object follows._ ```json {"verdict": "approve", "summary": "This adds comment/discussion indexing to search: a sixth `SearchField` at weight 0.7 (below description), a parallel `DiscussionsAsync` query run alongside the card read via `Task.WhenAll` (each on its own `DbContext`/connection, so no EF concurrency issue), an `InComments` flag on `SearchHit` that surfaces as a marker in the result row, and matching docs, changelog, and tests.\n\nVerified end to end:\n- `Comment.Card` → `Card.BoardColumn.BoardId` navigation used in `DiscussionsAsync`'s `Where` matches the actual entity model, and it reuses the same `boardIds` (already permission-filtered by `BoardService.GetVisibleAsync`) as the card query — no access-control gap.\n- `SearchField` enum order (Title, Tags, People, Place, Description, Comments) matches the new `Weights` array `[3.0, 2.0, 1.6, 1.2, 1.0, 0.7]`, and the field loop scans in that order so `>` (strict) comparison correctly makes ties resolve to the earlier/higher-weighted field, matching the documented \"ties go to the earlier field\" behavior.\n- `WhenAll` before the two separate `await`s is correct and matches the comment's stated reasoning (avoids an unobserved exception if the card query fails first).\n- The discussion string is built as one newline-joined haystack per card via a single ordered pass over `(CardId, CreatedAt)`-sorted comments — grouping logic is correct, and missing/no-comment cards fall back to `""` via `TryGetValue`.\n- New unit tests (`CardSearchTests`) and the e2e additions (`comment-form`, `modal-close`, `comment-body`, `nav-search-hit-comment` selectors, and the `comments.submit` button text \"Comment\") all match real markup/locale strings in the repo — nothing in the test relies on non-existent selectors.\n- Docs (`data.md`, `search.md`) were updated in the same PR to describe the new second query, its measured cost, and the ranking rationale, consistent with the CLAUDE.md requirement to keep docs in sync.\n\nNo correctness, security, or omission issues found. This is a clean, well-documented implementation."} ``` --- ⏱ 1m 13s · 13 turns · tokens: 48.7k in / 6.2k out (+611.7k cache-read) 📜 [Full session transcript](https://git.grandiras.net/Grandiras/claude-bot/src/branch/claude-logs/transcripts/Grandiras/Ponente/pr-168/run-393.md) <!-- claude-reviewed-head:66cd7d601ea4b9cb78fc40cb3087ca758cf8f602 -->
Author
Collaborator

🔧 Let Claude fix this — tick the box and claude-bot picks up the review above, on this PR branch. Nothing runs until you do.

  • @claude-bot Address the findings of the latest review on this pull request.
🔧 **Let Claude fix this** — tick the box and claude-bot picks up the review above, on this PR branch. Nothing runs until you do. - [ ] @claude-bot Address the findings of the latest review on this pull request. <!-- claude-fix-button:168 -->
Grandiras deleted branch claude/issue-164 2026-08-26 21:55:14 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Grandiras/Ponente!168
No description provided.