Files
backend_fiesta/scratch/buddystatus/main.go
2026-09-24 13:15:47 +05:30

82 lines
2.4 KiB
Go

// Asks the deployed server whether Nearle Buddy has a model.
//
// go run ./scratch/buddystatus # production
// go run ./scratch/buddystatus http://localhost:1122
//
// `/assistant/status` sits behind the session guard, so this mints one. That it
// CAN mint one, from a secret sitting in a tracked file, is itself the finding
// recorded in middleware/webauth.go: anybody with repository access can issue a
// session for any tenant. Rotating POS_TOKEN_SECRET out of `.env.local` is the
// fix, and this tool stops working the day that happens — which is correct.
//
// Read-only. It asks one question and prints the answer.
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"strings"
"time"
"nearle/utils"
"github.com/joho/godotenv"
)
func main() {
// The secret lives in the env files, not in this program.
_ = godotenv.Load(".env.local")
_ = godotenv.Load(".env")
host := "https://fiesta.nearle.app"
if len(os.Args) > 1 {
host = strings.TrimRight(os.Args[1], "/")
}
token, _, err := utils.MintWebToken(utils.WebClaims{Userid: 904, Tenantid: 1147}, time.Now())
if err != nil {
fmt.Println("cannot mint a session:", err)
fmt.Println("POS_TOKEN_SECRET is not set here, or is shorter than 16 characters.")
os.Exit(1)
}
url := host + "/live/api/v1/web/assistant/status"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("Authorization", "Bearer "+token)
resp, err := (&http.Client{Timeout: 20 * time.Second}).Do(req)
if err != nil {
fmt.Println("could not reach", url, err)
os.Exit(1)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Printf("%s\nHTTP %d\n%s\n\n", url, resp.StatusCode, body)
var envelope struct {
Details struct {
Available bool `json:"available"`
Reason string `json:"reason"`
} `json:"details"`
}
if json.Unmarshal(body, &envelope) != nil {
return
}
switch {
case resp.StatusCode == http.StatusUnauthorized:
fmt.Println("The session was refused — this deployment signs with a different secret.")
case envelope.Details.Available:
fmt.Println("Buddy has a model. The composer should accept a question on Console, Sales and Inventory.")
case envelope.Details.Reason != "":
fmt.Println("Buddy is off:", envelope.Details.Reason)
default:
fmt.Println("Buddy is off. This build does not say why — ASSISTANT_BASE_URL, ASSISTANT_MODEL")
fmt.Println("and ASSISTANT_API_KEY are what it needs, set on the platform and redeployed.")
}
}