feat(documents): hide-linked toggle filters system-wide (#1557)#1559
Conversation
Adds two E2E tests covering the new "Hide already-linked documents" toggle behaviour introduced in #1557: - Scenario 7a: mock GET /api/document-links/linked-ids returning [42]; opening the picker on workItemA shows both docs; checking the toggle hides doc #42 (linked system-wide) while doc #55 remains visible; unchecking restores both documents. - Scenario 7b: verifies the toggle is visible when system IDs > 0 and unchecked by default, so all documents show without filtering. Fixes #1557 (E2E coverage) Co-Authored-By: Claude e2e-test-engineer (Sonnet 4.6) <noreply@anthropic.com>
…linked ID filter Extends all five existing document-link test files with coverage for the new getAllLinkedDocumentIds service function, GET /api/document-links/linked-ids route, listAllLinkedDocumentIds API client function, useAllLinkedDocumentIds hook, and the system-wide filter merge logic in LinkedDocumentsSection. Tests cover: empty/single/duplicate/multi-entity deduplication scenarios (service and route), API client URL and response extraction, hook lifecycle (no-mount-fetch, isLoading transitions, ApiClientError/NetworkError/unknown error branches, fetch stability, second-call replacement), and component integration (fetch-on-open, system+entity ID merge, deduplication, empty passthrough). Co-Authored-By: Claude qa-integration-tester (Sonnet 4.6) <noreply@anthropic.com>
Add a system-wide filter that hides documents already linked to any work item when the "hide linked" toggle is active. Previously the filter only excluded links for the current entity. Fixes #1557 Co-Authored-By: Claude dev-team-lead (Sonnet 4.6) <noreply@anthropic.com> Co-Authored-By: Claude backend-developer (Haiku 4.5) <noreply@anthropic.com> Co-Authored-By: Claude frontend-developer (Haiku 4.5) <noreply@anthropic.com>
5624f20 to
f13970e
Compare
|
[security-engineer] APPROVE — no security findings. Auth enforcement: The new Information disclosure: The endpoint returns all Paperless document IDs across all entities without per-user filtering. This matches the existing SQL injection: CSRF: Read-only Response content: Verdict: APPROVE. Checklist clear — no injection vectors, auth enforced, no sensitive data exposed, no new dependencies, no hardcoded credentials. |
|
[product-owner] Verdict: APPROVE (posted as comment — PR author cannot self-approve via review API) All 5 acceptance criteria are met.
Out-of-scope items: All correctly avoided (no visual changes, no cross-open caching, no per-entity breakdown). Test authorship: Correct — Non-blocking nit: PR summary says "new Ready to merge after CI gates pass. |
steilerDev
left a comment
There was a problem hiding this comment.
[product-architect] Verdict: APPROVE
(Cannot --approve own PR via gh — posting as comment per agent convention.)
Architecture, contract, and coverage all check out. Verified against Wiki Architecture / API Contract / Schema and the existing documentLinks module conventions.
Verified:
- Drizzle
selectDistinct(server/src/services/documentLinkService.ts:224-230) — canonical pattern for column-level distinct. Pushes dedup to SQLite rather than JS-sideSet; correct for the scale and the right call. - Route ordering (server/src/routes/documentLinks.ts:126 vs 145) —
GET /linked-idsis registered beforeDELETE /:id. There is no actual method+path collision risk here (the:idroute isDELETE, the new route isGET), but the static-before-param ordering is the right defensive convention and matches Fastify guidance. - API contract shape —
{ paperlessDocumentIds: number[] }is consistent with the existing single-field wrapping inDocumentLinkResponse { documentLink }andDocumentLinkListResponse { documentLinks }. Auth gating (401UNAUTHORIZED) matches the rest of the file. No JSON schema on the response is consistent with the siblingGET /(existing in-file style). - Wiki documentation (
wiki/API-Contract.md6109–6133) — endpoint documented with auth requirement, empty response noted, error table present. Submodule ref98204a8is committed in the PR. Good wiki discipline. - Test coverage — 5 service / 5 integration / 8 hook / 5 component / 2 E2E. Critical paths (dedup within entity type, dedup across entity types, lazy fetch on picker open, error categorisation) are all exercised. Coverage is more than adequate for the change.
Informational (non-blocking):
- The local
interface AllLinkedDocumentIdsResponseindocumentLinks.test.ts(lines 28-32) is a worktree symlink workaround for@cornerstone/shared. Documented inline; will dissolve once merged. - Lazy
fetchon picker open (not mount) is the right design — keeps cost off pages where the picker is never opened.
No architectural debt introduced. Cleared for merge.
|
🎉 This PR is included in version 2.7.0-beta.6 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Summary
linkedDocumentIdsquery onGET /api/document-linksreturns all IDs linked across the system;documentLinkServiceexposes agetSystemLinkedDocumentIds()helperuseDocumentLinkshook andLinkedDocumentsSectionconsume the new system-wide ID set when building the filtered document listFixes #1557
Test plan
documentLinkService,documentLinksApi,useDocumentLinks)GET /api/document-links?linkedDocumentIds=true)Co-Authored-By: Claude dev-team-lead (Sonnet 4.6) noreply@anthropic.com