Document the upload, proof and forecast endpoints
Some checks failed
CI / backend (push) Failing after 9s
CI / naming (push) Successful in 2s
CI / frontend (push) Successful in 10s
CI / migrations-mysql (push) Failing after 7s

Ten routes shipped over the last few commits without reaching the inventory,
which is the file everything else is generated from - openapi.json, the /api/docs
browser, and the per-site build. An endpoint absent from it is invisible to
anyone integrating against the API even though it answers requests.

The auth notes matter more than the paths. API-REFERENCE tells a deployment
reviewer that essentially every GET is optional-auth; two of these are not, and
an exception buried in a table of 372 operations is one nobody reads. The
installer download and the warranty proof are called out with why: one is
licensed vendor software, the other carries pricing and a service tag. The
application image is listed with the fully public endpoints, since tiles render
before login.
This commit is contained in:
cproudlock
2026-08-12 12:06:25 -04:00
parent ea35a134fe
commit a64796f060
4 changed files with 302 additions and 1 deletions

View File

@@ -1437,6 +1437,54 @@
"auth": "permission:applications.edit",
"params": "body: appversionid",
"example": "curl -X PUT http://localhost:5001/api/applications/machines/8/15 -H \"Authorization: Bearer $TOK\" -H 'Content-Type: application/json' -d '{\"appversionid\":3}'"
},
{
"method": "POST",
"path": "/api/applications/<app_id>/image",
"auth": "jwt + applications.edit",
"params": "multipart/form-data: file=<image> (png/jpg/gif/webp/svg/ico)",
"purpose": "Upload or replace an application's image; sets application.image to the served URL",
"example": "curl -X POST -H 'Authorization: Bearer <token>' -F file=@logo.png http://localhost:5001/api/applications/5/image"
},
{
"method": "GET",
"path": "/api/applications/image/<filename>",
"auth": "none",
"params": "none",
"purpose": "Serve an uploaded application image. Public: application tiles render before login",
"example": "curl http://localhost:5001/api/applications/image/application-5.png"
},
{
"method": "DELETE",
"path": "/api/applications/<app_id>/image",
"auth": "jwt + applications.edit",
"params": "none",
"purpose": "Remove an application's image and clear the field",
"example": "curl -X DELETE -H 'Authorization: Bearer <token>' http://localhost:5001/api/applications/5/image"
},
{
"method": "POST",
"path": "/api/applications/<app_id>/package",
"auth": "jwt + applications.edit",
"params": "multipart/form-data: file=<installer> (exe/msi/msp/zip/7z/cab/iso/appx/msix/ps1/bat/txt/pdf), max 500MB",
"purpose": "Upload or replace the installer; sets installpath to the download URL",
"example": "curl -X POST -H 'Authorization: Bearer <token>' -F file=@setup.msi http://localhost:5001/api/applications/5/package"
},
{
"method": "GET",
"path": "/api/applications/package/<filename>",
"auth": "jwt + applications.view",
"params": "none",
"purpose": "Download an uploaded installer as an attachment. Authenticated: licensed vendor software",
"example": "curl -OJ -H 'Authorization: Bearer <token>' http://localhost:5001/api/applications/package/application-5.msi"
},
{
"method": "DELETE",
"path": "/api/applications/<app_id>/package",
"auth": "jwt + applications.edit",
"params": "none",
"purpose": "Remove an uploaded installer; clears installpath only when it pointed at the upload",
"example": "curl -X DELETE -H 'Authorization: Bearer <token>' http://localhost:5001/api/applications/5/package"
}
]
},
@@ -2895,6 +2943,14 @@
"params": "path: modelsupplyid",
"purpose": "Hard-delete a model supply mapping.",
"example": "curl -X DELETE -H \"Authorization: Bearer $TOKEN\" http://localhost:5001/api/printers/supplies/44"
},
{
"method": "GET",
"path": "/api/printers/supplies/forecast",
"auth": "jwt-optional",
"params": "days (1-365, default 90)",
"purpose": "Days-to-empty per printer from Zabbix history, soonest first, with cartridge replacement counts; printers with no honest estimate are returned separately with the reason. available=false when Zabbix is unreachable",
"example": "curl 'http://localhost:5001/api/printers/supplies/forecast?days=90'"
}
]
},
@@ -2972,6 +3028,30 @@
"auth": "jwt-optional",
"params": "none",
"example": "curl -H \"Authorization: Bearer $TOKEN\" http://localhost:5001/api/warranty/report"
},
{
"method": "POST",
"path": "/api/warranty/<warrantyid>/proof",
"auth": "jwt + warranty.edit",
"params": "multipart/form-data: file=<document> (pdf/png/jpg/gif/webp/tif/msg/eml/doc/docx/xls/xlsx), max 25MB",
"purpose": "Upload or replace the proof-of-cover document (invoice, certificate)",
"example": "curl -X POST -H 'Authorization: Bearer <token>' -F file=@invoice.pdf http://localhost:5001/api/warranty/12/proof"
},
{
"method": "GET",
"path": "/api/warranty/proof/<filename>",
"auth": "jwt + warranty.view",
"params": "none",
"purpose": "Download a proof document under the vendor's original filename. Authenticated: carries pricing and a service tag",
"example": "curl -OJ -H 'Authorization: Bearer <token>' http://localhost:5001/api/warranty/proof/warranty-12.pdf"
},
{
"method": "DELETE",
"path": "/api/warranty/<warrantyid>/proof",
"auth": "jwt + warranty.edit",
"params": "none",
"purpose": "Remove a proof document and clear both columns",
"example": "curl -X DELETE -H 'Authorization: Bearer <token>' http://localhost:5001/api/warranty/12/proof"
}
]
}