AI Suggestions previously invented near-duplicate metadata because the classification
prompt had no knowledge of the installation's own taxonomy. This surfaces
a small, ranked, permission-filtered set of existing tags/document
types/correspondents/storage paths - drawn from the document's RAG
neighbors plus its own already-assigned metadata - so the model prefers
reusing what already exists.
The LLM response schema now returns existing_ids (IDs of reused
candidates) separately from new_names (genuinely new suggestions).
Only new_names goes through localization and fuzzy name-matching;
existing_ids is resolved deterministically and never touched by the
localization pass, so exact matches can no longer be silently
corrupted by translation.
* perf: migrate 5 single-call Document permission sites to permitted_document_ids
Swaps get_objects_for_user_owner_aware(user, "view_document", Document) for
Document.objects.filter(id__in=permitted_document_ids(user)) at 5 read-only,
single-call sites: AI chat "ask all documents", bulk-edit
_resolve_document_ids all:true branch, SelectionDataView permission check,
global search docs bucket, and the statistics endpoint's Document branch.
Confirmed all 3 callers of _resolve_document_ids always use the default
"view_document" codename before swapping. Added a regression test pinning
the AI-chat owner/permission boundary through the real API client, and
updated 2 existing mocked tests in test_views.py that asserted on
get_objects_for_user_owner_aware for the chat endpoint.
* perf: migrate 3 serialisers.py Document permission sites to permitted_document_ids
Migrates _get_viewable_duplicates(), PaperlessTaskSerializer.get_duplicate_documents(),
and the ShareLinkBundle document field queryset to use permitted_document_ids()
instead of get_objects_for_user_owner_aware()/get_objects_for_user(), consolidating
onto the shared permission-filtering helper. The is_staff gate in
get_duplicate_documents() is preserved as-is.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GRp4kf1mdn9ruv81zWAmh2
* refactor: remove dead permission_codename param from _resolve_document_ids
The keyword param was unused in the method body since an earlier commit
switched it to call permitted_document_ids(user) internally. None of the
3 call sites passed it.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* docs: drop internal task-number reference from AI chat migration test docstring
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
* Updates code to use a FileResponse for streaming and unlink the file, but keep a handle to it
* Transitions the rest of the code to use FileResponse instead of a basic response, fixes up tests which assumed .content exists
* While here, let's add schema for it
* Implement share links
Basic implementation of share links
Make certain share link fields not editable, automatically grant permissions on migrate
Updated styling, error messages from expired / deleted links
frontend code linting, reversable sharelink migration
testing coverage
Update translation strings
No links message
* Consolidate file response methods
* improvements to share links on mobile devices
* Refactor share links file_version
* Add docs for share links
* Apply suggestions from code review
* When filtering share links, use the timezone aware now()
* Removes extra call to setup directories for usage in testing
* FIx copied badge display on some browsers
* Move copy to ngx-clipboard library
---------
Co-authored-by: Trenton H <797416+stumpylog@users.noreply.github.com>