R-1112: open the family store when the controller starts
gates / gates (push) Successful in 46s

Found on demo-hp with 0.325.0-rc.1: the store (and so the conversion of an old family.json) opened only on the
first family request; a box nobody visits through a family gate kept the session values. OpenFamilyStore from
main, one INFO line with the count. TestR1112_StartConvertsTheFamilyFile, TestR1112_MainOpensTheFamilyStore,
red-proved.

Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
2026-10-17 09:56:12 +02:00
parent 94f44931dd
commit 6ed223886d
6 changed files with 82 additions and 2 deletions
+3
View File
@@ -2058,6 +2058,9 @@ func main() {
// Browser .fab upload (v0.128.0): upload state is in-memory, so a restart strands the .part —
// GC stray part files in every registered drive's exports dir at startup.
webServer.CleanupStaleUploadParts()
// R-1112: open (and convert) the family list now, not on the first family request — a box nobody visits through a
// family gate would otherwise keep session values on disk.
webServer.OpenFamilyStore()
// Escrow wizard (v0.127.0): the Scenario-F stale-blob flag feeds the Távoli mentés card.
if escrowConfirmer != nil {
webServer.SetEscrowStale(escrowConfirmer.StaleBlob)
@@ -62,3 +62,24 @@ func TestR856_NormalGraceIsTheDeadAppBootGrace(t *testing.T) {
t.Errorf("crashboot.NormalGrace = %s, deadAppBootGrace = %s — a normal boot must keep today's grace", crashboot.NormalGrace, deadAppBootGrace)
}
}
// R-1112: main opens the family store at start (webServer.OpenFamilyStore), so an old family.json is converted on every
// box — not only on one where someone passes a family gate. Red-proof: remove the call from main.go → this fails.
func TestR1112_MainOpensTheFamilyStore(t *testing.T) {
f, err := parser.ParseFile(token.NewFileSet(), "main.go", nil, 0)
if err != nil {
t.Fatal(err)
}
found := false
ast.Inspect(f, func(n ast.Node) bool {
if call, ok := n.(*ast.CallExpr); ok {
if sel, ok := call.Fun.(*ast.SelectorExpr); ok && sel.Sel.Name == "OpenFamilyStore" {
found = true
}
}
return true
})
if !found {
t.Fatal("main.go does not call OpenFamilyStore — an old family.json keeps its session values until a family request")
}
}