add profile actors
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
// Package profile implements a user-profile actor grain (same event-driven
|
||||
// framework as the cart, checkout, and order grains). Mutations are the proto
|
||||
// messages in proto/profile; the grain's event log is the source of truth and
|
||||
// ProfileGrain is the projection rebuilt by replaying them.
|
||||
package profile
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// LinkedCart records a cart id linked to this profile.
|
||||
type LinkedCart struct {
|
||||
CartId uint64 `json:"cartId"`
|
||||
Label string `json:"label,omitempty"`
|
||||
}
|
||||
|
||||
// LinkedCheckout records a checkout id linked to this profile.
|
||||
type LinkedCheckout struct {
|
||||
CheckoutId uint64 `json:"checkoutId"`
|
||||
CartId uint64 `json:"cartId"`
|
||||
}
|
||||
|
||||
// LinkedOrder records an order linked to this profile.
|
||||
type LinkedOrder struct {
|
||||
OrderReference string `json:"orderReference"`
|
||||
CartId uint64 `json:"cartId"`
|
||||
Status string `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// StoredAddress is a saved address in the user's address book.
|
||||
type StoredAddress struct {
|
||||
Id uint32 `json:"id"`
|
||||
Label string `json:"label,omitempty"`
|
||||
FullName string `json:"fullName,omitempty"`
|
||||
AddressLine1 string `json:"addressLine1"`
|
||||
AddressLine2 string `json:"addressLine2,omitempty"`
|
||||
City string `json:"city"`
|
||||
State string `json:"state,omitempty"`
|
||||
Zip string `json:"zip"`
|
||||
Country string `json:"country"`
|
||||
Phone string `json:"phone,omitempty"`
|
||||
IsDefaultShipping bool `json:"isDefaultShipping,omitempty"`
|
||||
IsDefaultBilling bool `json:"isDefaultBilling,omitempty"`
|
||||
}
|
||||
|
||||
// ProfileGrain is the projected current state of a user profile. It implements
|
||||
// actor.Grain[ProfileGrain].
|
||||
type ProfileGrain struct {
|
||||
mu sync.RWMutex
|
||||
lastAccess time.Time
|
||||
lastChange time.Time
|
||||
nextAddrId uint32
|
||||
|
||||
Id uint64 `json:"id"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
Phone string `json:"phone,omitempty"`
|
||||
Language string `json:"language,omitempty"`
|
||||
Currency string `json:"currency,omitempty"`
|
||||
|
||||
AvatarUrl string `json:"avatarUrl,omitempty"`
|
||||
Carts []LinkedCart `json:"carts,omitempty"`
|
||||
Checkouts []LinkedCheckout `json:"checkouts,omitempty"`
|
||||
Orders []LinkedOrder `json:"orders,omitempty"`
|
||||
Addresses []StoredAddress `json:"addresses,omitempty"`
|
||||
}
|
||||
|
||||
// NewProfileGrain returns an empty profile grain for id.
|
||||
func NewProfileGrain(id uint64, ts time.Time) *ProfileGrain {
|
||||
return &ProfileGrain{
|
||||
Id: id,
|
||||
lastAccess: ts,
|
||||
lastChange: ts,
|
||||
}
|
||||
}
|
||||
|
||||
// --- actor.Grain[ProfileGrain] ---
|
||||
|
||||
func (p *ProfileGrain) GetId() uint64 { return p.Id }
|
||||
|
||||
func (p *ProfileGrain) GetLastAccess() time.Time { return p.lastAccess }
|
||||
|
||||
func (p *ProfileGrain) GetLastChange() time.Time { return p.lastChange }
|
||||
|
||||
func (p *ProfileGrain) GetCurrentState() (*ProfileGrain, error) {
|
||||
p.lastAccess = time.Now()
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (p *ProfileGrain) GetState() ([]byte, error) { return json.Marshal(p) }
|
||||
|
||||
// NextAddrId returns the next address id and advances the counter.
|
||||
func (p *ProfileGrain) NextAddrId() uint32 {
|
||||
p.nextAddrId++
|
||||
return p.nextAddrId
|
||||
}
|
||||
|
||||
// findAddress returns a pointer to the address with the given id, or nil.
|
||||
func (p *ProfileGrain) findAddress(id uint32) *StoredAddress {
|
||||
for i := range p.Addresses {
|
||||
if p.Addresses[i].Id == id {
|
||||
return &p.Addresses[i]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user