package api import ( "encoding/json" "net/http" ) func OpenAPI(w http.ResponseWriter, r *http.Request) { spec := map[string]any{ "openapi": "3.0.3", "info": map[string]any{ "title": "managerd API", "version": "v1", }, "paths": map[string]any{ "/health": map[string]any{ "get": map[string]any{ "responses": map[string]any{ "200": map[string]any{ "description": "ok", "content": map[string]any{"text/plain": map[string]any{}}, }, }, }, }, "/api/discovery/search": map[string]any{ "post": map[string]any{ "requestBody": map[string]any{ "required": true, "content": map[string]any{ "application/json": map[string]any{ "schema": map[string]any{ "type": "object", "properties": map[string]any{"timeout_ms": map[string]any{"type": "integer"}}, }, }, }, }, "responses": map[string]any{ "200": map[string]any{ "description": "devices", "content": map[string]any{"application/json": map[string]any{"schema": map[string]any{"type": "object"}}}, }, }, }, }, "/api/devices": map[string]any{ "get": map[string]any{ "responses": map[string]any{ "200": map[string]any{ "description": "devices", "content": map[string]any{"application/json": map[string]any{"schema": map[string]any{"type": "object"}}}, }, }, }, "post": map[string]any{ "requestBody": map[string]any{ "required": true, "content": map[string]any{ "application/json": map[string]any{ "schema": map[string]any{ "type": "object", "properties": map[string]any{ "device_id": map[string]any{"type": "string"}, "device_name": map[string]any{"type": "string"}, "ip": map[string]any{"type": "string"}, "agent_port": map[string]any{"type": "integer"}, "media_port": map[string]any{"type": "integer"}, }, "required": []any{"device_id", "ip"}, }, }, }, }, "responses": map[string]any{"200": map[string]any{"description": "ok"}}, }, }, "/api/devices/{id}": map[string]any{ "get": map[string]any{ "parameters": []any{map[string]any{"name": "id", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}}, "responses": map[string]any{"200": map[string]any{"description": "device", "content": map[string]any{"application/json": map[string]any{"schema": map[string]any{"type": "object"}}}}}, }, }, "/api/devices/{id}/info": map[string]any{ "get": map[string]any{ "parameters": []any{map[string]any{"name": "id", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}}, "responses": map[string]any{"200": map[string]any{"description": "agent info", "content": map[string]any{"application/json": map[string]any{"schema": map[string]any{"type": "object"}}}}}, }, }, "/api/devices/{id}/reload": map[string]any{ "post": map[string]any{ "parameters": []any{map[string]any{"name": "id", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}}, "responses": map[string]any{"200": map[string]any{"description": "ok"}}, }, }, "/api/devices/{id}/rollback": map[string]any{ "post": map[string]any{ "parameters": []any{map[string]any{"name": "id", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}}, "responses": map[string]any{"200": map[string]any{"description": "ok"}}, }, }, "/api/devices/{id}/media-server/start": map[string]any{ "post": map[string]any{ "parameters": []any{map[string]any{"name": "id", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}}, "responses": map[string]any{"200": map[string]any{"description": "ok"}}, }, }, "/api/devices/{id}/media-server/restart": map[string]any{ "post": map[string]any{ "parameters": []any{map[string]any{"name": "id", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}}, "responses": map[string]any{"200": map[string]any{"description": "ok"}}, }, }, "/api/devices/{id}/media-server/stop": map[string]any{ "post": map[string]any{ "parameters": []any{map[string]any{"name": "id", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}}, "responses": map[string]any{"200": map[string]any{"description": "ok"}}, }, }, "/api/devices/{id}/media-server/status": map[string]any{ "get": map[string]any{ "parameters": []any{map[string]any{"name": "id", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}}, "responses": map[string]any{"200": map[string]any{"description": "status", "content": map[string]any{"application/json": map[string]any{"schema": map[string]any{"type": "object"}}}}}, }, }, "/api/devices/{id}/graphs": map[string]any{ "get": map[string]any{ "parameters": []any{map[string]any{"name": "id", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}}, "responses": map[string]any{"200": map[string]any{"description": "graphs", "content": map[string]any{"application/json": map[string]any{"schema": map[string]any{"type": "object"}}}}}, }, }, "/api/devices/{id}/graphs/{name}": map[string]any{ "get": map[string]any{ "parameters": []any{ map[string]any{"name": "id", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}, map[string]any{"name": "name", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}, }, "responses": map[string]any{"200": map[string]any{"description": "graph", "content": map[string]any{"application/json": map[string]any{"schema": map[string]any{"type": "object"}}}}}, }, }, "/api/devices/{id}/logs": map[string]any{ "get": map[string]any{ "parameters": []any{ map[string]any{"name": "id", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}, map[string]any{"name": "limit", "in": "query", "required": false, "schema": map[string]any{"type": "integer"}}, }, "responses": map[string]any{"200": map[string]any{"description": "logs", "content": map[string]any{"application/json": map[string]any{"schema": map[string]any{"type": "object"}}}}}, }, }, "/api/devices/{id}/config/apply": map[string]any{ "post": map[string]any{ "parameters": []any{map[string]any{"name": "id", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}}, "requestBody": map[string]any{ "required": true, "content": map[string]any{"application/json": map[string]any{"schema": map[string]any{"type": "object"}}}, }, "responses": map[string]any{"200": map[string]any{"description": "ok"}}, }, }, "/api/devices/{id}/models": map[string]any{ "get": map[string]any{ "parameters": []any{map[string]any{"name": "id", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}}, "responses": map[string]any{"200": map[string]any{"description": "models", "content": map[string]any{"application/json": map[string]any{"schema": map[string]any{"type": "object"}}}}}, }, }, "/api/devices/{id}/models/upload": map[string]any{ "post": map[string]any{ "parameters": []any{map[string]any{"name": "id", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}}, "requestBody": map[string]any{ "required": true, "content": map[string]any{ "multipart/form-data": map[string]any{ "schema": map[string]any{ "type": "object", "properties": map[string]any{ "name": map[string]any{"type": "string"}, "file": map[string]any{"type": "string", "format": "binary"}, }, "required": []any{"name", "file"}, }, }, }, }, "responses": map[string]any{"200": map[string]any{"description": "ok"}}, }, }, "/api/devices/{id}/v1/config": map[string]any{ "get": map[string]any{ "parameters": []any{map[string]any{"name": "id", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}}, "responses": map[string]any{"200": map[string]any{"description": "config", "content": map[string]any{"application/json": map[string]any{"schema": map[string]any{"type": "object"}}}}}, }, "put": map[string]any{ "parameters": []any{map[string]any{"name": "id", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}}, "requestBody": map[string]any{ "required": true, "content": map[string]any{"application/json": map[string]any{"schema": map[string]any{"type": "object"}}}, }, "responses": map[string]any{"200": map[string]any{"description": "ok"}}, }, }, "/api/devices/{id}/v1/config/ui/schema": map[string]any{ "get": map[string]any{ "parameters": []any{map[string]any{"name": "id", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}}, "responses": map[string]any{"200": map[string]any{"description": "schema", "content": map[string]any{"application/json": map[string]any{"schema": map[string]any{"type": "object"}}}}}, }, }, "/api/devices/{id}/v1/config/ui/state": map[string]any{ "get": map[string]any{ "parameters": []any{map[string]any{"name": "id", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}}, "responses": map[string]any{"200": map[string]any{"description": "state", "content": map[string]any{"application/json": map[string]any{"schema": map[string]any{"type": "object"}}}}}, }, }, "/api/devices/{id}/v1/config/ui/plan": map[string]any{ "post": map[string]any{ "parameters": []any{map[string]any{"name": "id", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}}, "requestBody": map[string]any{ "required": true, "content": map[string]any{"application/json": map[string]any{"schema": map[string]any{"type": "object"}}}, }, "responses": map[string]any{"200": map[string]any{"description": "plan", "content": map[string]any{"application/json": map[string]any{"schema": map[string]any{"type": "object"}}}}}, }, }, "/api/devices/{id}/v1/config/ui/apply": map[string]any{ "post": map[string]any{ "parameters": []any{map[string]any{"name": "id", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}}, "requestBody": map[string]any{ "required": true, "content": map[string]any{"application/json": map[string]any{"schema": map[string]any{"type": "object"}}}, }, "responses": map[string]any{"200": map[string]any{"description": "ok"}}, }, }, "/api/devices/{id}/v1/face-gallery": map[string]any{ "get": map[string]any{ "parameters": []any{map[string]any{"name": "id", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}}, "responses": map[string]any{"200": map[string]any{"description": "face gallery info", "content": map[string]any{"application/json": map[string]any{"schema": map[string]any{"type": "object"}}}}}, }, "put": map[string]any{ "parameters": []any{map[string]any{"name": "id", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}}, "requestBody": map[string]any{ "required": true, "content": map[string]any{"application/octet-stream": map[string]any{"schema": map[string]any{"type": "string", "format": "binary"}}}, }, "responses": map[string]any{"200": map[string]any{"description": "ok"}}, }, }, "/api/devices/{id}/v1/face-gallery/reload": map[string]any{ "post": map[string]any{ "parameters": []any{map[string]any{"name": "id", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}}, "responses": map[string]any{"200": map[string]any{"description": "ok"}}, }, }, "/api/templates": map[string]any{ "get": map[string]any{ "responses": map[string]any{"200": map[string]any{"description": "templates", "content": map[string]any{"application/json": map[string]any{"schema": map[string]any{"type": "array"}}}}}, }, }, "/api/templates/{name}": map[string]any{ "get": map[string]any{ "parameters": []any{map[string]any{"name": "name", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}}, "responses": map[string]any{"200": map[string]any{"description": "template", "content": map[string]any{"application/json": map[string]any{"schema": map[string]any{"type": "object"}}}}}, }, }, "/api/tasks": map[string]any{ "get": map[string]any{ "responses": map[string]any{"200": map[string]any{"description": "tasks", "content": map[string]any{"application/json": map[string]any{"schema": map[string]any{"type": "object"}}}}}, }, "post": map[string]any{ "requestBody": map[string]any{ "required": true, "content": map[string]any{"application/json": map[string]any{"schema": map[string]any{"type": "object"}}}, }, "responses": map[string]any{"200": map[string]any{"description": "task_id", "content": map[string]any{"application/json": map[string]any{"schema": map[string]any{"type": "object"}}}}}, }, }, "/api/tasks/{id}/events": map[string]any{ "get": map[string]any{ "parameters": []any{map[string]any{"name": "id", "in": "path", "required": true, "schema": map[string]any{"type": "string"}}}, "responses": map[string]any{"200": map[string]any{"description": "SSE", "content": map[string]any{"text/event-stream": map[string]any{}}}}, }, }, }, } w.Header().Set("Content-Type", "application/json; charset=utf-8") _ = json.NewEncoder(w).Encode(spec) }