feat(ui): add user autocomplete widget for default_owner_id, user search API, and documentation

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-03-05 21:40:41 +00:00
parent 5722252dcb
commit 3601e2ca5c
7 changed files with 378 additions and 4 deletions
+112
View File
@@ -614,6 +614,118 @@ curl -X POST "http://<your-instance>/api/files/bulk-download" \
**Error Responses**:
- `404`: No files found with the provided IDs, or none of the selected files exist on disk
### Document Ownership (Multi-User Mode)
These endpoints are available when `MULTI_USER_ENABLED=true`.
---
**POST** `/api/files/{file_id}/claim`
Claim an unclaimed document (owner_id is NULL) for the current user.
```bash
curl -X POST "http://<your-instance>/api/files/42/claim"
```
**Response**:
```json
{
"status": "success",
"message": "Document claimed successfully",
"file_id": 42,
"owner_id": "alice@example.com"
}
```
**Error Responses**:
- `400`: Multi-user mode is not enabled
- `401`: Authentication required
- `403`: Document is already owned by another user
---
**POST** `/api/files/bulk-claim`
Claim multiple unclaimed documents at once. Already-owned documents are skipped.
**Request body**: JSON array of file IDs
```bash
curl -X POST "http://<your-instance>/api/files/bulk-claim" \
-H "Content-Type: application/json" \
-d '[1, 2, 3]'
```
**Response**:
```json
{
"status": "success",
"claimed_count": 2,
"claimed_ids": [1, 3],
"skipped": [{"file_id": 2, "reason": "already owned"}],
"owner_id": "alice@example.com"
}
```
---
**POST** `/api/files/assign-owner`
**Admin only.** Assign an owner to documents. If `file_ids` body is omitted, assigns all
currently unclaimed documents to the specified owner.
**Query Parameters**:
- `owner_id` (required): The user identifier to assign
**Request body** (optional): JSON array of specific file IDs
```bash
# Assign all unclaimed documents to a user
curl -X POST "http://<your-instance>/api/files/assign-owner?owner_id=alice@example.com"
# Assign specific files
curl -X POST "http://<your-instance>/api/files/assign-owner?owner_id=alice@example.com" \
-H "Content-Type: application/json" \
-d '[1, 2, 3]'
```
**Response**:
```json
{
"status": "success",
"message": "Assigned owner to 5 document(s)",
"updated_count": 5,
"owner_id": "alice@example.com"
}
```
**Error Responses**:
- `400`: Multi-user mode is not enabled
- `403`: Only admins can assign document owners
---
**GET** `/api/users/search`
Search known user identifiers from existing documents. Powers the autocomplete widget
in the settings page for the `DEFAULT_OWNER_ID` field.
**Query Parameters**:
- `q` (optional): Substring to match against known owner IDs (case-insensitive)
- `limit` (optional): Maximum results to return (default: 5, max: 20)
```bash
curl "http://<your-instance>/api/users/search?q=risti&limit=5"
```
**Response**:
```json
{
"users": ["christianlouis"]
}
```
### File Preview
**GET** `/api/files/{file_id}/preview`
+31
View File
@@ -163,6 +163,37 @@ Requires `AUTH_ENABLED=true`.
|-----------------------------|---------------------------------------------------------------------------------|-------------|
| `MULTI_USER_ENABLED` | Enable multi-user mode with individual document spaces per user. | `false` |
| `DEFAULT_DAILY_UPLOAD_LIMIT`| Maximum document uploads allowed per user per day. `0` = unlimited. | `0` |
| `UNOWNED_DOCS_VISIBLE_TO_ALL` | Show unclaimed documents (no owner) to all users. When `false`, only admins see them. | `true` |
| `DEFAULT_OWNER_ID` | Automatically assign this owner to newly ingested documents without a session (e.g. IMAP, API). Leave empty to keep unowned. | *(empty)* |
#### Unclaimed Documents
Documents ingested without a user session (e.g. via IMAP polling, API calls without authentication,
or legacy imports) have `owner_id = NULL`. These are called **unclaimed** documents.
- When `UNOWNED_DOCS_VISIBLE_TO_ALL=true` (default), every authenticated user sees unclaimed
documents alongside their own files. This allows users to discover and claim them.
- When `UNOWNED_DOCS_VISIBLE_TO_ALL=false`, only admins can see unclaimed documents.
#### Claiming Documents
Users can claim unclaimed documents via the API:
- **`POST /api/files/{file_id}/claim`** — Claim a single unclaimed document.
- **`POST /api/files/bulk-claim`** — Claim multiple unclaimed documents at once.
Only documents with `owner_id = NULL` can be claimed. Already-owned documents cannot be claimed
by another user.
#### Admin Owner Assignment
Admins can assign ownership of documents to any user:
- **`POST /api/files/assign-owner?owner_id=<user_id>`** — Assign all unclaimed documents to
the specified user, or pass a `file_ids` JSON body to assign specific files.
The `DEFAULT_OWNER_ID` setting can also be configured via the Settings page, which provides an
autocomplete field that searches existing users by substring.
### Security Headers
+1
View File
@@ -48,6 +48,7 @@ Settings are organized into logical categories for easy navigation:
- **Dropdown**: Predefined option lists (e.g., PDF/A format, S3 storage class, S3 ACL)
- **Multi-select**: Comma-separated selections from a list (e.g., OCR providers)
- **Model Picker**: Free-text with suggested model names (e.g., AI model selection)
- **User Autocomplete**: Typeahead search for existing user identifiers (e.g., default owner assignment)
- **List**: Comma-separated values (notification URLs, CORS origins)
### Sensitive Data