The board read is a split query, and says so #232
No reviewers
Labels
No labels
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Grandiras/Ponente!232
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "board-read-split-query"
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?
The remark on
CardService.GetColumnsAsyncand the matching rule indocs/data.mdsaid tags and assignees stay "in one query" becauseAsSplitQuerymeasured slower (25 ms against 18 ms). ButProgram.cshas madeSplitQuerythe app-wide default since June, and nothing in the method overrides it. So the documented single-query shape never ran.What actually runs
I counted statements with a
DbCommandInterceptoron a factory registered exactly asProgram.csregisters it.GetColumnsAsyncemits 5 statements: columns, cards, card tags + tag, card assignees + member, then the comment count. That's 724 rows on the documented board. With.AsSingleQuery()it's 2 statements and 600 rows, with identical results.Measured again
Setup: the board
docs/data.mddescribes (4 columns, 120 cards, 2 tags + 2 assignees + 5 comments a card, 780-character descriptions). The app's ownCardServiceran in one container andpostgres:17-alpinein another, on the same podman network (the way production runs them). Figures are medians of 200–300 rounds, variants interleaved in random order.Single query wins by under a millisecond on the exact benchmark shape, and loses as soon as cards carry more tags and assignees or longer text. Its rows grow with tags × assignees; split's grow with tags + assignees. So split stays.
Changes
GetColumnsAsyncnow says.AsSplitQuery()in place, so its shape no longer depends on the global default. That hidden dependency is how the code and the docs came apart. Nothing changes at runtime: same 5 statements, same results.docs/data.md,docs/orientation.md§12, and theProgram.cscomment (which still claimed "four collection navigations") now describe the split behaviour with the new numbers.Card.Comments,SearchServiceanddocs/search.mdrepeated the "four rows a card / cartesian" reasoning, so they're corrected too.docs/data.mdnow explains how to measure this without falling into either trap behind the old numbers:DbContextOptions.pasta, single measured 46 ms against 9 ms even though Postgres ran it in 1.6 ms.No changelog line: members see no difference.
Verification
tools/verify.sh: build clean, 560/560 unit tests pass (includingDocumentationTests).🤖 Generated with Claude Code
🤖 Reviewing this PR — the review will link the full session transcript.
📜 Live transcript — updating every ~5 minutes while the review runs.
✅ Verdict: approve — no blocking issues found.
Good to merge. The one runtime change — an explicit
.AsSplitQuery()onGetColumnsAsync— is a behavioural no-op under the app-wideSplitQuerydefault inProgram.cs, and its value is exactly what the PR says: the query's shape stops depending on a global setting that the docs had silently misdescribed. I verified the split default is indeed registered app-wide, that the documented statement layout (4 split statements plus the separate comment-count query) matches the query structure, and that the corrected "split vs single" and "comments counted, never loaded" reasoning is now consistent acrossCardService,Card.Comments,SearchService,docs/data.md,docs/search.md,docs/orientation.md, and the rewrittenProgram.cscomment. The new methodology section indata.mdhonestly records how the previous 18-vs-25 ms and 2,400-row/~68 ms figures went wrong (harness-built options bypassing the default; rootless published-port timing), which is the right lesson to leave behind. Keeping the rule with correct numbers rather than weakening it is the right call given the measurement table.⏱ 4m 17s · 6 steps · $0.0146 · tokens: 69.8k in / 1.8k out (+36.1k cache-read) · Go: 5h 1% · wk 84% · mo 74%
📜 Full session transcript
🤖 Resolving the merge conflicts — the reply will link the full session transcript.
📜 Live transcript — updating every ~5 minutes while the fix runs.
The merge is complete and clean. Here's the summary:
Merge resolution for #232 (board-read-split-query)
What conflicted: the branch's rewrite of the hot-read docs/comments collided head-on with #229's "debloat" rewrite of the same regions on main — and worse, main's debloated text carried two measured claims the branch's PR disproves (
AsSplitQuery was slower (25 vs 18 ms),~68 → ~18 ms), which would have contradicted the.AsSplitQuery()call the PR adds toGetColumnsAsync.How I resolved it (7 files):
docs/data.md/docs/orientation.md/docs/search.mdstructure, #229's trimmed code comments, and all of #229's functionalCardService/SearchServicechanges (constants,PlaceAt/BottomOfAsync,boardsById, deletedBoardOfCardAsync, etc.)..AsSplitQuery()onGetColumnsAsync, the "it is a split query, and says so in place" rule with the PR's corrected figures (8.9 vs 9.6 ms on the measured board; 14.3 vs 12.3 / 14.1 vs 10.8 off it; 2,400 rows at 35 ms / 7.0 MiB; 11.6 vs 8.8 ms, 3.9 vs 2.4 MiB counted), orientation item 12 ("it is a split query… all three are measured"), and the search page's "split like every query here" clause.DbContextOptionswithout the split default already inProgram.cs, and measuring throughpasta's port forwarding inflates timings — so the corrected numbers and the "how it was measured" note live indocs/data.md, with the in-code comments carrying the terse version.Verified: no conflict markers left;
dotnet build Ponente.slnclean (0 warnings); full unit suite green (558 passed, includingDocumentationTests);.AsSplitQuery()confirmed in the mergedGetColumnsAsync; no stale "25 vs 18" claims outside the historical trap note. The final diff vsmainis exactly the PR's change, now expressed in main's debloated style.→ Merge resolved and pushed; a re-review follows.
⏱ 13m 45s · 48 steps · $0.2075 · tokens: 590.2k in / 32.6k out (+3112.3k cache-read) · Go: 5h 3% · wk 84% · mo 75%
📜 Full session transcript
🤖 On it — the reply will link the full session transcript.
📜 Live transcript — updating every ~5 minutes while the task runs.
No new comment asked anything of me — the thread was quiet. The one new requirement in the follow-up was to verify with the repo's own entry point, so I did that:
task-232-muea4lt1(the session's original directory no longer existed), and it carries the merge resolution as committed:25e2836 Merge remote-tracking branch 'origin/main' into board-read-split-queryonboard-read-split-query, clean tree.tools/verify.sh(defaultcheckmode — build + unit tests in Release, what CI runs): build succeeded, 0 warnings, 558/558 tests passed. This supersedes my earlier hand-rolleddotnet build/dotnet testrun and confirms the same result through the sanctioned entry point.The merge resolution itself is unchanged from my previous reply: main's debloated surfaces kept, the PR's
.AsSplitQuery()and corrected measurements carried through, main's two disproved measurement claims replaced by the trap note indocs/data.md. Nothing further outstanding on #232.⏱ 2m 56s · 60 steps · $0.2754 · tokens: 724.3k in / 33.9k out (+4526.7k cache-read) · Go: 5h 7% · wk 86% · mo 76%
📜 Full session transcript