fix(paperless): use AND logic for tag filtering#580
Conversation
Change tag filtering from OR logic (tags__id__in) to AND logic (tags__id__all) so documents must have ALL selected tags, not just any. Fixes #579. Co-Authored-By: Claude backend-developer (Haiku 4.5) <noreply@anthropic.com>
…d results When tags are selected with AND logic, display counts reflecting how many documents in the current filtered result set have that tag. This provides users meaningful feedback about tag combinations. Compute tagCountMap from returned documents (which already have tags field) and use it for chip counts in DocumentBrowser. Falls back to tag.documentCount when tagCountMap is empty. Fixes #579 Co-Authored-By: Claude frontend-developer (Haiku 4.5) <noreply@anthropic.com>
Add the missing tagCountMap property to the makeHook() fixture in the DocumentBrowser test file. This property was added to UsePaperlessResult in the tag intersection count feature but the test fixture wasn't updated. Co-Authored-By: Claude backend-developer (Haiku 4.5) <noreply@anthropic.com>
…tMap Update paperlessService tests to assert tags__id__all (AND semantics) instead of tags__id__in. Add usePaperless tests covering tagCountMap computation from returned document tags. Co-Authored-By: Claude dev-team-lead (Sonnet 4.6) <noreply@anthropic.com> Co-Authored-By: Claude qa-integration-tester (Sonnet 4.5) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
steilerDev
left a comment
There was a problem hiding this comment.
[security-engineer]
Security review for PR #580 — fix(paperless): use AND logic for tag filtering.
Scope: 3-line backend change (tags__id__in → tags__id__all) in paperlessService.ts + frontend tagCountMap computation in usePaperless.ts + DocumentBrowser.tsx display update + associated tests.
Findings: None.
Checklist:
- No injection vectors —
query.tagsis passed throughURLSearchParams.set(), which percent-encodes the value. The parameter key is a hardcoded string literal. No SSRF change; the base URL origin remains controlled by server-side env vars. - Auth/authorization unchanged — no new routes or middleware changes.
-
tagCountMapcomputation is pure client-side arithmetic over API-returned data; no user-controlled values reach any execution or rendering path. -
DocumentBrowser.tsxrenderscountas a JSX text node — nodangerouslySetInnerHTMLor string interpolation into HTML. ARIA label uses the same numeric value; React escapes attribute content. - No new dependencies introduced.
- No secrets or sensitive data exposure.
- Tests correctly assert
tags__id__allis present andtags__id__inis absent.
The fix is correct and the security posture is unchanged from the previous audit baseline.
steilerDev
left a comment
There was a problem hiding this comment.
[product-architect]
Review complete — no architectural concerns. Would approve if not own PR.
Verified:
- Backend change correctly switches from
tags__id__in(OR) totags__id__all(AND) across all 3 code paths inpaperlessService.ts— matches Paperless-ngx API for AND tag semantics - Frontend
tagCountMapinusePaperlesshook provides intersection-aware counts with correct fallback totag.documentCount - No schema or API contract changes needed (this is a proxy query parameter fix)
- Test coverage adequate: unit tests for the parameter rename, new tests for
tagCountMapcomputation and edge cases - CI green (Quality Gates, Docker, tests all pass)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
🎉 This PR is included in version 1.13.0-beta.27 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
|
🎉 This PR is included in version 1.13.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Summary
tags__id__intotags__id__allinpaperlessService.tsso multi-tag filtering uses AND logic (documents must have ALL selected tags, not ANY)tagCountMaptousePaperlesshook — computes intersection-aware tag counts from the documents actually returned by the filtered query, so the tag count badges reflect the current filtered result setpaperlessService.test.tsto asserttags__id__allsemantics; addedusePaperless.test.tsxcoverage fortagCountMapcomputationFixes #579
Test plan