Skip to content

fix(taxonomy): match sections by their subsections, and count what we list - #144

Merged
ssavutu merged 1 commit into
mainfrom
fix/taxonomy-section-matching
Aug 1, 2026
Merged

fix(taxonomy): match sections by their subsections, and count what we list#144
ssavutu merged 1 commit into
mainfrom
fix/taxonomy-section-matching

Conversation

@ssavutu

@ssavutu ssavutu commented Aug 1, 2026

Copy link
Copy Markdown
Member

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 LIKE on the section slug alone, and ANDed 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 category Special Editions; its articles live under Welcome Week and 100 Year Anniversary. So:

  • /v1/sections/special-editions/articles0 articles
  • /v1/sections/special-editions/articles?subsection_slug=welcome-week0, the intersection of a real category with one that does not exist, while 30 articles sat under Welcome Week

news/politics and entertainment/music only worked by luck: those parent slugs happen to occur in category text.

2. Counts disagreed with listings. RebuildTaxonomyArticleCounts used a third definition — exact equality on CanonicalizeSlug(category). Arts & Entertainment canonicalizes to arts-entertainment, which never equalled the entertainment slug, 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.

  • A section matches itself OR any of its subsections.
  • A subsection matches only itself, instead of being ANDed with its parent. A subsection can only narrow a section, so intersecting the two could never add anything.
  • Counts are derived from the same matcher over the same published, non-archived population, so article_count is 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

before after
special-editions listing 0 60
welcome-week subsection 0 30
entertainment count 8 2602 (= its listing)
comics 221 293

Testing

go build, go vet and the full go test ./... suite pass. New unit tests cover the pattern expansion (comics-puzzlesComics & 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

… 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>
@ssavutu
ssavutu merged commit 2403322 into main Aug 1, 2026
6 checks passed
@ssavutu
ssavutu deleted the fix/taxonomy-section-matching branch August 1, 2026 22:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant