Skip to content

feat: admin TOC Validator screen (339595) - #398

Open
Us3r369 wants to merge 3 commits into
rc/v1.6.1from
feat/339595-metadata-classification-test
Open

feat: admin TOC Validator screen (339595)#398
Us3r369 wants to merge 3 commits into
rc/v1.6.1from
feat/339595-metadata-classification-test

Conversation

@Us3r369

@Us3r369 Us3r369 commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds an admin TOC Validator screen (ticket 339595) that surfaces documents whose body content is at risk of being hidden from Search because of how its sections are tagged.

Search's default content type filter only returns chunks whose section type is one of the "real content" types (executive_summary, context, methodology, findings, conclusions, recommendations, other). Everything else — front_matter, acronyms, annexes, appendix, bibliography, introduction — is excluded by default. Tagging is automatic at upload, so a body section mis-tagged as e.g. annexes silently disappears from default search results.

Each document carries a human-set body page range in its source metadata (Introduction - before beginning of Annexes). This feature checks that every section falling inside that range uses a default-included type, and lets an admin verify/fix the classification.

Screenshots

image

What it does

  • Lists documents (reusing the Documents Library /documents endpoint), with an indication of any prior validation result.
  • Select some or all documents → Run validation → each verdict is shown and persisted; rows that were added/changed by the run are highlighted.
  • Metadata and Contents links open the same modals as the Documents Library, so a flagged result can be checked — and edited — against the real document. Editing a classification re-validates that document.

Verdicts: pass (all in-range sections included), fail (an excluded type inside the body range), skipped (no range / no classified contents).

The check inspects the current classification only; it never re-tags.

How it's built

Shared logic — extracted into pipeline/validation/section_inclusion.py so the backend service and the existing offline eval script (tests/evaluation/section_inclusion/) share one implementation (the script now imports it; no behaviour change).

Backend (superuser-only, rate-limited) in ui/backend/routes/toc_validator.py + services/toc_validator.py:

  • POST /toc-validator/run — validate selected docs, persist, return results
  • GET /toc-validator/results — stored results for the screen on load

Frontend — new admin tab: TocValidatorManager + TocValidatorTable + TocValidationResultCell + useTocValidator, reusing MetadataModal/TocModal and the app's design tokens + shared badge/table/button classes.

Persistence — note for reviewers

Results are stored per document under a sys_toc_validation field via merge_doc_sys_fields (the same mechanism sys_toc_approved uses). No Alembic migration: the per-data-source docs_<source> tables are created/altered dynamically at runtime by the ensure_* helpers — they are not Alembic-managed except for uneg, so a migration would only (wrongly) touch that one source. This matches the existing per-doc-field precedent.

A finding worth a decision

Across the WFP corpus the dominant failure is sections tagged introduction inside the body range. That is systemic, not per-document mis-tagging: the body range starts at the introduction, and introduction is not in the default-included set (and has no checkbox in Search settings). The genuinely actionable mis-tags are annexes/acronyms/bibliography/front_matter appearing mid-body (e.g. a report whose Findings/Recommendations chapters were labelled annexes because headings contained "(EQs 1-5, Annex 8)"). Whether to add introduction to the defaults is a product decision this tool now makes visible.

Testing

  • Backend: unit tests for the shared logic (test_section_inclusion.py) and service (test_toc_validator_service.py); service round-tripped against real WFP data (persist + read-back).
  • Frontend: tocValidator.test.tsx (manager/table/result cell); full suite 518 passing, tsc clean, eslint zero warnings.
  • Verified the two endpoints register on the running API and are superuser-gated.

Docs: docs/admin/toc-validator.md (added to the sidebar).

🤖 Generated with Claude Code

Jan and others added 2 commits July 20, 2026 12:06
Add a standalone evaluation script that flags document sections whose
classified-TOC section type is excluded from Search by default despite
falling inside the human-set main-body page range
("Introduction - before beginning of Annexes"). Such sections are body
content that silently disappears from default search results.

Reads the body page range and the classified TOC from the Postgres
sidecar (docs_<data_source>) via PostgresClient.fetch_all_docs(), and
compares each in-range section label against the default-included set
mirrored from ui/frontend/src/utils/searchUrl.ts. Emits a per-document
xlsx report plus a console summary tallying which excluded section types
appear inside body ranges.

Includes unit tests for the page-range parsing, classified-TOC parsing
(incl. the real "[Front]" marker and roman-numeral page aliases),
in-range exclusion detection, document verdict, and document selection.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Wire the section-inclusion check into the app as a new superuser-only admin
tab. It lists documents, lets an admin select some or all and run validation,
persists and shows each verdict (pass/fail/skipped, with the excluded section
types), and links out to the Metadata and Contents views to verify or fix a
classification manually. Editing a classification re-validates that document.

The check compares the *current* classified TOC against the human-set body page
range ("Introduction - before beginning of Annexes"); it does not re-tag.

Shared logic
- Extract the validation logic into pipeline/validation/section_inclusion.py so
  the backend service and the offline eval script share one implementation; the
  eval script now imports from it (no behaviour change).

Backend (superuser-only, rate-limited)
- POST /toc-validator/run   — validate selected docs, persist, return results
- GET  /toc-validator/results — previously-stored results for the screen on load
- Results are stored per document under sys_toc_validation via
  merge_doc_sys_fields (same mechanism as sys_toc_approved); no migration needed
  as docs_<source> tables auto-create sys_* columns on write.

Frontend
- New TOC Validator admin tab (TocValidatorManager + table + result cell +
  useTocValidator hook), reusing the /documents endpoint and the existing
  MetadataModal and TocModal. Styling uses the app's design tokens and shared
  badge/table/button classes.

Tests & docs
- Unit tests for the shared logic and the backend service; frontend tests for
  the manager, table and result cell. Docs page at docs/admin/toc-validator.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Us3r369

Us3r369 commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator Author

When testing locally, the TOC validator flagged many cases with section type "introduction" outside of the "Introduction - before beginning of Annexes (start_page_number, end_page_number)" range. Flagging this here to discuss if this is expected and acceptable or should be adjusted!

@Us3r369
Us3r369 requested a review from dividor July 20, 2026 20:50

@dividor dividor left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please ensure the table column is clearly labelled so a person reading it knows exactly what it is 'Table of Contents review'. Also make sure it's filterable if not already.

@dividor
dividor changed the base branch from rc/v1.6.0 to rc/v1.6.1 July 21, 2026 15:17
- Rename the verdict column header "Validation" -> "Table of Contents review".
- Add per-column filters (funnel popovers) to Title, Organization, Status and
  the review verdict, reusing the Documents Library filter styling
  (filter-popover / filter-multiselect classes).
- Load all documents for the data source client-side so every filter — including
  the client-only verdict — applies across the whole set, not just one page;
  filtering, pagination and "select all" now operate on the filtered set.

New TocValidatorFilterPopover (text filter for title, checkbox multiselect for
organization/status/review). Frontend tests cover the rename and status
filtering; full suite green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Us3r369

Us3r369 commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator Author

@dividor adjusted column header and added filters in latest commit

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.

2 participants