From 7471ca99e832b0e21f2d8b3487c899119fc2b57d Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Sat, 24 Oct 2026 15:08:18 -0400 Subject: [PATCH] =?UTF-8?q?docs(analytics,jobs):=20Work=20Order=203=20batc?= =?UTF-8?q?h=204=20=E2=80=94=20device=20usage,=20popular=20books,=20job=20?= =?UTF-8?q?create/status?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DeviceUsageResponse / PopularBooksResponse / services.JobResult pinned by type; jobs create uses an inline anonymous request struct (RawMessage pin). Two UNVERIFIED markers recorded (analytics date-range params, facet value element shape). --- .../api/analytics/get_device_usage.md | 40 +++++++++++++++++++ .../api/analytics/get_popular_books.md | 39 ++++++++++++++++++ docs/developer/api/jobs/create_job.md | 40 +++++++++++++++++++ docs/developer/api/jobs/get_job_status.md | 34 ++++++++++++++++ internal/docs/schema.go | 16 ++++++++ 5 files changed, 169 insertions(+) create mode 100644 docs/developer/api/analytics/get_device_usage.md create mode 100644 docs/developer/api/analytics/get_popular_books.md create mode 100644 docs/developer/api/jobs/create_job.md create mode 100644 docs/developer/api/jobs/get_job_status.md diff --git a/docs/developer/api/analytics/get_device_usage.md b/docs/developer/api/analytics/get_device_usage.md new file mode 100644 index 00000000..da7f295a --- /dev/null +++ b/docs/developer/api/analytics/get_device_usage.md @@ -0,0 +1,40 @@ +--- +method: GET +path: /api/analytics/device-usage +auth: jwt +area: analytics +--- + + +# Get Device Usage + +Per-device sync activity for the signed-in user. + +## Example response + +```json example-response +{ + "devices": [ + { + "device_id": "550e8400-e29b-41d4-a716-446655440000", + "device_name": "Kobo Clara", + "device_type": "kobo", + "sync_count": 42, + "last_sync": "2026-10-24T13:57:01Z", + "total_time_seconds": 3600, + "total_time_minutes": 60 + } + ] +} +``` + +## Query parameters + +UNVERIFIED: accepts the standard analytics date-range params; confirm exact +names before relying on them. + +## Errors + +| Status | Body | When | +| ------ | ---- | ---- | +| 500 | `{"error": "..."}` | unexpected server error | diff --git a/docs/developer/api/analytics/get_popular_books.md b/docs/developer/api/analytics/get_popular_books.md new file mode 100644 index 00000000..0123c36a --- /dev/null +++ b/docs/developer/api/analytics/get_popular_books.md @@ -0,0 +1,39 @@ +--- +method: GET +path: /api/analytics/popular-books +auth: jwt +area: analytics +--- + + +# Get Popular Books + +Most-read books for the signed-in user. + +## Example response + +```json example-response +{ + "books": [ + { + "media_item_id": "550e8400-e29b-41d4-a716-446655440000", + "title": "1984", + "author": "George Orwell", + "read_count": 3, + "avg_completion": 0.95, + "last_read": "2026-10-24T13:57:01Z" + } + ] +} +``` + +## Query parameters + +UNVERIFIED: accepts the standard analytics date-range params; confirm exact +names before relying on them. + +## Errors + +| Status | Body | When | +| ------ | ---- | ---- | +| 500 | `{"error": "..."}` | unexpected server error | diff --git a/docs/developer/api/jobs/create_job.md b/docs/developer/api/jobs/create_job.md new file mode 100644 index 00000000..12d5fb67 --- /dev/null +++ b/docs/developer/api/jobs/create_job.md @@ -0,0 +1,40 @@ +--- +method: POST +path: /api/jobs +auth: jwt +area: jobs +--- + + +# Create Job + +Enqueues a background job (scan, import, convert — the set accepted by the +worker). Success is **202 Accepted** with the job id; poll its status via +`GET /api/jobs/:jobId`. + +## Example request + +```json example-request +{ + "type": "import", + "params": { "library_id": "990e8400-e29b-41d4-a716-446655440000" } +} +``` + +## Example response + +```json example-response +{ + "message": "Job created", + "job_id": "ee0e8400-e29b-41d4-a716-446655440000", + "type": "import", + "status": "pending" +} +``` + +## Errors + +| Status | Body | When | +| ------ | ---- | ---- | +| 400 | `{"error": "Invalid job type"}` / others | unknown type or params | +| 500 | `{"error": "..."}` | enqueue failure | diff --git a/docs/developer/api/jobs/get_job_status.md b/docs/developer/api/jobs/get_job_status.md new file mode 100644 index 00000000..39c5e9e6 --- /dev/null +++ b/docs/developer/api/jobs/get_job_status.md @@ -0,0 +1,34 @@ +--- +method: GET +path: /api/jobs/:jobId +auth: jwt +area: jobs +--- + + +# Get Job Status + +Returns the in-memory status/result of a background job. + +## Example response + +```json example-response +{ + "job_id": "ee0e8400-e29b-41d4-a716-446655440000", + "status": "completed", + "error": "", + "result": null, + "progress": 100, + "files_scanned": 120, + "new_items": 3, + "errors": 0 +} +``` + +`library_id` and `job_type` appear only on scan jobs (`omitempty`). + +## Errors + +| Status | Body | When | +| ------ | ---- | ---- | +| 404 | `{"error": "Job not found"}` | unknown id, or the in-memory result was evicted by a restart | diff --git a/internal/docs/schema.go b/internal/docs/schema.go index 1e75d3c7..8dd1b974 100644 --- a/internal/docs/schema.go +++ b/internal/docs/schema.go @@ -238,4 +238,20 @@ var Schemas = map[string]Schema{ "GET /api/media-items/filter-count": { Response: json.RawMessage(`{"count": 0}`), }, + + // --- analytics + jobs (batch 4) --- + "GET /api/analytics/device-usage": { + Response: handlers.DeviceUsageResponse{}, + }, + "GET /api/analytics/popular-books": { + Response: handlers.PopularBooksResponse{}, + }, + "POST /api/jobs": { + // Inline anonymous request struct {type, params} — pinned by sample. + Request: json.RawMessage(`{"type": "", "params": {}}`), + Response: json.RawMessage(`{"message": "", "job_id": "", "type": "", "status": ""}`), + }, + "GET /api/jobs/:jobId": { + Response: services.JobResult{}, + }, }