mirror of
https://github.com/MeshCore-Beacon/beacon-server.git
synced 2026-09-16 17:02:38 +00:00
feat: add observer status to nodes
IsObserver and ObserverID in summary and details
This commit is contained in:
+14
-3
@@ -310,14 +310,25 @@ UPDATE nodes SET supports_multibyte_traces = TRUE
|
||||
WHERE id = $1 AND supports_multibyte_traces = FALSE;
|
||||
|
||||
-- name: GetNodeByPubkey :one
|
||||
SELECT * FROM nodes WHERE public_key = $1;
|
||||
SELECT *,
|
||||
EXISTS (SELECT 1 FROM observers o WHERE o.public_key = n.public_key) AS is_observer,
|
||||
(SELECT o.id FROM observers o WHERE o.public_key = n.public_key LIMIT 1) AS observer_id
|
||||
FROM nodes n
|
||||
WHERE n.public_key = $1;
|
||||
|
||||
-- name: GetNodeByID :one
|
||||
SELECT * FROM nodes WHERE id = $1;
|
||||
SELECT *,
|
||||
EXISTS (SELECT 1 FROM observers o WHERE o.public_key = n.public_key) AS is_observer,
|
||||
(SELECT o.id FROM observers o WHERE o.public_key = n.public_key LIMIT 1) AS observer_id
|
||||
FROM nodes n
|
||||
WHERE n.id = $1;
|
||||
|
||||
|
||||
-- name: ListNodes :many
|
||||
SELECT n.id, n.public_key, n.node_type, n.name, n.latitude, n.longitude, n.last_seen,
|
||||
array_remove(array_agg(DISTINCT ni.iata ORDER BY ni.iata), NULL)::text[] AS iatas
|
||||
array_remove(array_agg(DISTINCT ni.iata ORDER BY ni.iata), NULL)::text[] AS iatas,
|
||||
EXISTS (SELECT 1 FROM observers o WHERE o.public_key = n.public_key) AS is_observer,
|
||||
(SELECT o.id FROM observers o WHERE o.public_key = n.public_key LIMIT 1) AS observer_id
|
||||
FROM nodes n
|
||||
LEFT JOIN node_iatas ni ON ni.node_id = n.id
|
||||
WHERE
|
||||
|
||||
+71
-15
@@ -206,12 +206,35 @@ func (q *Queries) GetIATA(ctx context.Context, iata string) (IataCode, error) {
|
||||
}
|
||||
|
||||
const getNodeByID = `-- name: GetNodeByID :one
|
||||
SELECT id, public_key, node_type, name, latitude, longitude, location_source, last_advert_at, supports_multibyte_paths, supports_multibyte_traces, min_firmware_version, first_seen, last_seen, metadata FROM nodes WHERE id = $1
|
||||
SELECT id, public_key, node_type, name, latitude, longitude, location_source, last_advert_at, supports_multibyte_paths, supports_multibyte_traces, min_firmware_version, first_seen, last_seen, metadata,
|
||||
EXISTS (SELECT 1 FROM observers o WHERE o.public_key = n.public_key) AS is_observer,
|
||||
(SELECT o.id FROM observers o WHERE o.public_key = n.public_key LIMIT 1) AS observer_id
|
||||
FROM nodes n
|
||||
WHERE n.id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetNodeByID(ctx context.Context, id uuid.UUID) (Node, error) {
|
||||
type GetNodeByIDRow struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
PublicKey []byte `json:"public_key"`
|
||||
NodeType int16 `json:"node_type"`
|
||||
Name *string `json:"name"`
|
||||
Latitude *float64 `json:"latitude"`
|
||||
Longitude *float64 `json:"longitude"`
|
||||
LocationSource *string `json:"location_source"`
|
||||
LastAdvertAt pgtype.Timestamptz `json:"last_advert_at"`
|
||||
SupportsMultibytePaths bool `json:"supports_multibyte_paths"`
|
||||
SupportsMultibyteTraces bool `json:"supports_multibyte_traces"`
|
||||
MinFirmwareVersion *string `json:"min_firmware_version"`
|
||||
FirstSeen pgtype.Timestamptz `json:"first_seen"`
|
||||
LastSeen pgtype.Timestamptz `json:"last_seen"`
|
||||
Metadata []byte `json:"metadata"`
|
||||
IsObserver bool `json:"is_observer"`
|
||||
ObserverID uuid.UUID `json:"observer_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetNodeByID(ctx context.Context, id uuid.UUID) (GetNodeByIDRow, error) {
|
||||
row := q.db.QueryRow(ctx, getNodeByID, id)
|
||||
var i Node
|
||||
var i GetNodeByIDRow
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.PublicKey,
|
||||
@@ -227,17 +250,42 @@ func (q *Queries) GetNodeByID(ctx context.Context, id uuid.UUID) (Node, error) {
|
||||
&i.FirstSeen,
|
||||
&i.LastSeen,
|
||||
&i.Metadata,
|
||||
&i.IsObserver,
|
||||
&i.ObserverID,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getNodeByPubkey = `-- name: GetNodeByPubkey :one
|
||||
SELECT id, public_key, node_type, name, latitude, longitude, location_source, last_advert_at, supports_multibyte_paths, supports_multibyte_traces, min_firmware_version, first_seen, last_seen, metadata FROM nodes WHERE public_key = $1
|
||||
SELECT id, public_key, node_type, name, latitude, longitude, location_source, last_advert_at, supports_multibyte_paths, supports_multibyte_traces, min_firmware_version, first_seen, last_seen, metadata,
|
||||
EXISTS (SELECT 1 FROM observers o WHERE o.public_key = n.public_key) AS is_observer,
|
||||
(SELECT o.id FROM observers o WHERE o.public_key = n.public_key LIMIT 1) AS observer_id
|
||||
FROM nodes n
|
||||
WHERE n.public_key = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetNodeByPubkey(ctx context.Context, publicKey []byte) (Node, error) {
|
||||
type GetNodeByPubkeyRow struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
PublicKey []byte `json:"public_key"`
|
||||
NodeType int16 `json:"node_type"`
|
||||
Name *string `json:"name"`
|
||||
Latitude *float64 `json:"latitude"`
|
||||
Longitude *float64 `json:"longitude"`
|
||||
LocationSource *string `json:"location_source"`
|
||||
LastAdvertAt pgtype.Timestamptz `json:"last_advert_at"`
|
||||
SupportsMultibytePaths bool `json:"supports_multibyte_paths"`
|
||||
SupportsMultibyteTraces bool `json:"supports_multibyte_traces"`
|
||||
MinFirmwareVersion *string `json:"min_firmware_version"`
|
||||
FirstSeen pgtype.Timestamptz `json:"first_seen"`
|
||||
LastSeen pgtype.Timestamptz `json:"last_seen"`
|
||||
Metadata []byte `json:"metadata"`
|
||||
IsObserver bool `json:"is_observer"`
|
||||
ObserverID uuid.UUID `json:"observer_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetNodeByPubkey(ctx context.Context, publicKey []byte) (GetNodeByPubkeyRow, error) {
|
||||
row := q.db.QueryRow(ctx, getNodeByPubkey, publicKey)
|
||||
var i Node
|
||||
var i GetNodeByPubkeyRow
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.PublicKey,
|
||||
@@ -253,6 +301,8 @@ func (q *Queries) GetNodeByPubkey(ctx context.Context, publicKey []byte) (Node,
|
||||
&i.FirstSeen,
|
||||
&i.LastSeen,
|
||||
&i.Metadata,
|
||||
&i.IsObserver,
|
||||
&i.ObserverID,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@@ -1292,7 +1342,9 @@ func (q *Queries) ListNodeObservations(ctx context.Context, arg ListNodeObservat
|
||||
|
||||
const listNodes = `-- name: ListNodes :many
|
||||
SELECT n.id, n.public_key, n.node_type, n.name, n.latitude, n.longitude, n.last_seen,
|
||||
array_remove(array_agg(DISTINCT ni.iata ORDER BY ni.iata), NULL)::text[] AS iatas
|
||||
array_remove(array_agg(DISTINCT ni.iata ORDER BY ni.iata), NULL)::text[] AS iatas,
|
||||
EXISTS (SELECT 1 FROM observers o WHERE o.public_key = n.public_key) AS is_observer,
|
||||
(SELECT o.id FROM observers o WHERE o.public_key = n.public_key LIMIT 1) AS observer_id
|
||||
FROM nodes n
|
||||
LEFT JOIN node_iatas ni ON ni.node_id = n.id
|
||||
WHERE
|
||||
@@ -1320,14 +1372,16 @@ type ListNodesParams struct {
|
||||
}
|
||||
|
||||
type ListNodesRow struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
PublicKey []byte `json:"public_key"`
|
||||
NodeType int16 `json:"node_type"`
|
||||
Name *string `json:"name"`
|
||||
Latitude *float64 `json:"latitude"`
|
||||
Longitude *float64 `json:"longitude"`
|
||||
LastSeen pgtype.Timestamptz `json:"last_seen"`
|
||||
Iatas []string `json:"iatas"`
|
||||
ID uuid.UUID `json:"id"`
|
||||
PublicKey []byte `json:"public_key"`
|
||||
NodeType int16 `json:"node_type"`
|
||||
Name *string `json:"name"`
|
||||
Latitude *float64 `json:"latitude"`
|
||||
Longitude *float64 `json:"longitude"`
|
||||
LastSeen pgtype.Timestamptz `json:"last_seen"`
|
||||
Iatas []string `json:"iatas"`
|
||||
IsObserver bool `json:"is_observer"`
|
||||
ObserverID uuid.UUID `json:"observer_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) ListNodes(ctx context.Context, arg ListNodesParams) ([]ListNodesRow, error) {
|
||||
@@ -1357,6 +1411,8 @@ func (q *Queries) ListNodes(ctx context.Context, arg ListNodesParams) ([]ListNod
|
||||
&i.Longitude,
|
||||
&i.LastSeen,
|
||||
&i.Iatas,
|
||||
&i.IsObserver,
|
||||
&i.ObserverID,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+11
@@ -840,6 +840,8 @@ func (s *Store) ListNodes(ctx context.Context, nodeType int16, iata string, supp
|
||||
Latitude: v.Latitude,
|
||||
Longitude: v.Longitude,
|
||||
IATAs: v.Iatas,
|
||||
IsObserver: v.IsObserver,
|
||||
ObvserverID: nullableUUID(v.ObserverID),
|
||||
})
|
||||
}
|
||||
var nextCursor *int64
|
||||
@@ -875,6 +877,8 @@ func (s *Store) GetNode(ctx context.Context, nodeID uuid.UUID) (*api.Node, error
|
||||
Latitude: row.Latitude,
|
||||
Longitude: row.Longitude,
|
||||
IATAs: iatas,
|
||||
IsObserver: row.IsObserver,
|
||||
ObvserverID: nullableUUID(row.ObserverID),
|
||||
},
|
||||
LocationSource: row.LocationSource,
|
||||
SupportsMultibytePaths: row.SupportsMultibytePaths,
|
||||
@@ -1182,3 +1186,10 @@ func (s *Store) GetStatsTopObservers(ctx context.Context, iata string, since tim
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func nullableUUID(id uuid.UUID) *uuid.UUID {
|
||||
if id == (uuid.UUID{}) {
|
||||
return nil
|
||||
}
|
||||
return &id
|
||||
}
|
||||
|
||||
+10
-8
@@ -182,14 +182,16 @@ type ObserverTelemetry struct {
|
||||
|
||||
// NodeSummary is the minimal node representation used in list responses.
|
||||
type NodeSummary struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
PublicKey string `json:"publicKey"` // hex-encoded public key
|
||||
NodeType int16 `json:"nodeType"` // 1=companion, 2=repeater, 3=room server
|
||||
NodeTypeName string `json:"nodeTypeName"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
Latitude *float64 `json:"lat,omitempty"`
|
||||
Longitude *float64 `json:"lng,omitempty"`
|
||||
IATAs []string `json:"iatas"`
|
||||
ID uuid.UUID `json:"id"`
|
||||
PublicKey string `json:"publicKey"` // hex-encoded public key
|
||||
NodeType int16 `json:"nodeType"` // 1=companion, 2=repeater, 3=room server
|
||||
NodeTypeName string `json:"nodeTypeName"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
IsObserver bool `json:"isObserver"`
|
||||
ObvserverID *uuid.UUID `json:"observerId,omitempty"`
|
||||
Latitude *float64 `json:"lat,omitempty"`
|
||||
Longitude *float64 `json:"lng,omitempty"`
|
||||
IATAs []string `json:"iatas"`
|
||||
}
|
||||
|
||||
// Node is the full node representation including firmware capability flags,
|
||||
|
||||
Reference in New Issue
Block a user