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

@@ -2,7 +2,7 @@
"openapi": "3.1.0",
"info": {
"title": "ShopDB Flask API",
"version": "0.8.1",
"version": "0.9.0",
"description": "Asset-management API (core + plugins). Responses use a `success_response` envelope: `{status, data, meta}`. Auth: Bearer JWT (login or a managed PAT) for `jwt`/`admin`/`permission:*`; `X-API-Key` for collector/managed-token endpoints; public endpoints need neither."
},
"servers": [
@@ -3271,6 +3271,112 @@
}
}
},
"/api/applications/{app_id}/image": {
"post": {
"tags": [
"core-catalog"
],
"summary": "Upload or replace an application's image; sets application.image to the served URL",
"description": "Upload or replace an application's image; sets application.image to the served URL\n\n**Auth:** jwt + applications.edit\n\n**Params:** multipart/form-data: file=<image> (png/jpg/gif/webp/svg/ico)\n\n**Example:**\n```\ncurl -X POST -H 'Authorization: Bearer <token>' -F file=@logo.png http://localhost:5001/api/applications/5/image\n```",
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "Success (success_response envelope)"
}
}
},
"delete": {
"tags": [
"core-catalog"
],
"summary": "Remove an application's image and clear the field",
"description": "Remove an application's image and clear the field\n\n**Auth:** jwt + applications.edit\n\n**Params:** none\n\n**Example:**\n```\ncurl -X DELETE -H 'Authorization: Bearer <token>' http://localhost:5001/api/applications/5/image\n```",
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "Success (success_response envelope)"
}
}
}
},
"/api/applications/image/{filename}": {
"get": {
"tags": [
"core-catalog"
],
"summary": "Serve an uploaded application image. Public: application tiles render before login",
"description": "Serve an uploaded application image. Public: application tiles render before login\n\n**Auth:** none\n\n**Params:** none\n\n**Example:**\n```\ncurl http://localhost:5001/api/applications/image/application-5.png\n```",
"security": [],
"responses": {
"200": {
"description": "Success (success_response envelope)"
}
}
}
},
"/api/applications/{app_id}/package": {
"post": {
"tags": [
"core-catalog"
],
"summary": "Upload or replace the installer; sets installpath to the download URL",
"description": "Upload or replace the installer; sets installpath to the download URL\n\n**Auth:** jwt + applications.edit\n\n**Params:** multipart/form-data: file=<installer> (exe/msi/msp/zip/7z/cab/iso/appx/msix/ps1/bat/txt/pdf), max 500MB\n\n**Example:**\n```\ncurl -X POST -H 'Authorization: Bearer <token>' -F file=@setup.msi http://localhost:5001/api/applications/5/package\n```",
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "Success (success_response envelope)"
}
}
},
"delete": {
"tags": [
"core-catalog"
],
"summary": "Remove an uploaded installer; clears installpath only when it pointed at the upload",
"description": "Remove an uploaded installer; clears installpath only when it pointed at the upload\n\n**Auth:** jwt + applications.edit\n\n**Params:** none\n\n**Example:**\n```\ncurl -X DELETE -H 'Authorization: Bearer <token>' http://localhost:5001/api/applications/5/package\n```",
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "Success (success_response envelope)"
}
}
}
},
"/api/applications/package/{filename}": {
"get": {
"tags": [
"core-catalog"
],
"summary": "Download an uploaded installer as an attachment. Authenticated: licensed vendor software",
"description": "Download an uploaded installer as an attachment. Authenticated: licensed vendor software\n\n**Auth:** jwt + applications.view\n\n**Params:** none\n\n**Example:**\n```\ncurl -OJ -H 'Authorization: Bearer <token>' http://localhost:5001/api/applications/package/application-5.msi\n```",
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "Success (success_response envelope)"
}
}
}
},
"/api/computers/types": {
"get": {
"tags": [
@@ -6451,6 +6557,25 @@
}
}
},
"/api/printers/supplies/forecast": {
"get": {
"tags": [
"plugin-printers"
],
"summary": "Days-to-empty per printer from Zabbix history, soonest first, with cartridge replacement counts; printers with no honest",
"description": "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\n\n**Auth:** jwt-optional\n\n**Params:** days (1-365, default 90)\n\n**Example:**\n```\ncurl 'http://localhost:5001/api/printers/supplies/forecast?days=90'\n```",
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "Success (success_response envelope)"
}
}
}
},
"/api/warranty": {
"get": {
"tags": [
@@ -6615,6 +6740,61 @@
}
}
}
},
"/api/warranty/{warrantyid}/proof": {
"post": {
"tags": [
"plugin-warranty"
],
"summary": "Upload or replace the proof-of-cover document (invoice, certificate)",
"description": "Upload or replace the proof-of-cover document (invoice, certificate)\n\n**Auth:** jwt + warranty.edit\n\n**Params:** multipart/form-data: file=<document> (pdf/png/jpg/gif/webp/tif/msg/eml/doc/docx/xls/xlsx), max 25MB\n\n**Example:**\n```\ncurl -X POST -H 'Authorization: Bearer <token>' -F file=@invoice.pdf http://localhost:5001/api/warranty/12/proof\n```",
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "Success (success_response envelope)"
}
}
},
"delete": {
"tags": [
"plugin-warranty"
],
"summary": "Remove a proof document and clear both columns",
"description": "Remove a proof document and clear both columns\n\n**Auth:** jwt + warranty.edit\n\n**Params:** none\n\n**Example:**\n```\ncurl -X DELETE -H 'Authorization: Bearer <token>' http://localhost:5001/api/warranty/12/proof\n```",
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "Success (success_response envelope)"
}
}
}
},
"/api/warranty/proof/{filename}": {
"get": {
"tags": [
"plugin-warranty"
],
"summary": "Download a proof document under the vendor's original filename. Authenticated: carries pricing and a service tag",
"description": "Download a proof document under the vendor's original filename. Authenticated: carries pricing and a service tag\n\n**Auth:** jwt + warranty.view\n\n**Params:** none\n\n**Example:**\n```\ncurl -OJ -H 'Authorization: Bearer <token>' http://localhost:5001/api/warranty/proof/warranty-12.pdf\n```",
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "Success (success_response envelope)"
}
}
}
}
}
}