package main
import (
"bytes"
"database/sql"
"encoding/json"
"fmt"
"html/template"
"io"
"log"
"net/http"
"os"
"sort"
"strings"
"time"
_ "modernc.org/sqlite"
)
const (
fireworksKey = "fw_RVcDe4c6mN4utKLsgA7hTm"
fireworksModel = "accounts/fireworks/models/gpt-oss-20b"
fireworksURL = "https://api.fireworks.ai/inference/v1/chat/completions"
)
var systemPrompt = `You are the Vault1984 NOC assistant. Vault1984 is a global network of security POPs (Points of Presence) across 21 regions.
Your job is to:
- Help users report network problems or outages
- Answer questions about Vault1984 infrastructure status
- Collect details about issues (region, symptoms, timestamps)
- Be concise and professional
If someone reports a problem, acknowledge it, collect: affected region, what they observed, and when it started. Keep responses short.`
const version = "v0.4"
const (
colorGreen = "#76AD2A"
colorOrange = "#E86235"
colorRed = "#E04343"
colorGray = "#D8D6D0"
)
// Schema
const schema = `
CREATE TABLE IF NOT EXISTS nodes (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
region TEXT NOT NULL,
ip TEXT NOT NULL DEFAULT '',
status TEXT NOT NULL DEFAULT 'planned'
);
CREATE TABLE IF NOT EXISTS uptime (
node_id TEXT NOT NULL,
date TEXT NOT NULL, -- YYYY-MM-DD
status TEXT NOT NULL, -- operational | degraded | outage | planned
PRIMARY KEY (node_id, date)
);
CREATE TABLE IF NOT EXISTS incidents (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
status TEXT NOT NULL, -- resolved | monitoring | investigating
date TEXT NOT NULL, -- display date e.g. "Mar 4, 2026"
node_ids TEXT NOT NULL DEFAULT '',
created_at INTEGER NOT NULL DEFAULT (strftime('%s','now'))
);
CREATE TABLE IF NOT EXISTS incident_updates (
id INTEGER PRIMARY KEY AUTOINCREMENT,
incident_id INTEGER NOT NULL REFERENCES incidents(id),
ts TEXT NOT NULL, -- ISO8601 e.g. "2026-03-04 16:08 UTC"
status TEXT NOT NULL, -- investigating | identified | monitoring | resolved
body TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS telemetry (
id INTEGER PRIMARY KEY AUTOINCREMENT,
node_id TEXT NOT NULL,
received_at INTEGER NOT NULL DEFAULT (strftime('%s','now')),
version TEXT NOT NULL DEFAULT '',
hostname TEXT NOT NULL DEFAULT '',
uptime_seconds INTEGER NOT NULL DEFAULT 0,
cpu_percent REAL NOT NULL DEFAULT 0,
memory_total_mb INTEGER NOT NULL DEFAULT 0,
memory_used_mb INTEGER NOT NULL DEFAULT 0,
disk_total_mb INTEGER NOT NULL DEFAULT 0,
disk_used_mb INTEGER NOT NULL DEFAULT 0,
load_1m REAL NOT NULL DEFAULT 0,
vault_count INTEGER NOT NULL DEFAULT 0,
vault_size_mb REAL NOT NULL DEFAULT 0,
vault_entries INTEGER NOT NULL DEFAULT 0,
mode TEXT NOT NULL DEFAULT ''
);
`
type Node struct {
ID string
Name string
Region string
IP string
Status string
History []DayStatus
}
type DayStatus struct {
Date string
Status string
}
type IncidentUpdate struct {
TS string
Status string
Body string
}
type Incident struct {
ID int64
Title string
Status string
Date string
NodeIDs string
Updates []IncidentUpdate
}
type PageData struct {
UpdatedAt string
OverallOK bool
Nodes []*Node
Incidents []Incident
}
func (n *Node) UptimePct() string {
if n.Status == "planned" {
return "—"
}
total, ok := 0, 0
for _, h := range n.History {
if h.Status == "planned" || h.Status == "nodata" {
continue
}
total++
if h.Status == "operational" {
ok++
}
}
if total == 0 {
return "—"
}
return fmt.Sprintf("%.2f%%", float64(ok)/float64(total)*100)
}
func (n *Node) SVGBars() template.HTML {
var sb strings.Builder
sb.WriteString(``)
return template.HTML(sb.String())
}
func (n *Node) StatusLabel() string {
switch n.Status {
case "operational":
return "Operational"
case "degraded":
return "Degraded Performance"
case "outage":
return "Major Outage"
case "planned":
return "Planned"
}
return "Unknown"
}
func (n *Node) StatusColor() string {
switch n.Status {
case "operational":
return colorGreen
case "degraded":
return colorOrange
case "outage":
return colorRed
}
return colorGray
}
func nodeOrder(n *Node) int {
if n.ID == "hq-zurich" {
return 0
}
if n.Status == "operational" {
return 1
}
return 2
}
var db *sql.DB
// seedData populates the DB on first run
func seedData() {
// Insert nodes
nodeList := []struct{ id, name, region, ip, status string }{
{"virginia", "Virginia", "us-east-1", "18.209.55.127", "operational"},
{"singapore", "Singapore", "ap-southeast-1", "47.129.4.217", "operational"},
{"zurich", "Zürich", "eu-central-2", "16.18.20.81", "operational"},
{"ncalifornia", "N. California", "us-west-1", "", "planned"},
{"montreal", "Montreal", "ca-central-1", "", "planned"},
{"mexicocity", "Mexico City", "mx-central-1", "", "planned"},
{"saopaulo", "São Paulo", "sa-east-1", "", "planned"},
{"london", "London", "eu-west-2", "", "planned"},
{"paris", "Paris", "eu-west-3", "", "planned"},
{"spain", "Spain", "eu-south-2", "", "planned"},
{"stockholm", "Stockholm", "eu-north-1", "", "planned"},
{"uae", "UAE", "me-central-1", "", "planned"},
{"telaviv", "Tel Aviv", "il-central-1", "", "planned"},
{"capetown", "Cape Town", "af-south-1", "", "planned"},
{"mumbai", "Mumbai", "ap-south-1", "", "planned"},
{"jakarta", "Jakarta", "ap-southeast-3", "", "planned"},
{"malaysia", "Malaysia", "ap-southeast-5", "", "planned"},
{"sydney", "Sydney", "ap-southeast-2", "", "planned"},
{"seoul", "Seoul", "ap-northeast-2", "", "planned"},
{"hongkong", "Hong Kong", "ap-east-1", "", "planned"},
{"tokyo", "Tokyo", "ap-northeast-1", "", "planned"},
}
for _, n := range nodeList {
db.Exec(`INSERT OR IGNORE INTO nodes(id,name,region,ip,status) VALUES(?,?,?,?,?)`,
n.id, n.name, n.region, n.ip, n.status)
}
// Planned nodes: seed gray bars so the UI renders correctly
var plannedIDs []string
rows, _ := db.Query(`SELECT id FROM nodes WHERE status='planned'`)
for rows.Next() {
var id string
rows.Scan(&id)
plannedIDs = append(plannedIDs, id)
}
rows.Close()
now := time.Now()
for _, nodeID := range plannedIDs {
for i := 89; i >= 0; i-- {
date := now.AddDate(0, 0, -i).Format("2006-01-02")
db.Exec(`INSERT OR IGNORE INTO uptime(node_id,date,status) VALUES(?,?,?)`, nodeID, date, "planned")
}
}
}
func loadNodes() []*Node {
rows, err := db.Query(`SELECT id,name,region,ip,status FROM nodes`)
if err != nil {
log.Printf("loadNodes error: %v", err)
return nil
}
defer rows.Close()
var nodes []*Node
for rows.Next() {
n := &Node{}
rows.Scan(&n.ID, &n.Name, &n.Region, &n.IP, &n.Status)
nodes = append(nodes, n)
}
// Load 90-day history for each node
now := time.Now()
for _, n := range nodes {
n.History = make([]DayStatus, 90)
// Build date map from DB
histMap := map[string]string{}
hrows, _ := db.Query(`SELECT date,status FROM uptime WHERE node_id=? ORDER BY date`, n.ID)
for hrows.Next() {
var date, status string
hrows.Scan(&date, &status)
histMap[date] = status
}
hrows.Close()
for i := 0; i < 90; i++ {
date := now.AddDate(0, 0, -(89 - i)).Format("2006-01-02")
status, ok := histMap[date]
if !ok {
if n.Status == "planned" {
status = "planned"
} else {
status = "nodata" // live node, no record yet — render transparent
}
}
n.History[i] = DayStatus{Date: date, Status: status}
}
}
sort.SliceStable(nodes, func(i, j int) bool {
oi, oj := nodeOrder(nodes[i]), nodeOrder(nodes[j])
if oi != oj {
return oi < oj
}
return nodes[i].Name < nodes[j].Name
})
return nodes
}
func loadIncidents() []Incident {
rows, err := db.Query(`SELECT id,title,status,date,node_ids FROM incidents ORDER BY created_at DESC`)
if err != nil {
return nil
}
defer rows.Close()
var list []Incident
for rows.Next() {
var inc Incident
rows.Scan(&inc.ID, &inc.Title, &inc.Status, &inc.Date, &inc.NodeIDs)
list = append(list, inc)
}
rows.Close()
// Load updates for each incident
for i := range list {
urows, err := db.Query(
`SELECT ts,status,body FROM incident_updates WHERE incident_id=? ORDER BY id ASC`,
list[i].ID,
)
if err != nil {
continue
}
for urows.Next() {
var u IncidentUpdate
urows.Scan(&u.TS, &u.Status, &u.Body)
list[i].Updates = append(list[i].Updates, u)
}
urows.Close()
}
return list
}
func buildPage() PageData {
nodes := loadNodes()
ok := true
for _, n := range nodes {
if n.Status == "outage" || n.Status == "degraded" {
ok = false
break
}
}
return PageData{
UpdatedAt: time.Now().UTC().Format("Jan 2, 2006 15:04 UTC"),
OverallOK: ok,
Nodes: nodes,
Incidents: loadIncidents(),
}
}
var tpl = template.Must(template.New("page").Parse(`