Merged in feature/add-deletes (pull request #214)

support delete for client, document and folder

* support delete

for client, document and folder

* remove batch cancel conflict

not used


Approved-by: Jacob Mathison
This commit is contained in:
Jay Brown
2026-03-04 18:30:13 +00:00
parent 62b5de5722
commit 09c61ea9b4
28 changed files with 3438 additions and 632 deletions
+109 -20
View File
@@ -266,6 +266,36 @@ Updates client information.
**Response**: `200` Client updated successfully
### `DELETE /client/{id}`
Permanently deletes a client and all associated data: documents (with all dependent rows), folders, collector configurations, batch uploads, and clientCanSync records. Source documents in S3 are NOT deleted; their paths are logged and optionally returned. This operation is irreversible.
**Security**: Requires JWT authentication. Restricted to `super_admin` role only.
**Query Parameters**:
- `confirm` (required, boolean): Must be `true` to proceed. Returns `400 Bad Request` if absent or false.
- `verbose` (optional, boolean, default: false): When `true`, returns S3 paths of orphaned source documents.
**Response**:
- `204`: Client deleted successfully (when `verbose=false`)
- `200`: Client deleted successfully with S3 paths (when `verbose=true`):
```json
{
"deletedDocuments": [
{
"documentId": "019580df-b3f8-7348-9ab1-1e55b3f18ed7",
"s3Path": "s3://bucket-name/key/path/to/file"
}
]
}
```
- `400`: Missing `confirm=true` query parameter
- `404`: Client not found
### `GET /client/{id}/status`
Returns client synchronization status.
@@ -356,6 +386,38 @@ Retrieves enriched document details by ID, including metadata such as folder, fi
}
```
### `DELETE /document/{id}`
Permanently deletes a document and all dependent data: document entries, cleans (and their entries), text extractions (and their entries), field extractions (versions and array fields), labels, results, and result dependencies. Source documents in S3 are NOT deleted; their paths are logged and optionally returned.
**Security**: Requires JWT authentication. Restricted to `super_admin` role only.
**Path Parameters**:
- `id`: Document UUID (max 36 chars)
**Query Parameters**:
- `verbose` (optional, boolean, default: false): When `true`, returns S3 paths of orphaned source documents.
**Response**:
- `204`: Document deleted successfully (when `verbose=false`)
- `200`: Document deleted successfully with S3 paths (when `verbose=true`):
```json
{
"deletedDocuments": [
{
"documentId": "019580df-b3f8-7348-9ab1-1e55b3f18ed7",
"s3Path": "s3://bucket-name/key/path/to/file"
}
]
}
```
- `404`: Document not found
---
## Batch Document Operations (DocumentsService)
@@ -448,17 +510,6 @@ Retrieves detailed status information for a specific batch upload.
}
```
### `DELETE /client/{id}/document/batch/{batch_id}`
Cancels a batch upload that is currently processing.
**Security**: Requires JWT authentication
**Response**:
- `204`: Batch upload cancelled successfully
- `404`: Batch not found
---
## Folder Operations (FolderService)
@@ -612,6 +663,40 @@ Renames an existing folder.
**Response** (`200 OK`): Updated folder object
### `DELETE /folders/{folderId}`
Permanently deletes a folder and all child folders recursively. The root folder (`/`) cannot be deleted. If the folder tree contains documents, the caller must either delete the documents first or pass `include_documents=true`.
**Security**: Requires JWT authentication. Restricted to `super_admin` role only.
**Path Parameters**:
- `folderId`: Folder UUID
**Query Parameters**:
- `include_documents` (optional, boolean, default: false): When `true`, deletes all documents in the folder tree along with the folders. When `false` and the folder tree contains documents, returns `409 Conflict`.
- `verbose` (optional, boolean, default: false): When `true`, returns S3 paths of orphaned source documents.
**Response**:
- `204`: Folder tree deleted successfully (when `verbose=false`)
- `200`: Folder tree deleted successfully with S3 paths (when `verbose=true`):
```json
{
"deletedDocuments": [
{
"documentId": "019580df-b3f8-7348-9ab1-1e55b3f18ed7",
"s3Path": "s3://bucket-name/key/path/to/file"
}
]
}
```
- `404`: Folder not found
- `409`: Cannot delete root folder, or folder tree contains documents and `include_documents` is not `true`
### `GET /folders/{folderId}/documents`
Retrieves all documents within a specific folder, including filename and labels. Returns a lighter-weight format than `GET /document/{id}` (excludes `client_id`).
@@ -1637,20 +1722,22 @@ The following table shows what data is passed to Permit.io for each protected en
| `GET` | `/clients` | `clients` | `get` | List all clients |
| `GET` | `/client/{id}` | `client` | `get` | Get client details |
| `PATCH` | `/client/{id}` | `client` | `patch` | Update client |
| `DELETE` | `/client/{id}` | `client` | `delete` | Hard-delete client (super_admin only) |
| `GET` | `/client/{id}/status` | `client` | `get` | Get client sync status |
| **Document Operations** |
| `POST` | `/client/{id}/document` | `client` | `post` | Upload document |
| `GET` | `/client/{id}/document` | `client` | `get` | List client documents |
| `GET` | `/document/{id}` | `document` | `get` | Get document details |
| `DELETE` | `/document/{id}` | `document` | `delete` | Hard-delete document (super_admin only) |
| **Batch Document Operations** |
| `POST` | `/client/{id}/document/batch` | `client` | `post` | Upload batch (ZIP) |
| `GET` | `/client/{id}/document/batch` | `client` | `get` | List batch uploads |
| `GET` | `/client/{id}/document/batch/{batch_id}` | `client` | `get` | Get batch status |
| `DELETE` | `/client/{id}/document/batch/{batch_id}` | `client` | `delete` | Cancel batch upload |
| **Folder Operations** |
| `GET` | `/client/{id}/folders` | `client` | `get` | List client folders |
| `POST` | `/folders` | `folders` | `post` | Create folder |
| `PATCH` | `/folders/{folderId}` | `folders` | `patch` | Rename folder |
| `DELETE` | `/folders/{folderId}` | `folders` | `delete` | Hard-delete folder tree (super_admin only) |
| `GET` | `/folders/{folderId}/documents` | `folders` | `get` | List folder documents |
| `GET` | `/folders/{folderId}/metrics` | `folders` | `get` | Get folder metrics |
| **Label Operations** |
@@ -1717,16 +1804,18 @@ To configure Permit.io to work with this API, administrators must create:
| `delete` | DELETE | Delete resources |
| `head` | HEAD | Check resource existence |
#### Example Role Configuration
#### Role Configuration
Typical role assignments for common personas:
The following roles are defined in the Permit.io configuration (`cmd/auth_related/permit.setup/permit_policies.yaml`):
| Role | Resources | Actions | Use Case |
| ------------ | -------------------------------------------------------------------------- | ---------------------- | -------------------------- |
| `viewer` | `client`, `clients`, `document`, `documents`, `folders`, `export` | `get` | Read-only access |
| `editor` | `client`, `document`, `documents`, `folders`, `field-extractions` | `get`, `post`, `patch` | Content management |
| `admin` | All resources | All actions | Full administrative access |
| `user_admin` | `admin` | All actions | User management only |
| Role | Resources | Actions | Use Case |
| -------------- | -------------------------------------------------------------------------------------- | -------------------------------- | --------------------------------------- |
| `super_admin` | All resources | All actions including `delete` | Full administrative access |
| `user_admin` | `admin`, `documents`, `field-extractions`, `folders` | `get`, `post`, `patch`, `delete` (admin only) | User management |
| `auditor` | `admin`, `client`, `clients`, `document`, `export`, `documents`, `field-extractions`, `folders`, `labels` | `get` (and `head` for admin) | Read-only access for auditing |
| `client_user` | `client`, `clients`, `document`, `export`, `documents`, `field-extractions`, `folders`, `labels` | `get`, `post`, `patch` (varies by resource) | Client-specific access |
**Delete permissions**: Only `super_admin` has `delete` access to `client`, `document`, and `folders` resources. The `client_user` role does NOT have `client:delete` or any other delete permissions on these resources.
### Authorization Error Responses
+10 -3
View File
@@ -309,10 +309,10 @@ Permissions follow the format `resource:action`:
| Resource | Actions | Description |
|----------|---------|-------------|
| `client` | `get`, `post`, `patch`, `delete` | Client management |
| `client` | `get`, `post`, `patch`, `delete` | Client management (delete: super_admin only) |
| `clients` | `get` | List all clients |
| `document` | `get`, `post`, `patch`, `delete` | Document operations |
| `folders` | `get`, `post`, `patch`, `delete` | Folder management |
| `document` | `get`, `post`, `delete` | Document operations (delete: super_admin only) |
| `folders` | `get`, `post`, `patch`, `delete` | Folder management (delete: super_admin only) |
| `export` | `get`, `post` | Export operations |
| `admin` | `get`, `post`, `patch`, `delete` | User and EULA administration |
| `eula` | `get`, `post` | EULA status and agreement |
@@ -402,6 +402,9 @@ const UI_FEATURES = {
viewDocuments: ['client:get', 'document:get'],
uploadDocuments: ['client:post'],
manageClients: ['client:post', 'client:patch'],
deleteClients: ['client:delete'],
deleteDocuments: ['document:delete'],
deleteFolders: ['folders:delete'],
viewExports: ['export:get'],
createExports: ['export:post'],
adminPanel: ['admin:get'],
@@ -431,6 +434,7 @@ function canAccessFeature(
| `401` | Unauthorized | Token invalid/expired - refresh or re-login |
| `403` | Forbidden | User lacks permission - show access denied |
| `404` | Not Found | Resource doesn't exist |
| `409` | Conflict | Operation cannot proceed in current state (e.g., folder has documents) |
| `429` | Too Many Requests | Rate limited - implement backoff |
| `500` | Server Error | Show generic error, retry later |
| `502` | Bad Gateway | Authorization service unavailable |
@@ -898,6 +902,9 @@ Content-Type: application/json
| `/client/{id}/document` | POST | Upload document (multipart/form-data) |
| `/client/{id}/document/batch` | POST | Upload ZIP batch |
| `/document/{id}` | GET | Get document details |
| `/client/{id}` | DELETE | Hard-delete client (super_admin, requires confirm=true) |
| `/document/{id}` | DELETE | Hard-delete document (super_admin) |
| `/folders/{folderId}` | DELETE | Hard-delete folder tree (super_admin) |
| `/clients/{clientId}/folders` | GET | List folders |
| `/eula` | GET | Get current EULA (no auth required) |
| `/eula/status` | GET | Check user's EULA agreement status |
+28 -7
View File
@@ -13,18 +13,18 @@ This document provides a comprehensive summary of all REST API endpoints availab
| /identity | GET | AuthService |
| /client | POST | ClientService |
| /clients | GET | ClientService |
| /client/{id} | GET, PATCH | ClientService |
| /client/{id} | GET, PATCH, DELETE | ClientService |
| /client/{id}/status | GET | ClientService |
| /client/{id}/collector | GET, PATCH | CollectorService |
| /client/{id}/folders | GET | FolderService |
| /folders | POST | FolderService |
| /folders/{folderId} | PATCH | FolderService |
| /folders/{folderId} | PATCH, DELETE | FolderService |
| /folders/{folderId}/documents | GET | FolderService |
| /folders/{folderId}/metrics | GET | FolderService |
| /client/{id}/document | GET, POST | DocumentsService |
| /client/{id}/document/batch | GET, POST | DocumentsService |
| /client/{id}/document/batch/{batch_id} | GET, DELETE | DocumentsService |
| /document/{id} | GET | DocumentsService |
| /client/{id}/document/batch/{batch_id} | GET | DocumentsService |
| /document/{id} | GET, DELETE | DocumentsService |
| /documents/{documentId}/labels | GET, POST | LabelService |
| /labels/{labelName}/documents | GET | LabelService |
| /field-extractions | GET, POST | FieldExtractionService |
@@ -90,6 +90,14 @@ This document provides a comprehensive summary of all REST API endpoints availab
- Request Body: `{name?, can_sync?}` (optional fields)
- Returns: 200 OK on success
- **DELETE /client/{id}** - Hard-delete a client and all associated data (super_admin only)
- Query Parameters:
- `confirm=true` (required) - Must be set to confirm deletion
- `verbose` (optional, default: false) - When true, returns S3 paths of orphaned source documents
- Deletes all documents, folders, collector configs, batch uploads, and clientCanSync records
- S3 source files are NOT deleted; their paths are logged
- Returns: 204 No Content (or 200 with S3 paths when verbose=true)
- **GET /client/{id}/status** - Retrieve the sync status for a client
- Returns: `{status}` where status is one of: `IN_SYNC`, `NOT_SYNCED`, `NOT_SYNCING`
@@ -120,6 +128,15 @@ This document provides a comprehensive summary of all REST API endpoints availab
- Request Body: `{path}`
- Returns: `{id, client_id, path, parent_id}` (200 OK)
- **DELETE /folders/{folderId}** - Hard-delete a folder tree (super_admin only)
- Query Parameters:
- `include_documents` (optional, default: false) - When true, also deletes all documents in the folder tree
- `verbose` (optional, default: false) - When true, returns S3 paths of orphaned source documents
- Root folder (`/`) cannot be deleted (returns 409 Conflict)
- If folder tree contains documents and include_documents is false, returns 409 Conflict
- S3 source files are NOT deleted; their paths are logged
- Returns: 204 No Content (or 200 with S3 paths when verbose=true)
- **GET /folders/{folderId}/documents** - Get documents in a folder
- Query Parameters:
- `textRecord` (optional, default: false) - When true, includes full text extraction record
@@ -146,6 +163,13 @@ This document provides a comprehensive summary of all REST API endpoints availab
- `textRecord` (optional, default: false) - When true, includes full text extraction record
- Returns: `{id, client_id, hash, folder_id, filename, labels[], fields{}, text_record?}`
- **DELETE /document/{id}** - Hard-delete a document and all dependent data (super_admin only)
- Query Parameters:
- `verbose` (optional, default: false) - When true, returns S3 paths of orphaned source documents
- Deletes all dependent rows: entries, cleans, text extractions, field extractions, labels, results
- S3 source files are NOT deleted; their paths are logged
- Returns: 204 No Content (or 200 with S3 paths when verbose=true)
### Batch Document Processing
- **POST /client/{id}/document/batch** - Upload multiple PDFs as ZIP archive for batch processing
- Content-Type: `multipart/form-data`
@@ -162,9 +186,6 @@ This document provides a comprehensive summary of all REST API endpoints availab
- **GET /client/{id}/document/batch/{batch_id}** - Get detailed status of a specific batch upload
- Returns: `{batch_id, client_id, original_filename, status, total_documents, processed_documents, failed_documents, invalid_type_documents, progress_percent, created_at, completed_at?, failed_filenames[]}`
- **DELETE /client/{id}/document/batch/{batch_id}** - Cancel a batch upload currently processing
- Returns: 204 No Content on successful cancellation
## Label Service
### Document Label Management