From afb4fe9053e2cd3eb0a48253a4ff7cb714c5a70b Mon Sep 17 00:00:00 2001 From: "Enot (ded) Skelly" Date: Tue, 2 Jun 2026 08:38:36 -0700 Subject: [PATCH] update swag comments fixes issue with generics not being parsed --- README.md | 2 +- docs/docs.go | 618 ++++++++++++++++++++++++----- docs/swagger.json | 602 ++++++++++++++++++++++++---- docs/swagger.yaml | 465 ++++++++++++++++++---- internal/api/handlers/channels.go | 4 +- internal/api/handlers/messages.go | 2 +- internal/api/handlers/nodes.go | 10 +- internal/api/handlers/observers.go | 6 +- internal/api/handlers/packets.go | 1 + internal/api/handlers/stats.go | 2 +- 10 files changed, 1428 insertions(+), 284 deletions(-) diff --git a/README.md b/README.md index e1a190a..197655d 100644 --- a/README.md +++ b/README.md @@ -340,7 +340,7 @@ After adding or modifying any handler, regenerate the docs and commit the updated `docs/` directory alongside your handler changes: ```bash -swag init -g cmd/tower/main.go -o docs +swag init -g cmd/tower/main.go -o docs --parseDependecy ``` Install swag: diff --git a/docs/docs.go b/docs/docs.go index dcad2a9..cd002aa 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -4,11 +4,11 @@ package docs import "github.com/swaggo/swag" const docTemplate = `{ - "schemes": {{ marshal .Schemes }}, + "schemes": [[ marshal .Schemes ]], "swagger": "2.0", "info": { - "description": "{{escape .Description}}", - "title": "{{.Title}}", + "description": "[[escape .Description]]", + "title": "[[.Title]]", "termsOfService": "https://github.com/MeshCore-Tower/tower-server", "contact": { "name": "MeshCore Tower", @@ -17,10 +17,10 @@ const docTemplate = `{ "license": { "name": "MIT" }, - "version": "{{.Version}}" + "version": "[[.Version]]" }, - "host": "{{.Host}}", - "basePath": "{{.BasePath}}", + "host": "[[.Host]]", + "basePath": "[[.BasePath]]", "paths": { "/brokers": { "get": { @@ -37,7 +37,7 @@ const docTemplate = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/handlers.BrokerStatus" + "$ref": "#/definitions/internal_api_handlers.BrokerStatus" } } } @@ -83,19 +83,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_ChannelSummary" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -123,19 +123,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/api.Channel" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Channel" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "404": { "description": "Not Found", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -187,19 +187,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_ChannelMessage" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -220,14 +220,14 @@ const docTemplate = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/api.IATA" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.IATA" } } }, "404": { "description": "Not Found", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -255,13 +255,13 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/api.IATA" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.IATA" } }, "404": { "description": "Not Found", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -318,19 +318,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_ChannelMessage" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -378,13 +378,13 @@ const docTemplate = `{ }, { "type": "boolean", - "description": "Filter to nodes with firmware \u003e= 1.14.0", + "description": "Filter by multibyte path support (true/false); omit for no filter", "name": "supportsMultibytePaths", "in": "query" }, { "type": "boolean", - "description": "Filter to nodes with firmware \u003e= 1.11.0", + "description": "Filter by multibyte trace support (true/false); omit for no filter", "name": "supportsMultibyteTraces", "in": "query" }, @@ -405,13 +405,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_NodeSummary" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -439,19 +445,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/api.Node" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Node" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "404": { "description": "Not Found", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -491,19 +497,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_PacketObservationSummary" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -566,13 +572,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_ObserverSummary" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -600,19 +612,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/api.Observer" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Observer" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "404": { "description": "Not Found", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -652,19 +664,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_AdvertObservation" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -698,25 +710,31 @@ const docTemplate = `{ "description": "Return points after this telemetry ID for WS reconnection backfill", "name": "afterId", "in": "query" + }, + { + "type": "string", + "description": "Bucketing interval, echoed back in the response; not yet applied server-side", + "name": "interval", + "in": "query" } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/api.ObserverTelemetry" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ObserverTelemetry" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -752,7 +770,7 @@ const docTemplate = `{ }, { "type": "string", - "description": "Filter by latest observation IATA (case-insensitive)", + "description": "Filter by IATA code", "name": "iata", "in": "query" }, @@ -785,13 +803,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "type": "object" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_PacketSummary" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -819,19 +843,25 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/api.Packet" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Packet" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "404": { "description": "Not Found", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -852,14 +882,14 @@ const docTemplate = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/api.RegionSummary" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.RegionSummary" } } }, "404": { "description": "Not Found", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -887,19 +917,19 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/api.Region" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Region" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "404": { "description": "Not Found", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -934,14 +964,14 @@ const docTemplate = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/api.ObservationPoint" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ObservationPoint" } } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -968,13 +998,13 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/api.StatsOverview" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.StatsOverview" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -1009,14 +1039,14 @@ const docTemplate = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/api.PayloadBreakdownItem" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.PayloadBreakdownItem" } } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -1034,7 +1064,7 @@ const docTemplate = `{ "parameters": [ { "type": "string", - "description": "Filter by IATA code (case-insensitive)", + "description": "Filter by exact IATA code (case-sensitive)", "name": "iata", "in": "query" }, @@ -1051,14 +1081,14 @@ const docTemplate = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/api.TopNode" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.TopNode" } } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -1099,14 +1129,14 @@ const docTemplate = `{ "schema": { "type": "array", "items": { - "$ref": "#/definitions/api.TopObserver" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.TopObserver" } } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -1114,7 +1144,48 @@ const docTemplate = `{ } }, "definitions": { - "api.Channel": { + "github_com_MeshCore-Tower_tower-server_internal_api.AdvertObservation": { + "type": "object", + "properties": { + "heardAt": { + "description": "epoch ms", + "type": "integer" + }, + "hopCount": { + "type": "integer" + }, + "iata": { + "type": "string" + }, + "id": { + "description": "observation ID, use as cursor for pagination", + "type": "integer" + }, + "nodeName": { + "type": "string" + }, + "nodePublicKey": { + "type": "string" + }, + "packetHash": { + "description": "hex-encoded", + "type": "string" + }, + "payloadType": { + "type": "integer" + }, + "payloadTypeName": { + "type": "string" + }, + "rssi": { + "type": "integer" + }, + "snr": { + "type": "number" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.Channel": { "type": "object", "properties": { "channelHash": { @@ -1153,7 +1224,67 @@ const docTemplate = `{ } } }, - "api.IATA": { + "github_com_MeshCore-Tower_tower-server_internal_api.ChannelMessage": { + "type": "object", + "properties": { + "channelHash": { + "description": "hex-encoded single-byte channel hash", + "type": "string" + }, + "content": { + "description": "decrypted message text", + "type": "string" + }, + "id": { + "type": "integer" + }, + "observationCount": { + "description": "the number of observations for this message packet hash", + "type": "integer" + }, + "packetHash": { + "description": "hex-encoded packet hash for correlation with packet events", + "type": "string" + }, + "senderName": { + "description": "display name from the decrypted payload", + "type": "string" + }, + "sentAt": { + "description": "epoch ms", + "type": "integer" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.ChannelSummary": { + "type": "object", + "properties": { + "channelHash": { + "description": "hex-encoded single-byte hash", + "type": "string" + }, + "id": { + "type": "integer" + }, + "isHashtag": { + "description": "true if derived from a hashtag PSK", + "type": "boolean" + }, + "keyKnown": { + "description": "true if Tower has a decryption key", + "type": "boolean" + }, + "lastSeen": { + "description": "epoch ms", + "type": "integer" + }, + "name": { + "description": "display name, nil if not set", + "type": "string" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.IATA": { "type": "object", "properties": { "displayName": { @@ -1170,7 +1301,7 @@ const docTemplate = `{ } } }, - "api.Node": { + "github_com_MeshCore-Tower_tower-server_internal_api.Node": { "type": "object", "properties": { "firstSeen": { @@ -1180,7 +1311,7 @@ const docTemplate = `{ "iatas": { "type": "array", "items": { - "type": "string" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.NodeIATA" } }, "id": { @@ -1231,6 +1362,9 @@ const docTemplate = `{ "description": "hex-encoded public key", "type": "string" }, + "radio": { + "type": "string" + }, "supportsMultibytePaths": { "description": "firmware \u003e= 1.14.0", "type": "boolean" @@ -1241,7 +1375,62 @@ const docTemplate = `{ } } }, - "api.ObservationPoint": { + "github_com_MeshCore-Tower_tower-server_internal_api.NodeIATA": { + "type": "object", + "properties": { + "iata": { + "type": "string" + }, + "lastHeard": { + "description": "epoch ms", + "type": "integer" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.NodeSummary": { + "type": "object", + "properties": { + "iatas": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.NodeIATA" + } + }, + "id": { + "type": "string" + }, + "isObserver": { + "type": "boolean" + }, + "lat": { + "type": "number" + }, + "lng": { + "type": "number" + }, + "name": { + "type": "string" + }, + "nodeType": { + "description": "1=companion, 2=repeater, 3=room server", + "type": "integer" + }, + "nodeTypeName": { + "type": "string" + }, + "observerId": { + "type": "string" + }, + "publicKey": { + "description": "hex-encoded public key", + "type": "string" + }, + "radio": { + "type": "string" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.ObservationPoint": { "type": "object", "properties": { "activeObservers": { @@ -1262,7 +1451,7 @@ const docTemplate = `{ } } }, - "api.Observer": { + "github_com_MeshCore-Tower_tower-server_internal_api.Observer": { "type": "object", "properties": { "batteryLevel": { @@ -1273,7 +1462,7 @@ const docTemplate = `{ "description": "broker names this observer has been seen on", "type": "array", "items": { - "$ref": "#/definitions/api.ObserverBroker" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ObserverBroker" } }, "displayName": { @@ -1319,6 +1508,9 @@ const docTemplate = `{ "description": "hex-encoded public key", "type": "string" }, + "radio": { + "type": "string" + }, "radioBwKhz": { "description": "bandwidth in kHz", "type": "number" @@ -1350,7 +1542,7 @@ const docTemplate = `{ } } }, - "api.ObserverBroker": { + "github_com_MeshCore-Tower_tower-server_internal_api.ObserverBroker": { "type": "object", "properties": { "lastPacketAt": { @@ -1367,7 +1559,34 @@ const docTemplate = `{ } } }, - "api.ObserverTelemetry": { + "github_com_MeshCore-Tower_tower-server_internal_api.ObserverSummary": { + "type": "object", + "properties": { + "displayName": { + "description": "friendly name from /status messages", + "type": "string" + }, + "iata": { + "description": "most recently heard IATA", + "type": "string" + }, + "id": { + "type": "string" + }, + "observerType": { + "description": "e.g. \"meshcoretomqtt\", \"meshcoreha\"", + "type": "string" + }, + "radio": { + "type": "string" + }, + "status": { + "description": "\"online\" or \"offline\" derived from last_status_at", + "type": "string" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.ObserverTelemetry": { "type": "object", "properties": { "interval": { @@ -1376,7 +1595,7 @@ const docTemplate = `{ "points": { "type": "array", "items": { - "$ref": "#/definitions/api.ObserverTelemetryPoint" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ObserverTelemetryPoint" } }, "range": { @@ -1384,7 +1603,7 @@ const docTemplate = `{ } } }, - "api.ObserverTelemetryPoint": { + "github_com_MeshCore-Tower_tower-server_internal_api.ObserverTelemetryPoint": { "type": "object", "properties": { "airtimeRxPct": { @@ -1414,7 +1633,7 @@ const docTemplate = `{ } } }, - "api.Packet": { + "github_com_MeshCore-Tower_tower-server_internal_api.Packet": { "type": "object", "properties": { "channelHash": { @@ -1438,7 +1657,7 @@ const docTemplate = `{ "observations": { "type": "array", "items": { - "$ref": "#/definitions/api.PacketObservationDetail" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.PacketObservationDetail" } }, "originPubkey": { @@ -1478,7 +1697,21 @@ const docTemplate = `{ } } }, - "api.PacketObservationDetail": { + "github_com_MeshCore-Tower_tower-server_internal_api.PacketLatestObserver": { + "type": "object", + "properties": { + "displayName": { + "type": "string" + }, + "iata": { + "type": "string" + }, + "id": { + "type": "string" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.PacketObservationDetail": { "type": "object", "properties": { "hashSize": { @@ -1514,12 +1747,12 @@ const docTemplate = `{ "type": "integer" }, "radio": { - "$ref": "#/definitions/api.PacketRadio" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.PacketRadio" }, "resolvedPath": { "type": "array", "items": { - "$ref": "#/definitions/api.ResolvedHop" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ResolvedHop" } }, "rssi": { @@ -1533,7 +1766,42 @@ const docTemplate = `{ } } }, - "api.PacketRadio": { + "github_com_MeshCore-Tower_tower-server_internal_api.PacketObservationSummary": { + "type": "object", + "properties": { + "heardAt": { + "description": "epoch ms", + "type": "integer" + }, + "hopCount": { + "type": "integer" + }, + "iata": { + "type": "string" + }, + "id": { + "description": "observation ID, use as cursor for pagination", + "type": "integer" + }, + "packetHash": { + "description": "hex-encoded", + "type": "string" + }, + "payloadType": { + "type": "integer" + }, + "payloadTypeName": { + "type": "string" + }, + "rssi": { + "type": "integer" + }, + "snr": { + "type": "number" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.PacketRadio": { "type": "object", "properties": { "bandwidthKhz": { @@ -1550,7 +1818,165 @@ const docTemplate = `{ } } }, - "api.PayloadBreakdownItem": { + "github_com_MeshCore-Tower_tower-server_internal_api.PacketSummary": { + "type": "object", + "properties": { + "firstHeardAt": { + "description": "epoch ms", + "type": "integer" + }, + "lastHeardAt": { + "description": "epoch ms", + "type": "integer" + }, + "latestObserver": { + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.PacketLatestObserver" + }, + "observationCount": { + "type": "integer" + }, + "packetHash": { + "description": "hex-encoded", + "type": "string" + }, + "payloadType": { + "type": "integer" + }, + "payloadTypeName": { + "type": "string" + }, + "routeType": { + "type": "integer" + }, + "routeTypeName": { + "type": "string" + }, + "summary": { + "description": "human-readable payload summary", + "type": "string" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_AdvertObservation": { + "type": "object", + "properties": { + "hasMore": { + "type": "boolean" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.AdvertObservation" + } + }, + "nextCursor": { + "type": "integer" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_ChannelMessage": { + "type": "object", + "properties": { + "hasMore": { + "type": "boolean" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ChannelMessage" + } + }, + "nextCursor": { + "type": "integer" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_ChannelSummary": { + "type": "object", + "properties": { + "hasMore": { + "type": "boolean" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ChannelSummary" + } + }, + "nextCursor": { + "type": "integer" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_NodeSummary": { + "type": "object", + "properties": { + "hasMore": { + "type": "boolean" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.NodeSummary" + } + }, + "nextCursor": { + "type": "integer" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_ObserverSummary": { + "type": "object", + "properties": { + "hasMore": { + "type": "boolean" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ObserverSummary" + } + }, + "nextCursor": { + "type": "integer" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_PacketObservationSummary": { + "type": "object", + "properties": { + "hasMore": { + "type": "boolean" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.PacketObservationSummary" + } + }, + "nextCursor": { + "type": "integer" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_PacketSummary": { + "type": "object", + "properties": { + "hasMore": { + "type": "boolean" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.PacketSummary" + } + }, + "nextCursor": { + "type": "integer" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.PayloadBreakdownItem": { "type": "object", "properties": { "count": { @@ -1564,7 +1990,7 @@ const docTemplate = `{ } } }, - "api.Region": { + "github_com_MeshCore-Tower_tower-server_internal_api.Region": { "type": "object", "properties": { "centerLat": { @@ -1601,7 +2027,7 @@ const docTemplate = `{ } } }, - "api.RegionSummary": { + "github_com_MeshCore-Tower_tower-server_internal_api.RegionSummary": { "type": "object", "properties": { "id": { @@ -1616,7 +2042,7 @@ const docTemplate = `{ } } }, - "api.ResolvedHop": { + "github_com_MeshCore-Tower_tower-server_internal_api.ResolvedHop": { "type": "object", "properties": { "confidence": { @@ -1624,11 +2050,11 @@ const docTemplate = `{ "type": "string" }, "node": { - "$ref": "#/definitions/api.ResolvedNode" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ResolvedNode" } } }, - "api.ResolvedNode": { + "github_com_MeshCore-Tower_tower-server_internal_api.ResolvedNode": { "type": "object", "properties": { "id": { @@ -1649,7 +2075,7 @@ const docTemplate = `{ } } }, - "api.StatsOverview": { + "github_com_MeshCore-Tower_tower-server_internal_api.StatsOverview": { "type": "object", "properties": { "activeIatas": { @@ -1670,7 +2096,7 @@ const docTemplate = `{ } } }, - "api.TopNode": { + "github_com_MeshCore-Tower_tower-server_internal_api.TopNode": { "type": "object", "properties": { "iata": { @@ -1697,7 +2123,7 @@ const docTemplate = `{ } } }, - "api.TopObserver": { + "github_com_MeshCore-Tower_tower-server_internal_api.TopObserver": { "type": "object", "properties": { "displayName": { @@ -1717,7 +2143,7 @@ const docTemplate = `{ } } }, - "handlers.APIError": { + "internal_api_handlers.APIError": { "type": "object", "properties": { "code": { @@ -1730,7 +2156,7 @@ const docTemplate = `{ } } }, - "handlers.BrokerStatus": { + "internal_api_handlers.BrokerStatus": { "type": "object", "properties": { "connected": { @@ -1792,8 +2218,8 @@ var SwaggerInfo = &swag.Spec{ Description: "MeshCore network observation backend. Ingests LoRa packets from MQTT brokers, stores in PostgreSQL, and streams live events via WebSocket.", InfoInstanceName: "swagger", SwaggerTemplate: docTemplate, - LeftDelim: "{{", - RightDelim: "}}", + LeftDelim: "[[", + RightDelim: "]]", } func init() { diff --git a/docs/swagger.json b/docs/swagger.json index 8ff1f94..a2f63d9 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -35,7 +35,7 @@ "schema": { "type": "array", "items": { - "$ref": "#/definitions/handlers.BrokerStatus" + "$ref": "#/definitions/internal_api_handlers.BrokerStatus" } } } @@ -81,19 +81,19 @@ "200": { "description": "OK", "schema": { - "type": "object" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_ChannelSummary" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -121,19 +121,19 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/api.Channel" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Channel" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "404": { "description": "Not Found", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -185,19 +185,19 @@ "200": { "description": "OK", "schema": { - "type": "object" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_ChannelMessage" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -218,14 +218,14 @@ "schema": { "type": "array", "items": { - "$ref": "#/definitions/api.IATA" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.IATA" } } }, "404": { "description": "Not Found", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -253,13 +253,13 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/api.IATA" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.IATA" } }, "404": { "description": "Not Found", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -316,19 +316,19 @@ "200": { "description": "OK", "schema": { - "type": "object" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_ChannelMessage" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -376,13 +376,13 @@ }, { "type": "boolean", - "description": "Filter to nodes with firmware \u003e= 1.14.0", + "description": "Filter by multibyte path support (true/false); omit for no filter", "name": "supportsMultibytePaths", "in": "query" }, { "type": "boolean", - "description": "Filter to nodes with firmware \u003e= 1.11.0", + "description": "Filter by multibyte trace support (true/false); omit for no filter", "name": "supportsMultibyteTraces", "in": "query" }, @@ -403,13 +403,19 @@ "200": { "description": "OK", "schema": { - "type": "object" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_NodeSummary" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -437,19 +443,19 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/api.Node" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Node" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "404": { "description": "Not Found", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -489,19 +495,19 @@ "200": { "description": "OK", "schema": { - "type": "object" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_PacketObservationSummary" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -564,13 +570,19 @@ "200": { "description": "OK", "schema": { - "type": "object" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_ObserverSummary" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -598,19 +610,19 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/api.Observer" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Observer" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "404": { "description": "Not Found", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -650,19 +662,19 @@ "200": { "description": "OK", "schema": { - "type": "object" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_AdvertObservation" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -696,25 +708,31 @@ "description": "Return points after this telemetry ID for WS reconnection backfill", "name": "afterId", "in": "query" + }, + { + "type": "string", + "description": "Bucketing interval, echoed back in the response; not yet applied server-side", + "name": "interval", + "in": "query" } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/api.ObserverTelemetry" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ObserverTelemetry" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -750,7 +768,7 @@ }, { "type": "string", - "description": "Filter by latest observation IATA (case-insensitive)", + "description": "Filter by IATA code", "name": "iata", "in": "query" }, @@ -783,13 +801,19 @@ "200": { "description": "OK", "schema": { - "type": "object" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_PacketSummary" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -817,19 +841,25 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/api.Packet" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Packet" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "404": { "description": "Not Found", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" + } + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -850,14 +880,14 @@ "schema": { "type": "array", "items": { - "$ref": "#/definitions/api.RegionSummary" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.RegionSummary" } } }, "404": { "description": "Not Found", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -885,19 +915,19 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/api.Region" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Region" } }, "400": { "description": "Bad Request", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } }, "404": { "description": "Not Found", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -932,14 +962,14 @@ "schema": { "type": "array", "items": { - "$ref": "#/definitions/api.ObservationPoint" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ObservationPoint" } } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -966,13 +996,13 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/api.StatsOverview" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.StatsOverview" } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -1007,14 +1037,14 @@ "schema": { "type": "array", "items": { - "$ref": "#/definitions/api.PayloadBreakdownItem" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.PayloadBreakdownItem" } } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -1032,7 +1062,7 @@ "parameters": [ { "type": "string", - "description": "Filter by IATA code (case-insensitive)", + "description": "Filter by exact IATA code (case-sensitive)", "name": "iata", "in": "query" }, @@ -1049,14 +1079,14 @@ "schema": { "type": "array", "items": { - "$ref": "#/definitions/api.TopNode" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.TopNode" } } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -1097,14 +1127,14 @@ "schema": { "type": "array", "items": { - "$ref": "#/definitions/api.TopObserver" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.TopObserver" } } }, "500": { "description": "Internal Server Error", "schema": { - "$ref": "#/definitions/handlers.APIError" + "$ref": "#/definitions/internal_api_handlers.APIError" } } } @@ -1112,7 +1142,48 @@ } }, "definitions": { - "api.Channel": { + "github_com_MeshCore-Tower_tower-server_internal_api.AdvertObservation": { + "type": "object", + "properties": { + "heardAt": { + "description": "epoch ms", + "type": "integer" + }, + "hopCount": { + "type": "integer" + }, + "iata": { + "type": "string" + }, + "id": { + "description": "observation ID, use as cursor for pagination", + "type": "integer" + }, + "nodeName": { + "type": "string" + }, + "nodePublicKey": { + "type": "string" + }, + "packetHash": { + "description": "hex-encoded", + "type": "string" + }, + "payloadType": { + "type": "integer" + }, + "payloadTypeName": { + "type": "string" + }, + "rssi": { + "type": "integer" + }, + "snr": { + "type": "number" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.Channel": { "type": "object", "properties": { "channelHash": { @@ -1151,7 +1222,67 @@ } } }, - "api.IATA": { + "github_com_MeshCore-Tower_tower-server_internal_api.ChannelMessage": { + "type": "object", + "properties": { + "channelHash": { + "description": "hex-encoded single-byte channel hash", + "type": "string" + }, + "content": { + "description": "decrypted message text", + "type": "string" + }, + "id": { + "type": "integer" + }, + "observationCount": { + "description": "the number of observations for this message packet hash", + "type": "integer" + }, + "packetHash": { + "description": "hex-encoded packet hash for correlation with packet events", + "type": "string" + }, + "senderName": { + "description": "display name from the decrypted payload", + "type": "string" + }, + "sentAt": { + "description": "epoch ms", + "type": "integer" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.ChannelSummary": { + "type": "object", + "properties": { + "channelHash": { + "description": "hex-encoded single-byte hash", + "type": "string" + }, + "id": { + "type": "integer" + }, + "isHashtag": { + "description": "true if derived from a hashtag PSK", + "type": "boolean" + }, + "keyKnown": { + "description": "true if Tower has a decryption key", + "type": "boolean" + }, + "lastSeen": { + "description": "epoch ms", + "type": "integer" + }, + "name": { + "description": "display name, nil if not set", + "type": "string" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.IATA": { "type": "object", "properties": { "displayName": { @@ -1168,7 +1299,7 @@ } } }, - "api.Node": { + "github_com_MeshCore-Tower_tower-server_internal_api.Node": { "type": "object", "properties": { "firstSeen": { @@ -1178,7 +1309,7 @@ "iatas": { "type": "array", "items": { - "type": "string" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.NodeIATA" } }, "id": { @@ -1229,6 +1360,9 @@ "description": "hex-encoded public key", "type": "string" }, + "radio": { + "type": "string" + }, "supportsMultibytePaths": { "description": "firmware \u003e= 1.14.0", "type": "boolean" @@ -1239,7 +1373,62 @@ } } }, - "api.ObservationPoint": { + "github_com_MeshCore-Tower_tower-server_internal_api.NodeIATA": { + "type": "object", + "properties": { + "iata": { + "type": "string" + }, + "lastHeard": { + "description": "epoch ms", + "type": "integer" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.NodeSummary": { + "type": "object", + "properties": { + "iatas": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.NodeIATA" + } + }, + "id": { + "type": "string" + }, + "isObserver": { + "type": "boolean" + }, + "lat": { + "type": "number" + }, + "lng": { + "type": "number" + }, + "name": { + "type": "string" + }, + "nodeType": { + "description": "1=companion, 2=repeater, 3=room server", + "type": "integer" + }, + "nodeTypeName": { + "type": "string" + }, + "observerId": { + "type": "string" + }, + "publicKey": { + "description": "hex-encoded public key", + "type": "string" + }, + "radio": { + "type": "string" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.ObservationPoint": { "type": "object", "properties": { "activeObservers": { @@ -1260,7 +1449,7 @@ } } }, - "api.Observer": { + "github_com_MeshCore-Tower_tower-server_internal_api.Observer": { "type": "object", "properties": { "batteryLevel": { @@ -1271,7 +1460,7 @@ "description": "broker names this observer has been seen on", "type": "array", "items": { - "$ref": "#/definitions/api.ObserverBroker" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ObserverBroker" } }, "displayName": { @@ -1317,6 +1506,9 @@ "description": "hex-encoded public key", "type": "string" }, + "radio": { + "type": "string" + }, "radioBwKhz": { "description": "bandwidth in kHz", "type": "number" @@ -1348,7 +1540,7 @@ } } }, - "api.ObserverBroker": { + "github_com_MeshCore-Tower_tower-server_internal_api.ObserverBroker": { "type": "object", "properties": { "lastPacketAt": { @@ -1365,7 +1557,34 @@ } } }, - "api.ObserverTelemetry": { + "github_com_MeshCore-Tower_tower-server_internal_api.ObserverSummary": { + "type": "object", + "properties": { + "displayName": { + "description": "friendly name from /status messages", + "type": "string" + }, + "iata": { + "description": "most recently heard IATA", + "type": "string" + }, + "id": { + "type": "string" + }, + "observerType": { + "description": "e.g. \"meshcoretomqtt\", \"meshcoreha\"", + "type": "string" + }, + "radio": { + "type": "string" + }, + "status": { + "description": "\"online\" or \"offline\" derived from last_status_at", + "type": "string" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.ObserverTelemetry": { "type": "object", "properties": { "interval": { @@ -1374,7 +1593,7 @@ "points": { "type": "array", "items": { - "$ref": "#/definitions/api.ObserverTelemetryPoint" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ObserverTelemetryPoint" } }, "range": { @@ -1382,7 +1601,7 @@ } } }, - "api.ObserverTelemetryPoint": { + "github_com_MeshCore-Tower_tower-server_internal_api.ObserverTelemetryPoint": { "type": "object", "properties": { "airtimeRxPct": { @@ -1412,7 +1631,7 @@ } } }, - "api.Packet": { + "github_com_MeshCore-Tower_tower-server_internal_api.Packet": { "type": "object", "properties": { "channelHash": { @@ -1436,7 +1655,7 @@ "observations": { "type": "array", "items": { - "$ref": "#/definitions/api.PacketObservationDetail" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.PacketObservationDetail" } }, "originPubkey": { @@ -1476,7 +1695,21 @@ } } }, - "api.PacketObservationDetail": { + "github_com_MeshCore-Tower_tower-server_internal_api.PacketLatestObserver": { + "type": "object", + "properties": { + "displayName": { + "type": "string" + }, + "iata": { + "type": "string" + }, + "id": { + "type": "string" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.PacketObservationDetail": { "type": "object", "properties": { "hashSize": { @@ -1512,12 +1745,12 @@ "type": "integer" }, "radio": { - "$ref": "#/definitions/api.PacketRadio" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.PacketRadio" }, "resolvedPath": { "type": "array", "items": { - "$ref": "#/definitions/api.ResolvedHop" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ResolvedHop" } }, "rssi": { @@ -1531,7 +1764,42 @@ } } }, - "api.PacketRadio": { + "github_com_MeshCore-Tower_tower-server_internal_api.PacketObservationSummary": { + "type": "object", + "properties": { + "heardAt": { + "description": "epoch ms", + "type": "integer" + }, + "hopCount": { + "type": "integer" + }, + "iata": { + "type": "string" + }, + "id": { + "description": "observation ID, use as cursor for pagination", + "type": "integer" + }, + "packetHash": { + "description": "hex-encoded", + "type": "string" + }, + "payloadType": { + "type": "integer" + }, + "payloadTypeName": { + "type": "string" + }, + "rssi": { + "type": "integer" + }, + "snr": { + "type": "number" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.PacketRadio": { "type": "object", "properties": { "bandwidthKhz": { @@ -1548,7 +1816,165 @@ } } }, - "api.PayloadBreakdownItem": { + "github_com_MeshCore-Tower_tower-server_internal_api.PacketSummary": { + "type": "object", + "properties": { + "firstHeardAt": { + "description": "epoch ms", + "type": "integer" + }, + "lastHeardAt": { + "description": "epoch ms", + "type": "integer" + }, + "latestObserver": { + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.PacketLatestObserver" + }, + "observationCount": { + "type": "integer" + }, + "packetHash": { + "description": "hex-encoded", + "type": "string" + }, + "payloadType": { + "type": "integer" + }, + "payloadTypeName": { + "type": "string" + }, + "routeType": { + "type": "integer" + }, + "routeTypeName": { + "type": "string" + }, + "summary": { + "description": "human-readable payload summary", + "type": "string" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_AdvertObservation": { + "type": "object", + "properties": { + "hasMore": { + "type": "boolean" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.AdvertObservation" + } + }, + "nextCursor": { + "type": "integer" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_ChannelMessage": { + "type": "object", + "properties": { + "hasMore": { + "type": "boolean" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ChannelMessage" + } + }, + "nextCursor": { + "type": "integer" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_ChannelSummary": { + "type": "object", + "properties": { + "hasMore": { + "type": "boolean" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ChannelSummary" + } + }, + "nextCursor": { + "type": "integer" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_NodeSummary": { + "type": "object", + "properties": { + "hasMore": { + "type": "boolean" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.NodeSummary" + } + }, + "nextCursor": { + "type": "integer" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_ObserverSummary": { + "type": "object", + "properties": { + "hasMore": { + "type": "boolean" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ObserverSummary" + } + }, + "nextCursor": { + "type": "integer" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_PacketObservationSummary": { + "type": "object", + "properties": { + "hasMore": { + "type": "boolean" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.PacketObservationSummary" + } + }, + "nextCursor": { + "type": "integer" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_PacketSummary": { + "type": "object", + "properties": { + "hasMore": { + "type": "boolean" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.PacketSummary" + } + }, + "nextCursor": { + "type": "integer" + } + } + }, + "github_com_MeshCore-Tower_tower-server_internal_api.PayloadBreakdownItem": { "type": "object", "properties": { "count": { @@ -1562,7 +1988,7 @@ } } }, - "api.Region": { + "github_com_MeshCore-Tower_tower-server_internal_api.Region": { "type": "object", "properties": { "centerLat": { @@ -1599,7 +2025,7 @@ } } }, - "api.RegionSummary": { + "github_com_MeshCore-Tower_tower-server_internal_api.RegionSummary": { "type": "object", "properties": { "id": { @@ -1614,7 +2040,7 @@ } } }, - "api.ResolvedHop": { + "github_com_MeshCore-Tower_tower-server_internal_api.ResolvedHop": { "type": "object", "properties": { "confidence": { @@ -1622,11 +2048,11 @@ "type": "string" }, "node": { - "$ref": "#/definitions/api.ResolvedNode" + "$ref": "#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ResolvedNode" } } }, - "api.ResolvedNode": { + "github_com_MeshCore-Tower_tower-server_internal_api.ResolvedNode": { "type": "object", "properties": { "id": { @@ -1647,7 +2073,7 @@ } } }, - "api.StatsOverview": { + "github_com_MeshCore-Tower_tower-server_internal_api.StatsOverview": { "type": "object", "properties": { "activeIatas": { @@ -1668,7 +2094,7 @@ } } }, - "api.TopNode": { + "github_com_MeshCore-Tower_tower-server_internal_api.TopNode": { "type": "object", "properties": { "iata": { @@ -1695,7 +2121,7 @@ } } }, - "api.TopObserver": { + "github_com_MeshCore-Tower_tower-server_internal_api.TopObserver": { "type": "object", "properties": { "displayName": { @@ -1715,7 +2141,7 @@ } } }, - "handlers.APIError": { + "internal_api_handlers.APIError": { "type": "object", "properties": { "code": { @@ -1728,7 +2154,7 @@ } } }, - "handlers.BrokerStatus": { + "internal_api_handlers.BrokerStatus": { "type": "object", "properties": { "connected": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 5f9115a..72165f1 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1,6 +1,34 @@ basePath: /api/v1 definitions: - api.Channel: + github_com_MeshCore-Tower_tower-server_internal_api.AdvertObservation: + properties: + heardAt: + description: epoch ms + type: integer + hopCount: + type: integer + iata: + type: string + id: + description: observation ID, use as cursor for pagination + type: integer + nodeName: + type: string + nodePublicKey: + type: string + packetHash: + description: hex-encoded + type: string + payloadType: + type: integer + payloadTypeName: + type: string + rssi: + type: integer + snr: + type: number + type: object + github_com_MeshCore-Tower_tower-server_internal_api.Channel: properties: channelHash: description: hex-encoded single-byte hash @@ -28,7 +56,50 @@ definitions: description: display name, nil if not set type: string type: object - api.IATA: + github_com_MeshCore-Tower_tower-server_internal_api.ChannelMessage: + properties: + channelHash: + description: hex-encoded single-byte channel hash + type: string + content: + description: decrypted message text + type: string + id: + type: integer + observationCount: + description: the number of observations for this message packet hash + type: integer + packetHash: + description: hex-encoded packet hash for correlation with packet events + type: string + senderName: + description: display name from the decrypted payload + type: string + sentAt: + description: epoch ms + type: integer + type: object + github_com_MeshCore-Tower_tower-server_internal_api.ChannelSummary: + properties: + channelHash: + description: hex-encoded single-byte hash + type: string + id: + type: integer + isHashtag: + description: true if derived from a hashtag PSK + type: boolean + keyKnown: + description: true if Tower has a decryption key + type: boolean + lastSeen: + description: epoch ms + type: integer + name: + description: display name, nil if not set + type: string + type: object + github_com_MeshCore-Tower_tower-server_internal_api.IATA: properties: displayName: type: string @@ -39,14 +110,14 @@ definitions: lon: type: number type: object - api.Node: + github_com_MeshCore-Tower_tower-server_internal_api.Node: properties: firstSeen: description: epoch ms type: integer iatas: items: - type: string + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.NodeIATA' type: array id: type: string @@ -82,6 +153,8 @@ definitions: publicKey: description: hex-encoded public key type: string + radio: + type: string supportsMultibytePaths: description: firmware >= 1.14.0 type: boolean @@ -89,7 +162,44 @@ definitions: description: firmware >= 1.11.0 type: boolean type: object - api.ObservationPoint: + github_com_MeshCore-Tower_tower-server_internal_api.NodeIATA: + properties: + iata: + type: string + lastHeard: + description: epoch ms + type: integer + type: object + github_com_MeshCore-Tower_tower-server_internal_api.NodeSummary: + properties: + iatas: + items: + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.NodeIATA' + type: array + id: + type: string + isObserver: + type: boolean + lat: + type: number + lng: + type: number + name: + type: string + nodeType: + description: 1=companion, 2=repeater, 3=room server + type: integer + nodeTypeName: + type: string + observerId: + type: string + publicKey: + description: hex-encoded public key + type: string + radio: + type: string + type: object + github_com_MeshCore-Tower_tower-server_internal_api.ObservationPoint: properties: activeObservers: type: integer @@ -103,7 +213,7 @@ definitions: uniquePackets: type: integer type: object - api.Observer: + github_com_MeshCore-Tower_tower-server_internal_api.Observer: properties: batteryLevel: description: volts, nil if mains powered @@ -111,7 +221,7 @@ definitions: brokers: description: broker names this observer has been seen on items: - $ref: '#/definitions/api.ObserverBroker' + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ObserverBroker' type: array displayName: description: friendly name from /status messages @@ -144,6 +254,8 @@ definitions: publicKey: description: hex-encoded public key type: string + radio: + type: string radioBwKhz: description: bandwidth in kHz type: number @@ -166,7 +278,7 @@ definitions: uptimeSeconds: type: integer type: object - api.ObserverBroker: + github_com_MeshCore-Tower_tower-server_internal_api.ObserverBroker: properties: lastPacketAt: description: epoch ms, last packet received via this broker; 0 if none @@ -178,18 +290,37 @@ definitions: description: broker name e.g. "mqtt1" type: string type: object - api.ObserverTelemetry: + github_com_MeshCore-Tower_tower-server_internal_api.ObserverSummary: + properties: + displayName: + description: friendly name from /status messages + type: string + iata: + description: most recently heard IATA + type: string + id: + type: string + observerType: + description: e.g. "meshcoretomqtt", "meshcoreha" + type: string + radio: + type: string + status: + description: '"online" or "offline" derived from last_status_at' + type: string + type: object + github_com_MeshCore-Tower_tower-server_internal_api.ObserverTelemetry: properties: interval: type: string points: items: - $ref: '#/definitions/api.ObserverTelemetryPoint' + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ObserverTelemetryPoint' type: array range: type: string type: object - api.ObserverTelemetryPoint: + github_com_MeshCore-Tower_tower-server_internal_api.ObserverTelemetryPoint: properties: airtimeRxPct: type: number @@ -209,7 +340,7 @@ definitions: uptimeSeconds: type: integer type: object - api.Packet: + github_com_MeshCore-Tower_tower-server_internal_api.Packet: properties: channelHash: description: hex-encoded @@ -226,7 +357,7 @@ definitions: type: integer observations: items: - $ref: '#/definitions/api.PacketObservationDetail' + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.PacketObservationDetail' type: array originPubkey: description: hex-encoded @@ -254,7 +385,16 @@ definitions: description: hex-encoded type: string type: object - api.PacketObservationDetail: + github_com_MeshCore-Tower_tower-server_internal_api.PacketLatestObserver: + properties: + displayName: + type: string + iata: + type: string + id: + type: string + type: object + github_com_MeshCore-Tower_tower-server_internal_api.PacketObservationDetail: properties: hashSize: type: integer @@ -279,10 +419,10 @@ definitions: propagationTimeMs: type: integer radio: - $ref: '#/definitions/api.PacketRadio' + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.PacketRadio' resolvedPath: items: - $ref: '#/definitions/api.ResolvedHop' + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ResolvedHop' type: array rssi: type: integer @@ -291,7 +431,31 @@ definitions: sourceBroker: type: string type: object - api.PacketRadio: + github_com_MeshCore-Tower_tower-server_internal_api.PacketObservationSummary: + properties: + heardAt: + description: epoch ms + type: integer + hopCount: + type: integer + iata: + type: string + id: + description: observation ID, use as cursor for pagination + type: integer + packetHash: + description: hex-encoded + type: string + payloadType: + type: integer + payloadTypeName: + type: string + rssi: + type: integer + snr: + type: number + type: object + github_com_MeshCore-Tower_tower-server_internal_api.PacketRadio: properties: bandwidthKhz: type: number @@ -302,7 +466,111 @@ definitions: spreadFactor: type: integer type: object - api.PayloadBreakdownItem: + github_com_MeshCore-Tower_tower-server_internal_api.PacketSummary: + properties: + firstHeardAt: + description: epoch ms + type: integer + lastHeardAt: + description: epoch ms + type: integer + latestObserver: + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.PacketLatestObserver' + observationCount: + type: integer + packetHash: + description: hex-encoded + type: string + payloadType: + type: integer + payloadTypeName: + type: string + routeType: + type: integer + routeTypeName: + type: string + summary: + description: human-readable payload summary + type: string + type: object + github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_AdvertObservation: + properties: + hasMore: + type: boolean + items: + items: + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.AdvertObservation' + type: array + nextCursor: + type: integer + type: object + github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_ChannelMessage: + properties: + hasMore: + type: boolean + items: + items: + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ChannelMessage' + type: array + nextCursor: + type: integer + type: object + github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_ChannelSummary: + properties: + hasMore: + type: boolean + items: + items: + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ChannelSummary' + type: array + nextCursor: + type: integer + type: object + github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_NodeSummary: + properties: + hasMore: + type: boolean + items: + items: + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.NodeSummary' + type: array + nextCursor: + type: integer + type: object + github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_ObserverSummary: + properties: + hasMore: + type: boolean + items: + items: + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ObserverSummary' + type: array + nextCursor: + type: integer + type: object + ? github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_PacketObservationSummary + : properties: + hasMore: + type: boolean + items: + items: + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.PacketObservationSummary' + type: array + nextCursor: + type: integer + type: object + github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_PacketSummary: + properties: + hasMore: + type: boolean + items: + items: + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.PacketSummary' + type: array + nextCursor: + type: integer + type: object + github_com_MeshCore-Tower_tower-server_internal_api.PayloadBreakdownItem: properties: count: type: integer @@ -311,7 +579,7 @@ definitions: payloadTypeName: type: string type: object - api.Region: + github_com_MeshCore-Tower_tower-server_internal_api.Region: properties: centerLat: description: map center latitude @@ -337,7 +605,7 @@ definitions: description: suggested map zoom level type: integer type: object - api.RegionSummary: + github_com_MeshCore-Tower_tower-server_internal_api.RegionSummary: properties: id: type: integer @@ -347,15 +615,15 @@ definitions: description: URL-safe identifier e.g. "western-canada" type: string type: object - api.ResolvedHop: + github_com_MeshCore-Tower_tower-server_internal_api.ResolvedHop: properties: confidence: description: '"high", "low", "unknown"' type: string node: - $ref: '#/definitions/api.ResolvedNode' + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ResolvedNode' type: object - api.ResolvedNode: + github_com_MeshCore-Tower_tower-server_internal_api.ResolvedNode: properties: id: type: string @@ -369,7 +637,7 @@ definitions: description: hex-encoded prefix type: string type: object - api.StatsOverview: + github_com_MeshCore-Tower_tower-server_internal_api.StatsOverview: properties: activeIatas: type: integer @@ -383,7 +651,7 @@ definitions: description: always 24 for now type: integer type: object - api.TopNode: + github_com_MeshCore-Tower_tower-server_internal_api.TopNode: properties: iata: type: string @@ -401,7 +669,7 @@ definitions: observationCount: type: integer type: object - api.TopObserver: + github_com_MeshCore-Tower_tower-server_internal_api.TopObserver: properties: displayName: type: string @@ -414,7 +682,7 @@ definitions: observerType: type: string type: object - handlers.APIError: + internal_api_handlers.APIError: properties: code: description: e.g. "not_found", "bad_request" @@ -423,7 +691,7 @@ definitions: description: e.g. "channel not found" type: string type: object - handlers.BrokerStatus: + internal_api_handlers.BrokerStatus: properties: connected: type: boolean @@ -452,7 +720,7 @@ paths: description: OK schema: items: - $ref: '#/definitions/handlers.BrokerStatus' + $ref: '#/definitions/internal_api_handlers.BrokerStatus' type: array summary: List all MQTT brokers and their connection status tags: @@ -482,15 +750,15 @@ paths: "200": description: OK schema: - type: object + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_ChannelSummary' "400": description: Bad Request schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' "500": description: Internal Server Error schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' summary: List channels tags: - Channels @@ -508,15 +776,15 @@ paths: "200": description: OK schema: - $ref: '#/definitions/api.Channel' + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Channel' "400": description: Bad Request schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' "404": description: Not Found schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' summary: Get channel detail tags: - Channels @@ -550,15 +818,15 @@ paths: "200": description: OK schema: - type: object + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_ChannelMessage' "400": description: Bad Request schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' "500": description: Internal Server Error schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' summary: List messages for a channel tags: - Channels @@ -571,12 +839,12 @@ paths: description: OK schema: items: - $ref: '#/definitions/api.IATA' + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.IATA' type: array "404": description: Not Found schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' summary: List all IATA codes tags: - IATAs @@ -594,11 +862,11 @@ paths: "200": description: OK schema: - $ref: '#/definitions/api.IATA' + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.IATA' "404": description: Not Found schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' summary: Get a single IATA code tags: - IATAs @@ -635,15 +903,15 @@ paths: "200": description: OK schema: - type: object + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_ChannelMessage' "400": description: Bad Request schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' "500": description: Internal Server Error schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' summary: List channel messages tags: - Messages @@ -670,11 +938,11 @@ paths: in: query name: pubkey type: string - - description: Filter to nodes with firmware >= 1.14.0 + - description: Filter by multibyte path support (true/false); omit for no filter in: query name: supportsMultibytePaths type: boolean - - description: Filter to nodes with firmware >= 1.11.0 + - description: Filter by multibyte trace support (true/false); omit for no filter in: query name: supportsMultibyteTraces type: boolean @@ -692,11 +960,15 @@ paths: "200": description: OK schema: - type: object + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_NodeSummary' + "400": + description: Bad Request + schema: + $ref: '#/definitions/internal_api_handlers.APIError' "500": description: Internal Server Error schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' summary: List nodes tags: - Nodes @@ -714,15 +986,15 @@ paths: "200": description: OK schema: - $ref: '#/definitions/api.Node' + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Node' "400": description: Bad Request schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' "404": description: Not Found schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' summary: Get node detail tags: - Nodes @@ -748,15 +1020,15 @@ paths: "200": description: OK schema: - type: object + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_PacketObservationSummary' "400": description: Bad Request schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' "500": description: Internal Server Error schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' summary: List packet observations originating from a node tags: - Nodes @@ -797,11 +1069,15 @@ paths: "200": description: OK schema: - type: object + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_ObserverSummary' + "400": + description: Bad Request + schema: + $ref: '#/definitions/internal_api_handlers.APIError' "500": description: Internal Server Error schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' summary: List observers tags: - Observers @@ -819,15 +1095,15 @@ paths: "200": description: OK schema: - $ref: '#/definitions/api.Observer' + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Observer' "400": description: Bad Request schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' "404": description: Not Found schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' summary: Get observer detail tags: - Observers @@ -853,15 +1129,15 @@ paths: "200": description: OK schema: - type: object + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_AdvertObservation' "400": description: Bad Request schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' "500": description: Internal Server Error schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' summary: List advert packets heard by an observer tags: - Observers @@ -881,21 +1157,26 @@ paths: in: query name: afterId type: integer + - description: Bucketing interval, echoed back in the response; not yet applied + server-side + in: query + name: interval + type: string produces: - application/json responses: "200": description: OK schema: - $ref: '#/definitions/api.ObserverTelemetry' + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ObserverTelemetry' "400": description: Bad Request schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' "500": description: Internal Server Error schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' summary: Get observer telemetry history tags: - Observers @@ -915,7 +1196,7 @@ paths: in: query name: routeType type: integer - - description: Filter by latest observation IATA (case-insensitive) + - description: Filter by IATA code in: query name: iata type: string @@ -941,11 +1222,15 @@ paths: "200": description: OK schema: - type: object + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Page-github_com_MeshCore-Tower_tower-server_internal_api_PacketSummary' + "400": + description: Bad Request + schema: + $ref: '#/definitions/internal_api_handlers.APIError' "500": description: Internal Server Error schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' summary: List packets tags: - Packets @@ -963,15 +1248,19 @@ paths: "200": description: OK schema: - $ref: '#/definitions/api.Packet' + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Packet' "400": description: Bad Request schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' "404": description: Not Found schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' + "500": + description: Internal Server Error + schema: + $ref: '#/definitions/internal_api_handlers.APIError' summary: Get full packet detail tags: - Packets @@ -984,12 +1273,12 @@ paths: description: OK schema: items: - $ref: '#/definitions/api.RegionSummary' + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.RegionSummary' type: array "404": description: Not Found schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' summary: List all regions tags: - Regions @@ -1007,15 +1296,15 @@ paths: "200": description: OK schema: - $ref: '#/definitions/api.Region' + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.Region' "400": description: Bad Request schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' "404": description: Not Found schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' summary: Get a single region tags: - Regions @@ -1037,12 +1326,12 @@ paths: description: OK schema: items: - $ref: '#/definitions/api.ObservationPoint' + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.ObservationPoint' type: array "500": description: Internal Server Error schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' summary: Hourly observation time series tags: - Stats @@ -1059,11 +1348,11 @@ paths: "200": description: OK schema: - $ref: '#/definitions/api.StatsOverview' + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.StatsOverview' "500": description: Internal Server Error schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' summary: Network overview stats (last 24h) tags: - Stats @@ -1085,19 +1374,19 @@ paths: description: OK schema: items: - $ref: '#/definitions/api.PayloadBreakdownItem' + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.PayloadBreakdownItem' type: array "500": description: Internal Server Error schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' summary: Observation counts by payload type (last 24h by default) tags: - Stats /stats/top-nodes: get: parameters: - - description: Filter by IATA code (case-insensitive) + - description: Filter by exact IATA code (case-sensitive) in: query name: iata type: string @@ -1112,12 +1401,12 @@ paths: description: OK schema: items: - $ref: '#/definitions/api.TopNode' + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.TopNode' type: array "500": description: Internal Server Error schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' summary: Top N nodes by observation count (from materialized view) tags: - Stats @@ -1143,12 +1432,12 @@ paths: description: OK schema: items: - $ref: '#/definitions/api.TopObserver' + $ref: '#/definitions/github_com_MeshCore-Tower_tower-server_internal_api.TopObserver' type: array "500": description: Internal Server Error schema: - $ref: '#/definitions/handlers.APIError' + $ref: '#/definitions/internal_api_handlers.APIError' summary: Top N observers by observation count (last 24h by default) tags: - Stats diff --git a/internal/api/handlers/channels.go b/internal/api/handlers/channels.go index 1b3dd77..daa95fe 100644 --- a/internal/api/handlers/channels.go +++ b/internal/api/handlers/channels.go @@ -34,7 +34,7 @@ func ChannelsRouter(reader api.Reader) http.Handler { // @Param iata query string false "Filter by IATA code (case-insensitive)" // @Param cursor query int false "last_seen epoch ms of last item for pagination" // @Param limit query int false "Max results (default 50)" -// @Success 200 {object} object +// @Success 200 {object} api.Page[api.ChannelSummary] // @Failure 400 {object} handlers.APIError // @Failure 500 {object} handlers.APIError // @Router /channels [get] @@ -121,7 +121,7 @@ func getChannel(reader api.Reader) http.HandlerFunc { // @Param iata query string false "Filter by IATA code" // @Param cursor query int false "Message ID of last item for pagination" // @Param limit query int false "Max results (default 50)" -// @Success 200 {object} object +// @Success 200 {object} api.Page[api.ChannelMessage] // @Failure 400 {object} handlers.APIError // @Failure 500 {object} handlers.APIError // @Router /channels/{channelID}/messages [get] diff --git a/internal/api/handlers/messages.go b/internal/api/handlers/messages.go index 3a7cc0c..7bc6a17 100644 --- a/internal/api/handlers/messages.go +++ b/internal/api/handlers/messages.go @@ -30,7 +30,7 @@ func MessagesRouter(reader api.Reader) http.Handler { // @Param iata query string false "Filter by IATA code" // @Param cursor query int false "Message ID of last item for pagination" // @Param limit query int false "Max results (default 50)" -// @Success 200 {object} object +// @Success 200 {object} api.Page[api.ChannelMessage] // @Failure 400 {object} handlers.APIError // @Failure 500 {object} handlers.APIError // @Router /messages [get] diff --git a/internal/api/handlers/nodes.go b/internal/api/handlers/nodes.go index b6b6128..b7dbc1c 100644 --- a/internal/api/handlers/nodes.go +++ b/internal/api/handlers/nodes.go @@ -32,14 +32,15 @@ func NodesRouter(reader api.Reader) http.Handler { // @Produce json // @Param type query int false "Node type integer (1=companion, 2=repeater, 3=room_server, 4=sensor)" // @Param typeName query string false "Node type name (companion, repeater, room_server, sensor)" -// @Param iata query string false "Filter by IATA code (case-insensitive); comma-separated for multiple" +// @Param iata query string false "Filter by IATA code (case-insensitive)" // @Param name query string false "Partial case-insensitive name match" // @Param pubkey query string false "Exact public key match (hex)" -// @Param supportsMultibytePaths query string false "Multibyte path support filter: any (default), true, false" -// @Param supportsMultibyteTraces query string false "Multibyte trace support filter: any (default), true, false" +// @Param supportsMultibytePaths query bool false "Filter by multibyte path support (true/false); omit for no filter" +// @Param supportsMultibyteTraces query bool false "Filter by multibyte trace support (true/false); omit for no filter" // @Param cursor query int false "last_seen epoch ms of last item for pagination" // @Param limit query int false "Max results (default 50)" // @Success 200 {object} api.Page[api.NodeSummary] +// @Failure 400 {object} handlers.APIError // @Failure 500 {object} handlers.APIError // @Router /nodes [get] func listNodes(reader api.Reader) http.HandlerFunc { @@ -120,7 +121,6 @@ func listNodes(reader api.Reader) http.HandlerFunc { // @Success 200 {object} api.Node // @Failure 400 {object} handlers.APIError // @Failure 404 {object} handlers.APIError -// @Failure 500 {object} handlers.APIError // @Router /nodes/{nodeId} [get] func getNode(reader api.Reader) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { @@ -146,7 +146,7 @@ func getNode(reader api.Reader) http.HandlerFunc { // @Param nodeId path string true "Node UUID" // @Param cursor query int false "Observation ID of last item for pagination" // @Param limit query int false "Max results (default 50)" -// @Success 200 {object} api.Page[api.NodeObservation] +// @Success 200 {object} api.Page[api.PacketObservationSummary] // @Failure 400 {object} handlers.APIError // @Failure 500 {object} handlers.APIError // @Router /nodes/{nodeId}/observations [get] diff --git a/internal/api/handlers/observers.go b/internal/api/handlers/observers.go index 9d00b1d..ea0616d 100644 --- a/internal/api/handlers/observers.go +++ b/internal/api/handlers/observers.go @@ -39,7 +39,8 @@ func ObserversRouter(reader api.Reader) http.Handler { // @Param name query string false "Partial case-insensitive display name match" // @Param cursor query int false "last_seen epoch ms of last item for pagination" // @Param limit query int false "Max results (default 50)" -// @Success 200 {object} object +// @Success 200 {object} api.Page[api.ObserverSummary] +// @Failure 400 {object} handlers.APIError // @Failure 500 {object} handlers.APIError // @Router /observers [get] func listObservers(reader api.Reader) http.HandlerFunc { @@ -111,7 +112,7 @@ func getObserver(reader api.Reader) http.HandlerFunc { // @Param observerId path string true "Observer UUID" // @Param cursor query int false "Observation ID of last item for pagination" // @Param limit query int false "Max results (default 50)" -// @Success 200 {object} object +// @Success 200 {object} api.Page[api.AdvertObservation] // @Failure 400 {object} handlers.APIError // @Failure 500 {object} handlers.APIError // @Router /observers/{observerId}/adverts [get] @@ -157,6 +158,7 @@ func listObserverAdverts(reader api.Reader) http.HandlerFunc { // @Param observerId path string true "Observer UUID" // @Param range query string false "Duration window e.g. 24h, 48h, 168h (default 24h)" // @Param afterId query int false "Return points after this telemetry ID for WS reconnection backfill" +// @Param interval query string false "Bucketing interval, echoed back in the response; not yet applied server-side" // @Success 200 {object} api.ObserverTelemetry // @Failure 400 {object} handlers.APIError // @Failure 500 {object} handlers.APIError diff --git a/internal/api/handlers/packets.go b/internal/api/handlers/packets.go index d7564c0..c19c7d3 100644 --- a/internal/api/handlers/packets.go +++ b/internal/api/handlers/packets.go @@ -35,6 +35,7 @@ func PacketsRouter(reader api.Reader) http.Handler { // @Param cursor query int false "last_heard_at epoch ms of last item for pagination" // @Param limit query int false "Max results (default 50)" // @Success 200 {object} api.Page[api.PacketSummary] +// @Failure 400 {object} handlers.APIError // @Failure 500 {object} handlers.APIError // @Router /packets [get] func listPackets(reader api.Reader) http.HandlerFunc { diff --git a/internal/api/handlers/stats.go b/internal/api/handlers/stats.go index aa89347..bbdb0e8 100644 --- a/internal/api/handlers/stats.go +++ b/internal/api/handlers/stats.go @@ -121,7 +121,7 @@ func getStatsPayloadBreakdown(reader api.Reader) http.HandlerFunc { // @Summary Top N nodes by observation count (from materialized view) // @Tags Stats // @Produce json -// @Param iata query string false "Filter by IATA code (case-insensitive)" +// @Param iata query string false "Filter by exact IATA code (case-sensitive)" // @Param limit query int false "Max results (default 10)" // @Success 200 {array} api.TopNode // @Failure 500 {object} handlers.APIError