package ledger import ( "encoding/json" "strings" "github.com/tech/sendico/pkg/model" "github.com/tech/sendico/pkg/mservice" "go.mongodb.org/mongo-driver/bson/primitive" ) // PartyKind (string-backed enum) — readable in BSON/JSON, safe in Go. type PartyKind string const ( PartyKindPerson PartyKind = "person" PartyKindOrganization PartyKind = "organization" PartyKindExternal PartyKind = "external" // not mapped to internal user/org ) func (k *PartyKind) UnmarshalJSON(b []byte) error { var s string if err := json.Unmarshal(b, &s); err != nil { return err } switch PartyKind(s) { case PartyKindPerson, PartyKindOrganization, PartyKindExternal: *k = PartyKind(s) return nil default: return &ValidationError{Issues: []ValidationIssue{{ Field: "kind", Code: "invalid_kind", Msg: "expected person|organization|external", }}} } } // Party represents a legal person or organization that can own accounts. // Composed with your storable.Base and model.PermissionBound. type Party struct { model.PermissionBound `bson:",inline" json:",inline"` Kind PartyKind `bson:"kind" json:"kind"` Name string `bson:"name" json:"name"` UserRef *primitive.ObjectID `bson:"userRef,omitempty" json:"userRef,omitempty"` // internal user, if applicable OrganizationRef *primitive.ObjectID `bson:"organizationRef,omitempty" json:"organizationRef,omitempty"` // internal org, if applicable // add your own fields here if needed (KYC flags, etc.) } func (p *Party) Collection() string { return mservice.LedgerParties } func (p *Party) Validate() error { var verr *ValidationError if strings.TrimSpace(p.Name) == "" { veAdd(&verr, "name", "required", "party name is required") } switch p.Kind { case PartyKindPerson: if p.OrganizationRef != nil { veAdd(&verr, "organizationRef", "must_be_nil", "person party cannot have organizationRef") } case PartyKindOrganization: if p.UserRef != nil { veAdd(&verr, "userRef", "must_be_nil", "organization party cannot have userRef") } case PartyKindExternal: if p.UserRef != nil || p.OrganizationRef != nil { veAdd(&verr, "refs", "must_be_nil", "external party cannot reference internal user/org") } default: veAdd(&verr, "kind", "invalid", "unknown party kind") } return verr }