feat(issues): retry a processing issue through the individual scanner
POST /api/libraries/:id/issues/:issueId/retry (admin, family-lens gated via the existing gateIssue) re-runs the work that produced an open issue — deliberately NOT a library-wide rescan. Two shapes mirror the two ledger entry kinds: - item-backed issues rescan their media item through the book-detail RescanMediaItem mechanism (self-resolving folders, multi-file audiobook routing, write-after-success guards) and then close the issue (RetryMediaItemIssue); - row-less import_failed issues re-import the single file through the watcher's standalone processMediaFile path (RetryFailedImport: folders resolved RescanMediaItem-style so paths stay library-root-relative), whose create-path self-heal plus an explicit path resolve closes the issue even when the content was already imported by a prior attempt. Failures return the REAL underlying error so the UI can show why the issue still exists; a vanished file is a 409 (ErrRetryFileMissing); already-resolved issues reject re-retry. Docs + bruno mirrors regenerated for the new route (the generator's seq renumbering touches three unrelated bruno files as fallout; openapi gains the path and the date bump), and the docs schema registry gains the retry entry so TestDocsMatchRoutes passes.
This commit is contained in:
1 parent
fb117635f8
commit
6f37be59fc
10 files changed
+246
-4
No files matched your search
@@ -0,0 +1,41 @@
|
||||
---
|
||||
method: POST
|
||||
path: /api/libraries/:id/issues/:issueId/retry
|
||||
auth: jwt+admin
|
||||
area: libraries
|
||||
---
|
||||
<!-- source: internal/handlers/processing_issues.go RetryProcessingIssue -->
|
||||
|
||||
# Retry Processing Issue
|
||||
|
||||
Re-runs the work that produced an open issue through the individual
|
||||
scanner — deliberately NOT a library-wide rescan. Two shapes:
|
||||
|
||||
- **Item-backed issues** (media item exists): the item is rescanned via
|
||||
the same mechanism as the book-detail Rescan action — self-resolving
|
||||
folders, multi-file audiobook routing, write-after-success guards.
|
||||
- **Row-less `import_failed` issues** (no media item): the single file
|
||||
is re-imported through the scanner's standalone per-file path.
|
||||
|
||||
On success the issue is closed. On failure the response carries the REAL
|
||||
error (e.g. the underlying SQL failure), so the UI can show why the issue
|
||||
still exists. The issue's library must be in the requester's visible set.
|
||||
|
||||
## Example response
|
||||
|
||||
```json example-response
|
||||
{
|
||||
"success": true,
|
||||
"message": "File imported; issue resolved"
|
||||
}
|
||||
```
|
||||
|
||||
## Errors
|
||||
|
||||
| Status | Body | When |
|
||||
| ------ | ---- | ---- |
|
||||
| 400 | `{"error": "Invalid issue ID"}` | malformed path param |
|
||||
| 403 | — | issue's library not in requester's visible set |
|
||||
| 404 | `{"error": "Issue not found"}` | no such issue |
|
||||
| 409 | `{"error": "Issue is already resolved"}` / `{"error": "media file not found on disk: …"}` | nothing to retry, or the file vanished |
|
||||
| 500 | `{"error": "…"}` | the retried work failed — body carries the underlying error |
|
||||
Reference in new issue
Block a user