feat(panel): reskin backend — node sortIndex, presence/speed, /api/system, credentials, subscription aggregation (Node+Go parity)

This commit is contained in:
aaaamoooo
2026-10-20 18:09:07 +00:00
parent 7c21742810
commit 011eecc096
23 changed files with 3370 additions and 146 deletions
+69 -17
View File
@@ -217,23 +217,24 @@ func recordJSON[T any](raw []byte, dst *T, extra *extraFields) error {
// ---------- database ----------
type Data struct {
SchemaVersion int `json:"schemaVersion"`
CreatedAt string `json:"createdAt"`
Settings Settings `json:"settings"`
Users []*User `json:"users"`
Servers []*Server `json:"servers"`
Agents []*Agent `json:"agents"`
EnrollmentTokens []*EnrollmentToken `json:"enrollmentTokens"`
Customers []*Customer `json:"customers"`
Nodes []*Node `json:"nodes"`
NodeClients []*NodeClient `json:"nodeClients"`
Jobs []*Job `json:"jobs"`
Activity []*Activity `json:"activity"`
Observations []*Observation `json:"observations"`
SubscriptionAccess []*SubscriptionAccess `json:"subscriptionAccess"`
SubscriptionClients []*SubscriptionClient `json:"subscriptionClients"`
KeyStore map[string]*KeyEntry `json:"keyStore"`
Extra extraFields `json:"-"`
SchemaVersion int `json:"schemaVersion"`
CreatedAt string `json:"createdAt"`
Settings Settings `json:"settings"`
Users []*User `json:"users"`
Servers []*Server `json:"servers"`
Agents []*Agent `json:"agents"`
EnrollmentTokens []*EnrollmentToken `json:"enrollmentTokens"`
Customers []*Customer `json:"customers"`
Nodes []*Node `json:"nodes"`
NodeClients []*NodeClient `json:"nodeClients"`
Jobs []*Job `json:"jobs"`
Activity []*Activity `json:"activity"`
Observations []*Observation `json:"observations"`
SubscriptionAccess []*SubscriptionAccess `json:"subscriptionAccess"`
SubscriptionClients []*SubscriptionClient `json:"subscriptionClients"`
KeyStore map[string]*KeyEntry `json:"keyStore"`
SubSourceCache map[string]*SubSourceCacheEntry `json:"subSourceCache,omitempty"`
Extra extraFields `json:"-"`
}
func (d *Data) UnmarshalJSON(raw []byte) error {
@@ -272,6 +273,8 @@ type Settings struct {
ObservationTtlMinutes float64 `json:"observationTtlMinutes"`
ActivityRetentionDays float64 `json:"activityRetentionDays"`
CompletedJobRetentionDays float64 `json:"completedJobRetentionDays"`
ExternalSubRefreshMinutes float64 `json:"externalSubRefreshMinutes,omitempty"`
AllowPrivateSubSources bool `json:"allowPrivateSubSources,omitempty"`
Extra extraFields `json:"-"`
}
@@ -379,6 +382,7 @@ type Server struct {
PortRangeEnd int `json:"portRangeEnd"`
Labels []string `json:"labels"`
Status string `json:"status"`
Enabled *bool `json:"enabled,omitempty"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
LastSeenAt *string `json:"lastSeenAt,omitempty"`
@@ -501,6 +505,11 @@ func (c UsageCounters) MarshalJSON() ([]byte, error) {
type UsageSlot struct {
UsageCounters *UsageCounters `json:"usageCounters,omitempty"`
RetiredUsageEpochs []string `json:"retiredUsageEpochs,omitempty"`
LastSampleAt *string `json:"lastSampleAt,omitempty"`
LastActiveAt *string `json:"lastActiveAt,omitempty"`
SpeedUpBps *float64 `json:"speedUpBps,omitempty"`
SpeedDownBps *float64 `json:"speedDownBps,omitempty"`
SpeedAt *string `json:"speedAt,omitempty"`
Extra extraFields `json:"-"`
}
@@ -545,9 +554,46 @@ type Customer struct {
ServerUsage map[string]*UsageSlot `json:"serverUsage,omitempty"`
LastUsageAt *string `json:"lastUsageAt,omitempty"`
LastOnlineAt *string `json:"lastOnlineAt,omitempty"`
ExternalSources []ExtSource `json:"externalSources,omitempty"`
ManualLinks []ManualLink `json:"manualLinks,omitempty"`
Extra extraFields `json:"-"`
}
// ExtSource is one external subscription source on a customer
// (SUB-AGGREGATION-DESIGN.md). UserAgent is optional.
type ExtSource struct {
ID string `json:"id"`
URL string `json:"url"`
Remark string `json:"remark"`
Enabled bool `json:"enabled"`
UserAgent string `json:"userAgent,omitempty"`
}
// ManualLink is one hand-added node link on a customer.
type ManualLink struct {
ID string `json:"id"`
URI string `json:"uri"`
Remark string `json:"remark"`
Enabled bool `json:"enabled"`
}
// SubCacheItem is one parsed entry of a fetched external source.
type SubCacheItem struct {
URI string `json:"uri"`
Name string `json:"name"`
}
// SubSourceCacheEntry is the fetch cache for one external source,
// stored top-level in data.subSourceCache keyed by source id.
type SubSourceCacheEntry struct {
FetchedAt *string `json:"fetchedAt"`
OkAt *string `json:"okAt"`
FailCount int `json:"failCount"`
LastError *string `json:"lastError"`
DroppedCount int `json:"droppedCount"`
Items []SubCacheItem `json:"items"`
}
func (c *Customer) UnmarshalJSON(raw []byte) error {
type plain Customer
var p plain
@@ -678,6 +724,12 @@ type Node struct {
RetiredUsageEpochs []string `json:"retiredUsageEpochs"`
MeteredTraffic *MeteredTraffic `json:"meteredTraffic"`
LastUsageAt *string `json:"lastUsageAt"`
SortIndex int `json:"sortIndex"`
SpeedUpBps *float64 `json:"speedUpBps,omitempty"`
SpeedDownBps *float64 `json:"speedDownBps,omitempty"`
SpeedAt *string `json:"speedAt,omitempty"`
LastActiveAt *string `json:"lastActiveAt,omitempty"`
LastSampleAt *string `json:"lastSampleAt,omitempty"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
Extra extraFields `json:"-"`