Skip to content

feat(taxa): per-taxon verification & agreement counts + verified filter (#1316)#1317

Open
mihow wants to merge 1 commit into
mainfrom
worktree-taxa-verification-counts
Open

feat(taxa): per-taxon verification & agreement counts + verified filter (#1316)#1317
mihow wants to merge 1 commit into
mainfrom
worktree-taxa-verification-counts

Conversation

@mihow
Copy link
Copy Markdown
Collaborator

@mihow mihow commented May 22, 2026

Implements #1316 — per-taxon verification / model-agreement data on the taxa list + detail, with matching UI.

Backend (GET /api/v2/taxa/)

  • verified_count and agreed_with_prediction_count — always-on annotations. Both roll up descendant occurrences (a Family/Order row aggregates its species), occurrence-weighted.
  • agreed_exact_count — gated behind with_agreement=true; always present on the detail view. Compares occurrence.determination_id (top human ID, already maintained) against the top machine Classification.taxon_id.
  • verified=true|false filter — EXISTS / strict complement, project-scoped, respects apply_default_filters.
  • verified_count added to ordering_fields.
  • Detail view (/taxa/<id>/) returns all four counts unconditionally.

The hierarchical descendant match reuses the parents_json containment pattern from the occurrence-list taxon=<id> filter, but the right-hand side is built from an OuterRef via jsonb_build_array(jsonb_build_object('id', <outer id>)) — a literal __contains lookup can't embed an OuterRef. Migration 0085 adds the supporting GIN index (parents_json jsonb_path_ops), created CONCURRENTLY / IF NOT EXISTS so it co-exists with the same index if it lands separately via the #1307 follow-up.

Frontend

  • Sortable Verified column on the taxa list (links to that taxon's verified occurrences), shown next to Occurrences.
  • Verification status filter pill (All / Verified / Unverified) → verified= query param (reuses the existing occurrence-list filter component).
  • Verification panel on the taxon detail page showing the counts.

Tests

ami.main.tests.TestTaxaVerification (9 tests): hierarchical rollup to ancestors, chosen-identification-only agreed_with_prediction, gated agreed_exact_count (absent on list unless with_agreement), verified filter + strict complement, ordering, and apply_defaults handling. Existing taxon suite (47 tests) green, including the list query-count audit (the new annotations are inline correlated subqueries, so the statement count doesn't change).

Performance — needs a decision before merge

Rough warm/cold timings for a 25-row page against a production DB copy, with the GIN index in place (numbers are measurements, the interpretation is mine):

Project size default list verified=false ordering=verified_count with_agreement
small (~25 occ) ~15ms ~6ms ~5ms ~40ms
mid (~2k occ) ~380ms ~430ms ~500ms ~630ms
large (~180k occ, ~11k verified) ~8.5s cold ~9s cold >90s (timeout) not measured

Small/mid meet the issue's targets. The largest project does not: the always-on count subqueries run ~8–9s cold, and ordering=verified_count falls off a cliff because it must compute the subquery for every taxon in the project before sorting, not just a page.

This looks structural rather than a missing index. Directions worth discussing (ordered by effort):

  1. Gate the count annotations (compute only when explicitly requested / sorted on) and keep the default list on the cheap occurrences_count path.
  2. Drop server-side sort on verified_count for large projects, or back it with a denormalized column (the issue already lists "backfill counts onto a denormalized Taxon field" as a follow-up).
  3. Keep agreed_exact_count detail-only (already gated) and, if needed, add a /taxa/stats/verification/ aggregate endpoint (the Endpoint for stats about verified occurrences #1307 fallback the issue calls out).

I'd rather settle this than silently ship a list endpoint that times out on the biggest project. The correctness and UX are done; this is the open question.

Note on count semantics

occurrences_count stays direct-match (unchanged) while verified_count rolls up descendants, per the ticket. For species rows (the common case) they're equivalent; for Family/Order rows verified_count can exceed the direct occurrences_count. Flagging in case we want them consistent.

Test plan

  • Backend tests pass in CI.
  • Decide on the large-project performance approach above.
  • Browser check of the column / filter / detail panel (not yet done — the shared dev stack is bind-mounted to another branch's live test).

🤖 Generated with Claude Code

…lter

Adds to GET /api/v2/taxa/ (issue #1316):
- verified_count and agreed_with_prediction_count annotations (always on),
  rolled up over descendant occurrences via a hierarchical parents_json match.
- agreed_exact_count, gated behind with_agreement=true (and always on the
  detail view).
- verified=true|false filter (EXISTS / strict complement), project-scoped and
  respecting apply_default_filters.
- verified_count added to ordering_fields.

The hierarchical descendant match uses a Postgres jsonb @> containment built
from an OuterRef (literal __contains can't embed an OuterRef). Migration 0085
adds the supporting GIN index on Taxon.parents_json (jsonb_path_ops).

Frontend: sortable "Verified" column + "Verification status" filter on the taxa
list, and a Verification panel on the taxon detail page.

Co-Authored-By: Claude <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 22, 2026 04:46
@netlify
Copy link
Copy Markdown

netlify Bot commented May 22, 2026

Deploy Preview for antenna-preview ready!

Name Link
🔨 Latest commit ea9f45d
🔍 Latest deploy log https://app.netlify.com/projects/antenna-preview/deploys/6a0fdfb705e8ee000847dd15
😎 Deploy Preview https://deploy-preview-1317--antenna-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 61 (🔴 down 4 from production)
Accessibility: 89 (no change from production)
Best Practices: 92 (🔴 down 8 from production)
SEO: 92 (no change from production)
PWA: 80 (no change from production)
View the detailed breakdown and full score reports
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify
Copy link
Copy Markdown

netlify Bot commented May 22, 2026

Deploy Preview for antenna-ssec ready!

Name Link
🔨 Latest commit ea9f45d
🔍 Latest deploy log https://app.netlify.com/projects/antenna-ssec/deploys/6a0fdfb795bb2c0008b81779
😎 Deploy Preview https://deploy-preview-1317--antenna-ssec.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 22, 2026

Warning

Rate limit exceeded

@mihow has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 36 minutes and 15 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 811c23f3-7337-470a-8d33-0f82b8d2ad3d

📥 Commits

Reviewing files that changed from the base of the PR and between e721c8b and ea9f45d.

📒 Files selected for processing (11)
  • ami/main/api/serializers.py
  • ami/main/api/views.py
  • ami/main/migrations/0085_taxon_parents_json_gin_index.py
  • ami/main/models.py
  • ami/main/tests.py
  • docs/claude/planning/2026-05-20-taxa-verification-guidance-ticket.md
  • ui/src/data-services/models/species.ts
  • ui/src/pages/species-details/species-details.tsx
  • ui/src/pages/species/species-columns.tsx
  • ui/src/pages/species/species.tsx
  • ui/src/utils/getAppRoute.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch worktree-taxa-verification-counts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds per-taxon verification and model-agreement metrics to the taxa API and surfaces them in the taxa (“species”) UI, including a new verified filter and verified-count sorting/links.

Changes:

  • Backend: annotate taxa with verified_count + agreed_with_prediction_count, optionally agreed_exact_count, and add verified=true|false filtering; add GIN index migration for parents_json.
  • Frontend: add “Verified” column, verified filter control, and taxon detail “Verification” panel; propagate verified query param via routing utils.
  • Tests/docs: add API tests covering counts, gating, filter complement behavior, ordering, and apply-defaults behavior; add planning doc.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
ui/src/utils/getAppRoute.ts Adds verified to supported query filter keys for route generation.
ui/src/pages/species/species.tsx Enables verified filter control and default column visibility.
ui/src/pages/species/species-columns.tsx Adds sortable “Verified” column linking to verified occurrences for a taxon.
ui/src/pages/species-details/species-details.tsx Displays verification/agreement counts on the taxon detail panel with a link to verified occurrences.
ui/src/data-services/models/species.ts Exposes new server fields via getters (verified_count, agreement counts).
docs/claude/planning/2026-05-20-taxa-verification-guidance-ticket.md Planning/spec documentation for the feature and performance considerations.
ami/main/tests.py Adds TestTaxaVerification coverage for annotations, gating, filtering, ordering, and apply-defaults.
ami/main/models.py Adds Taxon stub methods for new annotated fields to support serialization.
ami/main/migrations/0085_taxon_parents_json_gin_index.py Adds concurrent GIN index on Taxon.parents_json for hierarchical containment performance.
ami/main/api/views.py Implements hierarchical “under taxon” occurrence correlation, annotations, verified filter, and ordering field addition.
ami/main/api/serializers.py Gates agreed_exact_count field on list responses unless with_agreement=true.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread ami/main/api/views.py
Comment on lines 1669 to +1674
if not include_unobserved:
# Efficient EXISTS check that uses the composite index
qs = qs.filter(models.Exists(Occurrence.objects.filter(base_filter)))

qs = self.add_verification_data(qs, occurrence_filters, default_filters_q)

Comment thread ami/main/api/views.py
"created_at",
"updated_at",
"occurrences_count",
"verified_count",
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