A demo build can claim a real shop instead of running on its own

The first demo sealed the office cameras into the package and ran the
PC standalone - a copy of the product with no head office. The bundle
can now carry an installation code instead: setup redeems it exactly as
the app's Setup screen does, the PC joins the shop, and its cameras
arrive from head office on the first sync. The demo then IS the product
- login, Loya, head office - not a local imitation of it. The code is
single-use, so one bundle is one install. release.sh ships the bundle
with DEMO_PACK=.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KGcjxF1cNLcuwc3DAPcnfj
This commit is contained in:
2026-09-19 13:51:01 +05:30
parent 51b9cb9743
commit 4bd1718491
4 changed files with 130 additions and 23 deletions

View File

@@ -19,25 +19,34 @@ import (
)
func main() {
in := flag.String("cameras", "", "JSON array of cameras (id, host, port, path, username, password)")
in := flag.String("cameras", "", "JSON array of cameras (id, host, port, path, username, password) - the PC then runs on its own")
enrolCode := flag.String("enrol-code", "", "an installation code from head office - the PC then claims that shop and gets its cameras from there")
cloud := flag.String("cloud", "https://mcp.loyaly.ai", "head office, with -enrol-code")
out := flag.String("out", "demo-cameras.enc", "sealed bundle to write")
flag.Parse()
if *in == "" {
fmt.Fprintln(os.Stderr, "usage: behavision-demo-pack -cameras cameras.json [-out demo-cameras.enc]")
if *in == "" && *enrolCode == "" {
fmt.Fprintln(os.Stderr, "usage: behavision-demo-pack (-cameras cameras.json | -enrol-code CODE [-cloud URL]) [-out demo-cameras.enc]")
os.Exit(2)
}
raw, err := os.ReadFile(*in)
if err != nil {
die("read cameras: %v", err)
var payload demo.Payload
if *in != "" {
raw, err := os.ReadFile(*in)
if err != nil {
die("read cameras: %v", err)
}
if err := json.Unmarshal(raw, &payload.Cameras); err != nil {
die("cameras.json: %v", err)
}
if len(payload.Cameras) == 0 {
die("no cameras in %s", *in)
}
}
var cams []demo.Camera
if err := json.Unmarshal(raw, &cams); err != nil {
die("cameras.json: %v", err)
}
if len(cams) == 0 {
die("no cameras in %s", *in)
payload.EnrolCode = *enrolCode
if *enrolCode != "" {
payload.CloudBase = *cloud
}
cams := payload.Cameras
for i, c := range cams {
switch {
case c.ID == "":
@@ -50,7 +59,7 @@ func main() {
}
// Re-marshal so only the fields the engine accepts travel, in a stable
// shape, whatever extra keys the input happened to carry.
plain, err := json.Marshal(cams)
plain, err := json.Marshal(payload)
if err != nil {
die("marshal: %v", err)
}
@@ -67,7 +76,11 @@ func main() {
die("write: %v", err)
}
fmt.Printf("\n sealed %d camera(s) into %s (%d bytes)\n\n", len(cams), *out, len(sealed))
if payload.EnrolCode != "" {
fmt.Printf("\n sealed an installation code for %s into %s (%d bytes)\n\n", payload.CloudBase, *out, len(sealed))
} else {
fmt.Printf("\n sealed %d camera(s) into %s (%d bytes)\n\n", len(cams), *out, len(sealed))
}
fmt.Printf(" unlock code: %s\n\n", code)
fmt.Println(" Shown once. Give it to whoever runs behavision-setup, by voice")
fmt.Println(" or message - not in the same place as the zip.")