Finished joins the admin filter vocabulary; four hygiene predicates learn to exclude it #159

Closed
opened 2026-08-22 12:37:29 +07:00 by sulthan · 1 comment
Owner

Part of #136.

Blocked by: #157, #158.

What to build

The finished flag becomes first-class in the admin filter vocabulary, and the four clock-based hygiene predicates stop counting Series the owner deliberately retired. The owner can review every finished Series as a list, and an empty hygiene list is achievable again.

Acceptance criteria

  • A finished filter joins the vocabulary with predicate finished_at > 0, label Finished, its own count in the aggregate, and the zero-renders-the-digit-unlinked rule applied unchanged.
  • The finished figure is ordered last in the stats block as informational rather than fixable — it does not sit among the counts that represent work to do.
  • The stale, never-checked, no-cover and never-read-a-chapter predicates exclude finished Series, so a finished row stops ageing into "not checked in 12h" forever.
  • The unpollable, orphan and sighting-raised predicates deliberately include finished Series: a retired row with no page, no Readers, or a Reader-raised Latest Chapter is still worth repairing.
  • A comment keeps the contrast that motivates the split: the four guarded predicates are computed from clocks that keep ticking after the last Poll, so they lie about a finished row; the three unguarded ones are computed from stored outcomes, which simply stop arriving.
  • The one-filter-at-a-time select behaviour is unchanged.
  • Store tests cover every guarded and unguarded predicate against a finished Series and the aggregate's finished count; a web test covers the filter option and the stats figure.
Part of #136. Blocked by: #157, #158. ## What to build The finished flag becomes first-class in the admin filter vocabulary, and the four clock-based hygiene predicates stop counting Series the owner deliberately retired. The owner can review every finished Series as a list, and an empty hygiene list is achievable again. ## Acceptance criteria - [ ] A finished filter joins the vocabulary with predicate `finished_at > 0`, label Finished, its own count in the aggregate, and the zero-renders-the-digit-unlinked rule applied unchanged. - [ ] The finished figure is ordered last in the stats block as informational rather than fixable — it does not sit among the counts that represent work to do. - [ ] The stale, never-checked, no-cover and never-read-a-chapter predicates exclude finished Series, so a finished row stops ageing into "not checked in 12h" forever. - [ ] The unpollable, orphan and sighting-raised predicates deliberately include finished Series: a retired row with no page, no Readers, or a Reader-raised Latest Chapter is still worth repairing. - [ ] A comment keeps the contrast that motivates the split: the four guarded predicates are computed from clocks that keep ticking after the last Poll, so they lie about a finished row; the three unguarded ones are computed from stored outcomes, which simply stop arriving. - [ ] The one-filter-at-a-time select behaviour is unchanged. - [ ] Store tests cover every guarded and unguarded predicate against a finished Series and the aggregate's finished count; a web test covers the filter option and the stats figure.
sulthan added the ready-for-agent label 2026-08-22 12:37:29 +07:00
sulthan self-assigned this 2026-08-22 17:19:20 +07:00
Author
Owner

Landed on spec-136 as a --no-ff merge of ticket/159-finished-filter (0029cff, cdd2e1d).

  • store/admin.go: SeriesFilterFinished = "finished" added last in the const block and explicitly outside the permanent-then-fixable ordering (the block comment now says so); adminFilter case → s.finished_at > 0; guard AND s.finished_at = 0 appended to the no-chapter, never-checked, stale and no-cover clauses (in the stale clause the guard sits after the cutoff placeholder, so no renumbering); no-URL, no-readers (the one HAVING) and reader-report stay deliberately unguarded. One dense paragraph in adminFilter's doc comment carries the clocks-versus-outcomes contrast.
  • web/admin_series.go: label Finished, appended last to seriesFilterOrder — that single edit yields the select's last option, its aggregate count via seriesFilterOptions, and the tail position in the Overview stats block. No new branch anywhere; seriesFilterLabels doubles as the validation set, so the one-filter-at-a-time select, FilterLabel and seriesListHref pick it up for free.
  • web/admin_overview.go: comment-only. The false "seven problem filters" line (plus two more stale counts) corrected; view.Unchecked untouched.
  • Tests: TestAdminFinishedSeriesFilters (four guarded predicates exclude a finished Series, three unguarded include it, finished returns exactly the retired rows, SeriesShapes finished total), plus three web tests — select option with count, index-order assertion that the finished figure renders after the seven hygiene figures, and zero-renders-as-unlinked-digit.

go vet ./... and go test ./... green on the merged base. No open concerns.

Landed on `spec-136` as a `--no-ff` merge of `ticket/159-finished-filter` (`0029cff`, `cdd2e1d`). - `store/admin.go`: `SeriesFilterFinished = "finished"` added last in the const block and explicitly outside the permanent-then-fixable ordering (the block comment now says so); `adminFilter` case → `s.finished_at > 0`; guard `AND s.finished_at = 0` appended to the no-chapter, never-checked, stale and no-cover clauses (in the stale clause the guard sits after the cutoff placeholder, so no renumbering); no-URL, no-readers (the one HAVING) and reader-report stay deliberately unguarded. One dense paragraph in `adminFilter`'s doc comment carries the clocks-versus-outcomes contrast. - `web/admin_series.go`: label `Finished`, appended last to `seriesFilterOrder` — that single edit yields the select's last option, its aggregate count via `seriesFilterOptions`, and the tail position in the Overview stats block. No new branch anywhere; `seriesFilterLabels` doubles as the validation set, so the one-filter-at-a-time select, `FilterLabel` and `seriesListHref` pick it up for free. - `web/admin_overview.go`: comment-only. The false "seven problem filters" line (plus two more stale counts) corrected; `view.Unchecked` untouched. - Tests: `TestAdminFinishedSeriesFilters` (four guarded predicates exclude a finished Series, three unguarded include it, `finished` returns exactly the retired rows, `SeriesShapes` finished total), plus three web tests — select option with count, index-order assertion that the finished figure renders after the seven hygiene figures, and zero-renders-as-unlinked-digit. `go vet ./...` and `go test ./...` green on the merged base. No open concerns.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sulthan/mangaBookmark#159