package livestore import ( "context" "cloud.google.com/go/firestore" ) //go:generate go tool mockgen -source ./membershippublisher.go -destination ./mocks/membershippublisher.go // MembershipPublisher fans network membership changes out to Firestore. // Postgres is the source of truth; the reconciler heals drift, so publish // failures are safe to log and ignore. type MembershipPublisher interface { Add(ctx context.Context, humanId, networkID string) error Remove(ctx context.Context, humanId, networkID string) error } func NewMembershipPublisher(fs *firestore.Client) MembershipPublisher { return &firestoreMembershipPublisher{fs: fs} } type firestoreMembershipPublisher struct { fs *firestore.Client } func (p *firestoreMembershipPublisher) Add(ctx context.Context, humanId, networkID string) error { _, err := p.fs.Collection("humans").Doc(humanId).Set(ctx, map[string]any{ "networks": firestore.ArrayUnion(networkID), "updated_at": firestore.ServerTimestamp, }, firestore.MergeAll) return err } func (p *firestoreMembershipPublisher) Remove(ctx context.Context, humanId, networkID string) error { _, err := p.fs.Collection("humans").Doc(humanId).Set(ctx, map[string]any{ "networks": firestore.ArrayRemove(networkID), "updated_at": firestore.ServerTimestamp, }, firestore.MergeAll) return err }