package store import ( "crypto/rand" "encoding/hex" "github.com/google/uuid" ) // rowScanner is the subset of *sql.Row / *sql.Rows used by row scanners // across this package. Kept package-private — callers should not need to // implement it themselves. type rowScanner interface { Scan(dest ...any) error } // BoolToInt converts a Go bool to the 0/1 INTEGER convention SQLite uses // for boolean columns across this schema. func BoolToInt(b bool) int { if b { return 1 } return 0 } // GenerateWebhookSecret returns a 256-bit hex-encoded random token. // Exported so the api layer can share one implementation — keeping // two copies invited drift (one panicked, one fell back to UUID). // crypto/rand directly rather than uuid.New() so the intent ("secret // token, not identifier") is explicit and the entropy is unambiguous. func GenerateWebhookSecret() string { b := make([]byte, 32) if _, err := rand.Read(b); err != nil { // crypto/rand is documented to never fail on supported platforms; // fall back to a UUID rather than panicking. return uuid.New().String() } return hex.EncodeToString(b) } // generateWebhookSecret is the in-package alias kept for the existing // CRUD call sites that don't reach across packages. New callers in // other packages should use GenerateWebhookSecret directly. func generateWebhookSecret() string { return GenerateWebhookSecret() }