fix(taxonomy): match sections by their subsections, and count what we list - #144
Merged
Conversation
… list Section pages resolved articles with a LIKE on the section slug alone, and ANDed a subsection with its parent. Both assume the section slug appears in the WordPress category text, which is not true for a container section: nothing is filed under "Special Editions", its articles live under "Welcome Week" and "100 Year Anniversary". So /special-editions listed 0 articles, and /special-editions?subsection_slug=welcome-week listed 0 as well -- the intersection of a real category with one that does not exist -- while 30 articles sat under Welcome Week. A section now matches itself OR any of its subsections, and a subsection matches only itself instead of being ANDed with its parent. A subsection can only ever narrow a section, so intersecting the two could never add anything. Counting had a third, separate definition: exact equality on CanonicalizeSlug(category). That let a section list 2545 articles while reporting 8, since "Arts & Entertainment" canonicalizes to arts-entertainment and never equalled the entertainment slug. Counts are now derived from the same matcher as the listing, over the same published, non-archived population, so article_count is the total a reader pages through rather than an independent estimate. Against the current corpus: special-editions 0 -> 60, welcome-week 0 -> 30, entertainment count 8 -> 2602, comics 221 -> 293. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
The bug
Two section-page problems that turned out to share one root: section membership had three different definitions in the codebase.
1. Container sections listed nothing. Article filtering did a
LIKEon the section slug alone, andANDed a subsection with its parent. Both assume the section slug appears in the WordPress category text — untrue for a section that is only a container. Nothing is filed under the categorySpecial Editions; its articles live underWelcome Weekand100 Year Anniversary. So:/v1/sections/special-editions/articles→ 0 articles/v1/sections/special-editions/articles?subsection_slug=welcome-week→ 0, the intersection of a real category with one that does not exist, while 30 articles sat under Welcome Weeknews/politicsandentertainment/musiconly worked by luck: those parent slugs happen to occur in category text.2. Counts disagreed with listings.
RebuildTaxonomyArticleCountsused a third definition — exact equality onCanonicalizeSlug(category).Arts & Entertainmentcanonicalizes toarts-entertainment, which never equalled theentertainmentslug, so the section listed 2545 articles while reporting 8.The fix
One matcher,
db.CategoryMatchPatterns, used by both the listing and the count rebuild so they cannot drift apart.ANDed with its parent. A subsection can only narrow a section, so intersecting the two could never add anything.article_countis the total a reader actually pages through.The homepage section blocks resolve their match slugs too, so a homepage block for a container section shows its subsections' articles.
Effect on the current corpus
special-editionslistingwelcome-weeksubsectionentertainmentcountcomicsTesting
go build,go vetand the fullgo test ./...suite pass. New unit tests cover the pattern expansion (comics-puzzles→Comics & Puzzles), the OR-not-AND behaviour, and the empty cases. The SQL the new code generates was also run against the live corpus to produce the numbers above.Note the count rebuild now issues one
COUNT(*)per taxonomy row (35 today) at startup instead of a single scan.🤖 Generated with Claude Code