Add a central search feature to search for a card #159
Labels
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Grandiras/Ponente#159
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Make this semantically aware, so maybe use a simple embedding model and make the DB vector-like. This way, cards can also be found by their context (take title and description into account). Should be a centralized "omni-search", so user-based and cross-board.
Followup-Idea: Use @ to search for cards by a user, date: for date-based search (allow things like date:September), and tag: for tag-based search. Add more if you see fit. Add a simple teaching tip inside the default flyout (so before a search has been performed, but after the search box has been focused. Design it in a way that fits on desktop (on the nav bar in the center) and mobile (separate page? modal? flyout?)
🤖 On it — follow along in the action run; the reply will link the full session transcript.
📜 Live transcript — updating every ~5 minutes while the task runs.
Pushed
claude/issue-159.What it does
One box for every board, in the middle of the header — the magnifier below 960px, and the middle of the phone's bottom bar. Type a word and it finds the card on any board you can see.
Context comes from the card's surroundings. A word is looked for in five places at once — title, tags, the names of the people on it, the board and column it lives in, and the description — and counts wherever it lands. So
urgent deployfinds the card tagged Urgent whose description says time to deploy, with neither word in its title. Half-typed words, typos (encrytpion→ Rotate the encryption key; transpositions cost one edit, not four) and both languages' plurals are handled by the matching rules rather than a stemmer.Four operators, taught in a flyout the moment the box is focused and before anything is typed:
@alicetag:designdate:Septembertoday/tomorrow/week/month/overdue/none, and2027,2027-02,2027-02-14board:RoadmapRepeating one operator widens (
tag:bug tag:urgent= either), two different ones narrow. Both languages' spellings work whichever language is on screen (datum:überfälligon an English page) — operators are syntax, so switching language shouldn't cost you your muscle memory. Month names come out ofLocaleService.Translations, so a third locale brings its own./and Ctrl/⌘-K open it; ↑↓ and Enter walk the results; a result is a real<a>to/board/{id}?card={id}.On a phone it is a full-screen mode rather than a sheet — it covers the bottom bar, which is the card dialog's rule, and pays for that with a way out on screen.
The one thing I did not build
The issue asked for an embedding model and a vector-like DB. I deliberately didn't, and
docs/search.mdcarries the reasoning: every searchable column is AES-encrypted with non-deterministic ciphertext, so there is nothing forpgvectorto index. A plaintext embedding beside a ciphertext column is close enough to the content that it undoes the encryption for the one table anybody would attack; an encrypted one can only be read by decrypting all of it — which is exactly the in-memory passSearchServicealready does, plus ~90 MB of model in the image. What ranking quality that costs is bought back by the five-field matching above. I filed the decision as an issue with the measurement that would change it.SearchServicereads and decrypts the viewer's cards once per search session, scores them against every keystroke after that, and drops the snapshot when the box closes — a plaintext copy of a member's whole board set isn't a thing to hold for the life of a circuit. Two collection includes and no comments, onCardService.GetColumnsAsync's rule.Verified
dotnet buildanddotnet testgreen — 444 tests, 27 new acrossSearchQueryTests/CardSearchTests(operators, both languages' date words, month disambiguation, field weights, fuzzy budgets, umlaut folding).tests/e2e/search.spec.js(2 tests) passes, as dofilter,mobile,board,boards,calendar,changelog,install,prefs,icons. Every query in the table above was executed against a live two-board deployment.board.spec.js"edit a card", two incalendar.spec.js, one inboards.spec.js. All four reproduce with my changes stashed on an untouchedmain, so they are environmental/pre-existing; theboard.spec.jsone I filed, since it fails 2 runs in 6 on a clean tree.docs/search.mdis new and inCLAUDE.md's table, withorientation,ui,frontendandlive-updatesupdated to point at it.One gap I recorded rather than fixed:
design/Ponente.freehas no frame for the search box (Lunacy isn't reachable from CI), so every header in the canvas is now the one without it. That is written intodocs/frontend.md's "still approximate" list.⏱ 58m 23s · 179 turns · tokens: 315.8k in / 119.8k out (+39408.6k cache-read)
📜 Full session transcript
→ Opened PR: #162
→ Filed follow-up issue #163: Search: revisit semantic ranking once the corpus outgrows the in-memory pass
→ Filed follow-up issue #164: Search does not index card comments
→ Filed follow-up issue #165: Flaky e2e: "edit a card, verify changes persist" fails ~1 run in 3 on Escape