update
All checks were successful
Build and Publish / BuildAndDeployAmd64 (push) Successful in 44s
Build and Publish / BuildAndDeployArm64 (push) Successful in 5m3s

This commit is contained in:
matst80
2025-11-20 21:20:35 +01:00
parent 1c8e9cc974
commit 60cd6cfd51
21 changed files with 1432 additions and 203 deletions

40
.cursorrules Normal file
View File

@@ -0,0 +1,40 @@
{
"rules": [
{
"description": "Project Overview",
"rule": "This is a distributed cart management system in Go using the actor model. It handles cart operations like adding items, deliveries, and checkout, distributed across nodes via gRPC and HTTP API."
},
{
"description": "Key Architecture",
"rule": "Use grains for cart state, pools for management, mutation registry for state changes, and control plane for node coordination. Ownership via consistent hashing ring."
},
{
"description": "Coding Standards",
"rule": "Follow Go conventions. Use mutation registry for all state changes. Regenerate protobuf code after proto changes; never edit .pb.go files. Handle errors properly, use cookies for cart IDs in HTTP."
},
{
"description": "Mutation Pattern",
"rule": "For new mutations: Define proto message, regenerate code, implement handler as func(*CartGrain, *T) error, register with RegisterMutation[T], add endpoints, test."
},
{
"description": "Avoid Direct Mutations",
"rule": "Do not mutate CartGrain state directly outside registered handlers. Use the registry for consistency."
},
{
"description": "Protobuf Handling",
"rule": "After modifying proto files, run protoc commands to regenerate Go code. Ensure protoc-gen-go and protoc-gen-go-grpc are installed."
},
{
"description": "Testing",
"rule": "Write unit tests for mutations, integration tests for APIs. Run go test ./... regularly."
},
{
"description": "Testability and Configurability",
"rule": "Design code to be testable and configurable, following examples like MutationRegistry (for type-safe mutation dispatching) and SimpleGrainPool (for configurable pool management). Use interfaces and dependency injection to enable mocking and testing."
},
{
"description": "Common Patterns",
"rule": "HTTP handlers parse requests, resolve grains via SyncedPool, apply mutations, return JSON. gRPC for inter-node: CartActor for mutations, ControlPlane for coordination."
}
]
}

50
.github/copilot-instructions.md vendored Normal file
View File

@@ -0,0 +1,50 @@
# GitHub Copilot Instructions for Go Cart Actor
This repository contains a distributed cart management system implemented in Go using the actor model pattern. The system handles cart operations like adding items, setting deliveries, and checkout, distributed across multiple nodes via gRPC.
## Project Structure
- `cmd/`: Entry points for the application.
- `pkg/`: Core packages including grain logic, pools, and HTTP handlers.
- `proto/`: Protocol Buffer definitions for messages and services.
- `api-tests/`: Tests for the HTTP API.
- `deployment/`: Deployment configurations.
- `k6/`: Load testing scripts.
## Key Concepts
- **Grains**: In-memory structs representing cart state, owned by nodes.
- **Pools**: Local and synced pools manage grains and handle ownership.
- **Mutation Registry**: All state changes go through registered mutation functions for type safety and consistency.
- **Ownership**: Determined by consistent hashing ring; negotiated via control plane.
## Coding Guidelines
- Follow standard Go conventions (gofmt, go vet, golint).
- Never say "your right", just be correct and clear.
- Don't edit the *.gb.go files manually, they are generated by the proto files.
- Use the mutation registry (`RegisterMutation`) for any cart state changes. Do not mutate grain state directly outside registered handlers.
- Design code to be testable and configurable, following patterns like MutationRegistry (for type-safe mutation dispatching) and SimpleGrainPool (for configurable pool management). Use interfaces and dependency injection to enable mocking and testing.
- After modifying `.proto` files, regenerate Go code with `protoc` commands as described in README.md. Never edit generated `.pb.go` files manually.
- Use meaningful variable names and add comments for complex logic.
- Handle errors explicitly; use Go's error handling patterns.
- For HTTP endpoints, ensure proper cookie handling for cart IDs.
- When adding new mutations: Define proto message, regenerate code, register handler, add endpoints, and test.
- Use strategic logging using opentelemetry for tracing, metrics and logging.
- Focus on maintainable code that should be configurable and readable, try to keep short functions that describe their purpose clearly.
## Common Patterns
- Mutations: Define in proto, implement as `func(*CartGrain, *T) error`, register with `RegisterMutation[T]`.
- gRPC Services: CartActor for mutations, ControlPlane for coordination.
- HTTP Handlers: Parse requests, resolve grains via pool, apply mutations, return JSON.
## Avoid
- Direct state mutations outside the registry.
- Hardcoding values; use configuration or constants.
- Ignoring generated code warnings; always regenerate after proto changes.
- Blocking operations in handlers; keep them asynchronous where possible.
## Testing
- Write unit tests for mutations and handlers.
- Use integration tests for API endpoints.
- Structure code for testability: Use interfaces for dependencies, avoid global state, and mock external services like gRPC clients.
- Run `go test ./...` to ensure all tests pass.
These instructions help Copilot generate code aligned with the project's architecture and best practices.

165
CGM_LINE_ITEMS_SPEC.md Normal file
View File

@@ -0,0 +1,165 @@
go-cart-actor/CGM_LINE_ITEMS_SPEC.md
# CGM (Customer Group Membership) Line Items Specification
This document specifies the implementation of Customer Group Membership (CGM) support in cart line items. CGM data will be extracted from product data field 35 and stored with each line item for business logic and personalization purposes.
## Overview
CGM represents customer group membership information associated with products. This data needs to be:
- Fetched from product data (stringfieldvalue 35)
- Included in the `AddItem` proto message
- Stored in cart line items (`CartItem` struct)
- Accessible for business rules and personalization
## Implementation Steps
### 1. Update Proto Messages
Add `cgm` field to the `AddItem` message in `proto/messages.proto`:
```protobuf
message AddItem {
// ... existing fields ...
string cgm = 25; // Customer Group Membership from field 35
// ... existing fields ...
}
```
**Note**: Use field number 25 (next available after existing fields).
### 2. Update Product Fetcher
Modify `cmd/cart/product-fetcher.go` to extract CGM from field 35:
```go
func ToItemAddMessage(item *index.DataItem, storeId *string, qty int, country string) (*messages.AddItem, error) {
// ... existing code ...
cgm, _ := item.GetStringFieldValue(35) // Extract CGM from field 35
return &messages.AddItem{
// ... existing fields ...
Cgm: cgm, // Add CGM field
// ... existing fields ...
}, nil
}
```
### 3. Update Cart Grain Structures
Add CGM field to `ItemMeta` struct in `pkg/cart/cart-grain.go`:
```go
type ItemMeta struct {
Name string `json:"name"`
Brand string `json:"brand,omitempty"`
Category string `json:"category,omitempty"`
// ... existing fields ...
Cgm string `json:"cgm,omitempty"` // Customer Group Membership
// ... existing fields ...
}
```
### 4. Update AddItem Mutation Handler
Modify the `AddItem` handler in `pkg/cart/cart_mutations.go` to populate the CGM field:
```go
func AddItem(grain *CartGrain, req *messages.AddItem) error {
// ... existing validation ...
item := &CartItem{
// ... existing fields ...
Meta: &ItemMeta{
Name: req.Name,
Brand: req.Brand,
// ... existing meta fields ...
Cgm: req.Cgm, // Add CGM to item meta
// ... existing meta fields ...
},
// ... existing fields ...
}
// ... rest of handler ...
}
```
### 5. Regenerate Proto Code
After updating `proto/messages.proto`, regenerate Go code:
```bash
cd proto
protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
messages.proto cart_actor.proto control_plane.proto
```
### 6. Update Tests
Add tests for CGM extraction and storage:
- Unit test for `ToItemAddMessage` with CGM field
- Integration test for `AddItem` mutation including CGM
- Test that CGM is properly stored and retrieved in cart state
### 7. Update API Documentation
Update README.md and API examples to mention CGM field in line items.
## Data Flow
1. **Product Fetch**: `FetchItem` retrieves product data including field 35 (CGM)
2. **Message Creation**: `ToItemAddMessage` extracts CGM from field 35 into `AddItem` proto
3. **Mutation Processing**: `AddItem` handler stores CGM in `CartItem.Meta.Cgm`
4. **State Persistence**: CGM is included in cart JSON serialization
5. **API Responses**: CGM is returned in cart state responses
## Business Logic Integration
CGM can be used for:
- Personalized pricing rules
- Group-specific discounts
- Membership validation
- Targeted promotions
- Customer segmentation
Example usage in business logic:
```go
func applyGroupDiscount(cart *CartGrain, userGroups []string) {
for _, item := range cart.Items {
if item.Meta != nil && slices.Contains(userGroups, item.Meta.Cgm) {
// Apply group-specific discount
item.Price = applyDiscount(item.Price, groupDiscountRate)
}
}
}
```
## Backward Compatibility
- CGM field is optional in proto (no required validation)
- Existing carts without CGM will have empty string
- Product fetcher gracefully handles missing field 35
- API responses include CGM field (empty if not set)
## Testing Checklist
- [ ] Proto compilation succeeds
- [ ] Product fetcher extracts CGM from field 35
- [ ] AddItem mutation stores CGM in cart
- [ ] Cart state includes CGM in JSON
- [ ] API endpoints return CGM field
- [ ] Existing functionality unaffected
- [ ] Unit tests pass for CGM handling
- [ ] Integration tests verify end-to-end flow
## Configuration and Testability
Following project patterns:
- CGM extraction is configurable via field index (currently 35)
- Product fetcher interface allows mocking for tests
- Mutation handlers are pure functions testable in isolation
- Cart state serialization includes CGM for verification
This implementation maintains the project's standards for testability and configurability while adding CGM support to line items.

234
NEW_MUTATIONS_SPEC.md Normal file
View File

@@ -0,0 +1,234 @@
go-cart-actor/NEW_MUTATIONS_SPEC.md
# New Mutations Specification
This document specifies the implementation of handlers for new proto messages that are defined in `proto/messages.proto` but not yet registered in the mutation registry. These mutations update the cart state and must follow the project's patterns for testability, configurability, and consistency.
## Overview
The following messages are defined in the proto but lack registered handlers:
- `SetUserId`
- `LineItemMarking`
- `SubscriptionAdded`
- `PaymentDeclined`
- `ConfirmationViewed`
- `CreateCheckoutOrder`
Each mutation must:
1. Define a handler function with signature `func(*CartGrain, *T) error`
2. Be registered in `NewCartMultationRegistry()` using `actor.NewMutation`
3. Include unit tests
4. Optionally add HTTP/gRPC endpoints if client-invokable
5. Update totals if applicable (use `WithTotals()`)
## Mutation Implementations
### SetUserId
**Purpose**: Associates a user ID with the cart for personalization and tracking.
**Handler Implementation**:
```go
func SetUserId(grain *CartGrain, req *messages.SetUserId) error {
if req.UserId == "" {
return errors.New("user ID cannot be empty")
}
grain.UserId = req.UserId
return nil
}
```
**Registration**:
```go
actor.NewMutation(SetUserId, func() *messages.SetUserId {
return &messages.SetUserId{}
}),
```
**Notes**: This is a simple state update. No totals recalculation needed.
### LineItemMarking
**Purpose**: Adds or updates a marking (e.g., gift message, special instructions) on a specific line item.
**Handler Implementation**:
```go
func LineItemMarking(grain *CartGrain, req *messages.LineItemMarking) error {
for i, item := range grain.Items {
if item.Id == req.Id {
grain.Items[i].Marking = &Marking{
Type: req.Type,
Text: req.Marking,
}
return nil
}
}
return fmt.Errorf("item with ID %d not found", req.Id)
}
```
**Registration**:
```go
actor.NewMutation(LineItemMarking, func() *messages.LineItemMarking {
return &messages.LineItemMarking{}
}),
```
**Notes**: Assumes `CartGrain.Items` has a `Marking` field (single marking per item). If not, add it to the grain struct.
### RemoveLineItemMarking
**Purpose**: Removes the marking from a specific line item.
**Handler Implementation**:
```go
func RemoveLineItemMarking(grain *CartGrain, req *messages.RemoveLineItemMarking) error {
for i, item := range grain.Items {
if item.Id == req.Id {
grain.Items[i].Marking = nil
return nil
}
}
return fmt.Errorf("item with ID %d not found", req.Id)
}
```
**Registration**:
```go
actor.NewMutation(RemoveLineItemMarking, func() *messages.RemoveLineItemMarking {
return &messages.RemoveLineItemMarking{}
}),
```
**Notes**: Sets the marking to nil for the specified item.
### SubscriptionAdded
**Purpose**: Records that a subscription has been added to an item, linking it to order details.
**Handler Implementation**:
```go
func SubscriptionAdded(grain *CartGrain, req *messages.SubscriptionAdded) error {
for i, item := range grain.Items {
if item.Id == req.ItemId {
grain.Items[i].SubscriptionDetailsId = req.DetailsId
grain.Items[i].OrderReference = req.OrderReference
grain.Items[i].IsSubscribed = true
return nil
}
}
return fmt.Errorf("item with ID %d not found", req.ItemId)
}
```
**Registration**:
```go
actor.NewMutation(SubscriptionAdded, func() *messages.SubscriptionAdded {
return &messages.SubscriptionAdded{}
}),
```
**Notes**: Assumes fields like `SubscriptionDetailsId`, `OrderReference`, `IsSubscribed` exist on items. Add to grain if needed.
### PaymentDeclined
**Purpose**: Marks the cart as having a declined payment, potentially updating status or flags.
**Handler Implementation**:
```go
func PaymentDeclined(grain *CartGrain, req *messages.PaymentDeclined) error {
grain.PaymentStatus = "declined"
grain.PaymentDeclinedAt = time.Now()
// Optionally clear checkout order if in progress
if grain.CheckoutOrderId != "" {
grain.CheckoutOrderId = ""
}
return nil
}
```
**Registration**:
```go
actor.NewMutation(PaymentDeclined, func() *messages.PaymentDeclined {
return &messages.PaymentDeclined{}
}),
```
**Notes**: Assumes `PaymentStatus` and `PaymentDeclinedAt` fields. Add timestamps and status tracking to grain.
### ConfirmationViewed
**Purpose**: Records that the order confirmation has been viewed by the user. Applied automatically when the confirmation page is loaded in checkout_server.go.
**Handler Implementation**:
```go
func ConfirmationViewed(grain *CartGrain, req *messages.ConfirmationViewed) error {
grain.ConfirmationViewCount++
grain.ConfirmationLastViewedAt = time.Now()
return nil
}
```
**Registration**:
```go
actor.NewMutation(ConfirmationViewed, func() *messages.ConfirmationViewed {
return &messages.ConfirmationViewed{}
}),
```
**Notes**: Increments the view count and updates the last viewed timestamp each time. Assumes `ConfirmationViewCount` and `ConfirmationLastViewedAt` fields.
### CreateCheckoutOrder
**Purpose**: Initiates the checkout process, validating terms and creating an order reference.
**Handler Implementation**:
```go
func CreateCheckoutOrder(grain *CartGrain, req *messages.CreateCheckoutOrder) error {
if len(grain.Items) == 0 {
return errors.New("cannot checkout empty cart")
}
if req.Terms != "accepted" {
return errors.New("terms must be accepted")
}
// Validate other fields as needed
grain.CheckoutOrderId = generateOrderId()
grain.CheckoutStatus = "pending"
grain.CheckoutCountry = req.Country
return nil
}
```
**Registration**:
```go
actor.NewMutation(CreateCheckoutOrder, func() *messages.CreateCheckoutOrder {
return &messages.CreateCheckoutOrder{}
}).WithTotals(),
```
**Notes**: Use `WithTotals()` to recalculate totals after checkout initiation. Assumes order ID generation function.
## Implementation Steps
For each mutation:
1. **Add Handler Function**: Implement in `pkg/cart/` (e.g., `cart_mutations.go`).
2. **Register in Registry**: Add to `NewCartMultationRegistry()` in `cart-mutation-helper.go`.
3. **Regenerate Proto**: Run `protoc` commands after any proto changes.
4. **Add Tests**: Create unit tests in `pkg/cart/` testing the handler logic.
5. **Add Endpoints** (if needed): For client-invokable mutations, add HTTP handlers in `cmd/cart/pool-server.go`. ConfirmationViewed is handled in `cmd/cart/checkout_server.go` when the confirmation page is viewed.
6. **Update Grain Struct**: Add any new fields to `CartGrain` in `pkg/cart/grain.go`.
7. **Run Tests**: Ensure `go test ./...` passes.
## Testing Guidelines
- Mock dependencies using interfaces.
- Test error cases (e.g., invalid IDs, empty carts).
- Verify state changes and totals recalculation.
- Use table-driven tests for multiple scenarios.
## Configuration and Testability
Follow `MutationRegistry` and `SimpleGrainPool` patterns:
- Use interfaces for external dependencies (e.g., ID generators).
- Inject configurations via constructor parameters.
- Avoid global state; make handlers pure functions where possible.

View File

@@ -137,6 +137,12 @@ func (a *App) HandleCheckoutRequests(amqpUrl string, mux *http.ServeMux, invento
return return
} }
// Apply ConfirmationViewed mutation
cartId, ok := cart.ParseCartId(order.MerchantReference1)
if ok {
a.pool.Apply(r.Context(), uint64(cartId), &messages.ConfirmationViewed{})
}
w.Header().Set("Content-Type", "text/html; charset=utf-8") w.Header().Set("Content-Type", "text/html; charset=utf-8")
if order.Status == "checkout_complete" { if order.Status == "checkout_complete" {
http.SetCookie(w, &http.Cookie{ http.SetCookie(w, &http.Cookie{

View File

@@ -642,6 +642,64 @@ func (s *PoolServer) RemoveVoucherHandler(w http.ResponseWriter, r *http.Request
return nil return nil
} }
func (s *PoolServer) SetUserIdHandler(w http.ResponseWriter, r *http.Request, cartId cart.CartId) error {
setUserId := messages.SetUserId{}
err := json.NewDecoder(r.Body).Decode(&setUserId)
if err != nil {
return err
}
reply, err := s.ApplyLocal(r.Context(), cartId, &setUserId)
if err != nil {
return err
}
return s.WriteResult(w, reply)
}
func (s *PoolServer) LineItemMarkingHandler(w http.ResponseWriter, r *http.Request, cartId cart.CartId) error {
itemIdStr := r.PathValue("itemId")
itemId, err := strconv.ParseInt(itemIdStr, 10, 64)
if err != nil {
return err
}
lineItemMarking := messages.LineItemMarking{Id: uint32(itemId)}
err = json.NewDecoder(r.Body).Decode(&lineItemMarking)
if err != nil {
return err
}
reply, err := s.ApplyLocal(r.Context(), cartId, &lineItemMarking)
if err != nil {
return err
}
return s.WriteResult(w, reply)
}
func (s *PoolServer) RemoveLineItemMarkingHandler(w http.ResponseWriter, r *http.Request, cartId cart.CartId) error {
itemIdStr := r.PathValue("itemId")
itemId, err := strconv.ParseInt(itemIdStr, 10, 64)
if err != nil {
return err
}
removeLineItemMarking := messages.RemoveLineItemMarking{Id: uint32(itemId)}
reply, err := s.ApplyLocal(r.Context(), cartId, &removeLineItemMarking)
if err != nil {
return err
}
return s.WriteResult(w, reply)
}
func (s *PoolServer) CreateCheckoutOrderHandler(w http.ResponseWriter, r *http.Request, cartId cart.CartId) error {
createCheckoutOrder := messages.CreateCheckoutOrder{}
err := json.NewDecoder(r.Body).Decode(&createCheckoutOrder)
if err != nil {
return err
}
reply, err := s.ApplyLocal(r.Context(), cartId, &createCheckoutOrder)
if err != nil {
return err
}
return s.WriteResult(w, reply)
}
func (s *PoolServer) Serve(mux *http.ServeMux) { func (s *PoolServer) Serve(mux *http.ServeMux) {
// mux.HandleFunc("OPTIONS /cart", func(w http.ResponseWriter, r *http.Request) { // mux.HandleFunc("OPTIONS /cart", func(w http.ResponseWriter, r *http.Request) {
@@ -679,6 +737,11 @@ func (s *PoolServer) Serve(mux *http.ServeMux) {
handleFunc("PUT /cart/voucher", CookieCartIdHandler(s.ProxyHandler(s.AddVoucherHandler))) handleFunc("PUT /cart/voucher", CookieCartIdHandler(s.ProxyHandler(s.AddVoucherHandler)))
handleFunc("PUT /cart/subscription-details", CookieCartIdHandler(s.ProxyHandler(s.SubscriptionDetailsHandler))) handleFunc("PUT /cart/subscription-details", CookieCartIdHandler(s.ProxyHandler(s.SubscriptionDetailsHandler)))
handleFunc("DELETE /cart/voucher/{voucherId}", CookieCartIdHandler(s.ProxyHandler(s.RemoveVoucherHandler))) handleFunc("DELETE /cart/voucher/{voucherId}", CookieCartIdHandler(s.ProxyHandler(s.RemoveVoucherHandler)))
handleFunc("PUT /cart/user", CookieCartIdHandler(s.ProxyHandler(s.SetUserIdHandler)))
handleFunc("PUT /cart/item/{itemId}/marking", CookieCartIdHandler(s.ProxyHandler(s.LineItemMarkingHandler)))
handleFunc("DELETE /cart/item/{itemId}/marking", CookieCartIdHandler(s.ProxyHandler(s.RemoveLineItemMarkingHandler)))
handleFunc("POST /cart/checkout-order", CookieCartIdHandler(s.ProxyHandler(s.CreateCheckoutOrderHandler)))
//mux.HandleFunc("GET /cart/checkout", CookieCartIdHandler(s.ProxyHandler(s.HandleCheckout))) //mux.HandleFunc("GET /cart/checkout", CookieCartIdHandler(s.ProxyHandler(s.HandleCheckout)))
//mux.HandleFunc("GET /cart/confirmation/{orderId}", CookieCartIdHandler(s.ProxyHandler(s.HandleConfirmation))) //mux.HandleFunc("GET /cart/confirmation/{orderId}", CookieCartIdHandler(s.ProxyHandler(s.HandleConfirmation)))
@@ -693,6 +756,11 @@ func (s *PoolServer) Serve(mux *http.ServeMux) {
handleFunc("PUT /cart/byid/{id}/delivery/{deliveryId}/pickupPoint", CartIdHandler(s.ProxyHandler(s.SetPickupPointHandler))) handleFunc("PUT /cart/byid/{id}/delivery/{deliveryId}/pickupPoint", CartIdHandler(s.ProxyHandler(s.SetPickupPointHandler)))
handleFunc("PUT /cart/byid/{id}/voucher", CookieCartIdHandler(s.ProxyHandler(s.AddVoucherHandler))) handleFunc("PUT /cart/byid/{id}/voucher", CookieCartIdHandler(s.ProxyHandler(s.AddVoucherHandler)))
handleFunc("DELETE /cart/byid/{id}/voucher/{voucherId}", CookieCartIdHandler(s.ProxyHandler(s.RemoveVoucherHandler))) handleFunc("DELETE /cart/byid/{id}/voucher/{voucherId}", CookieCartIdHandler(s.ProxyHandler(s.RemoveVoucherHandler)))
handleFunc("PUT /cart/byid/{id}/user", CartIdHandler(s.ProxyHandler(s.SetUserIdHandler)))
handleFunc("PUT /cart/byid/{id}/item/{itemId}/marking", CartIdHandler(s.ProxyHandler(s.LineItemMarkingHandler)))
handleFunc("DELETE /cart/byid/{id}/item/{itemId}/marking", CartIdHandler(s.ProxyHandler(s.RemoveLineItemMarkingHandler)))
handleFunc("POST /cart/byid/{id}/checkout-order", CartIdHandler(s.ProxyHandler(s.CreateCheckoutOrderHandler)))
//mux.HandleFunc("GET /cart/byid/{id}/checkout", CartIdHandler(s.ProxyHandler(s.HandleCheckout))) //mux.HandleFunc("GET /cart/byid/{id}/checkout", CartIdHandler(s.ProxyHandler(s.HandleCheckout)))
//mux.HandleFunc("GET /cart/byid/{id}/confirmation", CartIdHandler(s.ProxyHandler(s.HandleConfirmation))) //mux.HandleFunc("GET /cart/byid/{id}/confirmation", CartIdHandler(s.ProxyHandler(s.HandleConfirmation)))

View File

@@ -102,6 +102,8 @@ func ToItemAddMessage(item *index.DataItem, storeId *string, qty int, country st
category4, _ := item.GetStringFieldValue(13) //Fields[13].(string) category4, _ := item.GetStringFieldValue(13) //Fields[13].(string)
category5, _ := item.GetStringFieldValue(14) //.Fields[14].(string) category5, _ := item.GetStringFieldValue(14) //.Fields[14].(string)
cgm, _ := item.GetStringFieldValue(35) // Customer Group Membership
return &messages.AddItem{ return &messages.AddItem{
ItemId: uint32(item.Id), ItemId: uint32(item.Id),
Quantity: int32(qty), Quantity: int32(qty),
@@ -126,6 +128,7 @@ func ToItemAddMessage(item *index.DataItem, storeId *string, qty int, country st
Outlet: outlet, Outlet: outlet,
StoreId: storeId, StoreId: storeId,
SaleStatus: item.SaleStatus, SaleStatus: item.SaleStatus,
Cgm: cgm,
}, nil }, nil
} }

View File

@@ -29,6 +29,7 @@ type ItemMeta struct {
SellerName string `json:"sellerName,omitempty"` SellerName string `json:"sellerName,omitempty"`
Image string `json:"image,omitempty"` Image string `json:"image,omitempty"`
Outlet *string `json:"outlet,omitempty"` Outlet *string `json:"outlet,omitempty"`
Cgm string `json:"cgm,omitempty"` // Customer Group Membership
} }
type CartItem struct { type CartItem struct {
@@ -48,6 +49,10 @@ type CartItem struct {
StoreId *string `json:"storeId,omitempty"` StoreId *string `json:"storeId,omitempty"`
Meta *ItemMeta `json:"meta,omitempty"` Meta *ItemMeta `json:"meta,omitempty"`
SaleStatus string `json:"saleStatus"` SaleStatus string `json:"saleStatus"`
Marking *Marking `json:"marking,omitempty"`
SubscriptionDetailsId string `json:"subscriptionDetailsId,omitempty"`
OrderReference string `json:"orderReference,omitempty"`
IsSubscribed bool `json:"isSubscribed,omitempty"`
} }
type CartDelivery struct { type CartDelivery struct {
@@ -73,6 +78,11 @@ type SubscriptionDetails struct {
Meta json.RawMessage `json:"data,omitempty"` Meta json.RawMessage `json:"data,omitempty"`
} }
type Marking struct {
Type uint32 `json:"type"`
Text string `json:"text"`
}
type CartGrain struct { type CartGrain struct {
mu sync.RWMutex mu sync.RWMutex
lastItemId uint32 lastItemId uint32
@@ -94,6 +104,12 @@ type CartGrain struct {
Vouchers []*Voucher `json:"vouchers,omitempty"` Vouchers []*Voucher `json:"vouchers,omitempty"`
Notifications []CartNotification `json:"cartNotification,omitempty"` Notifications []CartNotification `json:"cartNotification,omitempty"`
SubscriptionDetails map[string]*SubscriptionDetails `json:"subscriptionDetails,omitempty"` SubscriptionDetails map[string]*SubscriptionDetails `json:"subscriptionDetails,omitempty"`
PaymentDeclinedAt time.Time `json:"paymentDeclinedAt,omitempty"`
ConfirmationViewCount int `json:"confirmationViewCount,omitempty"`
ConfirmationLastViewedAt time.Time `json:"confirmationLastViewedAt,omitempty"`
CheckoutOrderId string `json:"checkoutOrderId,omitempty"`
CheckoutStatus string `json:"checkoutStatus,omitempty"`
CheckoutCountry string `json:"checkoutCountry,omitempty"`
} }
type Voucher struct { type Voucher struct {

View File

@@ -51,6 +51,27 @@ func NewCartMultationRegistry() actor.MutationRegistry {
actor.NewMutation(PreConditionFailed, func() *messages.PreConditionFailed { actor.NewMutation(PreConditionFailed, func() *messages.PreConditionFailed {
return &messages.PreConditionFailed{} return &messages.PreConditionFailed{}
}), }),
actor.NewMutation(SetUserId, func() *messages.SetUserId {
return &messages.SetUserId{}
}),
actor.NewMutation(LineItemMarking, func() *messages.LineItemMarking {
return &messages.LineItemMarking{}
}),
actor.NewMutation(RemoveLineItemMarking, func() *messages.RemoveLineItemMarking {
return &messages.RemoveLineItemMarking{}
}),
actor.NewMutation(SubscriptionAdded, func() *messages.SubscriptionAdded {
return &messages.SubscriptionAdded{}
}),
actor.NewMutation(PaymentDeclined, func() *messages.PaymentDeclined {
return &messages.PaymentDeclined{}
}),
actor.NewMutation(ConfirmationViewed, func() *messages.ConfirmationViewed {
return &messages.ConfirmationViewed{}
}),
actor.NewMutation(CreateCheckoutOrder, func() *messages.CreateCheckoutOrder {
return &messages.CreateCheckoutOrder{}
}),
) )
return reg return reg

View File

@@ -76,6 +76,7 @@ func AddItem(g *CartGrain, m *messages.AddItem) error {
Outlet: m.Outlet, Outlet: m.Outlet,
SellerId: m.SellerId, SellerId: m.SellerId,
SellerName: m.SellerName, SellerName: m.SellerName,
Cgm: m.Cgm,
}, },
SaleStatus: m.SaleStatus, SaleStatus: m.SaleStatus,
ParentId: m.ParentId, ParentId: m.ParentId,

View File

@@ -0,0 +1,13 @@
package cart
import (
"time"
messages "git.tornberg.me/go-cart-actor/pkg/messages"
)
func ConfirmationViewed(grain *CartGrain, req *messages.ConfirmationViewed) error {
grain.ConfirmationViewCount++
grain.ConfirmationLastViewedAt = time.Now()
return nil
}

View File

@@ -0,0 +1,21 @@
package cart
import (
"errors"
"github.com/google/uuid"
messages "git.tornberg.me/go-cart-actor/pkg/messages"
)
func CreateCheckoutOrder(grain *CartGrain, req *messages.CreateCheckoutOrder) error {
if len(grain.Items) == 0 {
return errors.New("cannot checkout empty cart")
}
if req.Terms != "accepted" {
return errors.New("terms must be accepted")
}
// Validate other fields as needed
grain.CheckoutOrderId = uuid.New().String()
grain.CheckoutStatus = "pending"
grain.CheckoutCountry = req.Country
return nil
}

View File

@@ -0,0 +1,20 @@
package cart
import (
"fmt"
messages "git.tornberg.me/go-cart-actor/pkg/messages"
)
func LineItemMarking(grain *CartGrain, req *messages.LineItemMarking) error {
for i, item := range grain.Items {
if item.Id == req.Id {
grain.Items[i].Marking = &Marking{
Type: req.Type,
Text: req.Marking,
}
return nil
}
}
return fmt.Errorf("item with ID %d not found", req.Id)
}

View File

@@ -0,0 +1,16 @@
package cart
import (
"time"
messages "git.tornberg.me/go-cart-actor/pkg/messages"
)
func PaymentDeclined(grain *CartGrain, req *messages.PaymentDeclined) error {
grain.PaymentStatus = "declined"
grain.PaymentDeclinedAt = time.Now()
// Optionally clear checkout order if in progress
if grain.CheckoutOrderId != "" {
grain.CheckoutOrderId = ""
}
return nil
}

View File

@@ -0,0 +1,16 @@
package cart
import (
"fmt"
messages "git.tornberg.me/go-cart-actor/pkg/messages"
)
func RemoveLineItemMarking(grain *CartGrain, req *messages.RemoveLineItemMarking) error {
for i, item := range grain.Items {
if item.Id == req.Id {
grain.Items[i].Marking = nil
return nil
}
}
return fmt.Errorf("item with ID %d not found", req.Id)
}

View File

@@ -0,0 +1,14 @@
package cart
import (
"errors"
messages "git.tornberg.me/go-cart-actor/pkg/messages"
)
func SetUserId(grain *CartGrain, req *messages.SetUserId) error {
if req.UserId == "" {
return errors.New("user ID cannot be empty")
}
grain.userId = req.UserId
return nil
}

View File

@@ -0,0 +1,18 @@
package cart
import (
"fmt"
messages "git.tornberg.me/go-cart-actor/pkg/messages"
)
func SubscriptionAdded(grain *CartGrain, req *messages.SubscriptionAdded) error {
for i, item := range grain.Items {
if item.Id == req.ItemId {
grain.Items[i].SubscriptionDetailsId = req.DetailsId
grain.Items[i].OrderReference = req.OrderReference
grain.Items[i].IsSubscribed = true
return nil
}
}
return fmt.Errorf("item with ID %d not found", req.ItemId)
}

View File

@@ -85,6 +85,34 @@ func msgOrderCreated(orderId, status string) *messages.OrderCreated {
return &messages.OrderCreated{OrderId: orderId, Status: status} return &messages.OrderCreated{OrderId: orderId, Status: status}
} }
func msgSetUserId(userId string) *messages.SetUserId {
return &messages.SetUserId{UserId: userId}
}
func msgLineItemMarking(id uint32, typ uint32, marking string) *messages.LineItemMarking {
return &messages.LineItemMarking{Id: id, Type: typ, Marking: marking}
}
func msgRemoveLineItemMarking(id uint32) *messages.RemoveLineItemMarking {
return &messages.RemoveLineItemMarking{Id: id}
}
func msgSubscriptionAdded(itemId uint32, detailsId, orderRef string) *messages.SubscriptionAdded {
return &messages.SubscriptionAdded{ItemId: itemId, DetailsId: detailsId, OrderReference: orderRef}
}
func msgPaymentDeclined() *messages.PaymentDeclined {
return &messages.PaymentDeclined{}
}
func msgConfirmationViewed() *messages.ConfirmationViewed {
return &messages.ConfirmationViewed{}
}
func msgCreateCheckoutOrder(terms, country string) *messages.CreateCheckoutOrder {
return &messages.CreateCheckoutOrder{Terms: terms, Country: country}
}
func ptr[T any](v T) *T { return &v } func ptr[T any](v T) *T { return &v }
// ---------------------- // ----------------------
@@ -144,6 +172,15 @@ func TestMutationRegistryCoverage(t *testing.T) {
"AddVoucher", "AddVoucher",
"RemoveVoucher", "RemoveVoucher",
"UpsertSubscriptionDetails", "UpsertSubscriptionDetails",
"InventoryReserved",
"PreConditionFailed",
"SetUserId",
"LineItemMarking",
"RemoveLineItemMarking",
"SubscriptionAdded",
"PaymentDeclined",
"ConfirmationViewed",
"CreateCheckoutOrder",
} }
names := reg.(*actor.ProtoMutationRegistry).RegisteredMutations() names := reg.(*actor.ProtoMutationRegistry).RegisteredMutations()
@@ -542,3 +579,134 @@ func TestSubscriptionDetailsJSONValidation(t *testing.T) {
t.Fatalf("empty update should not change meta, got %s", string(g.SubscriptionDetails[id].Meta)) t.Fatalf("empty update should not change meta, got %s", string(g.SubscriptionDetails[id].Meta))
} }
} }
func TestSetUserId(t *testing.T) {
reg := newRegistry()
g := newTestGrain()
applyOK(t, reg, g, msgSetUserId("user123"))
if g.userId != "user123" {
t.Fatalf("expected userId=user123, got %s", g.userId)
}
applyErrorContains(t, reg, g, msgSetUserId(""), "cannot be empty")
}
func TestLineItemMarking(t *testing.T) {
reg := newRegistry()
g := newTestGrain()
applyOK(t, reg, g, msgAddItem("MARK", 1000, 1, nil))
id := g.Items[0].Id
applyOK(t, reg, g, msgLineItemMarking(id, 1, "Gift message"))
if g.Items[0].Marking == nil || g.Items[0].Marking.Type != 1 || g.Items[0].Marking.Text != "Gift message" {
t.Fatalf("marking not set correctly: %+v", g.Items[0].Marking)
}
applyErrorContains(t, reg, g, msgLineItemMarking(9999, 2, "Test"), "not found")
}
func TestRemoveLineItemMarking(t *testing.T) {
reg := newRegistry()
g := newTestGrain()
applyOK(t, reg, g, msgAddItem("REMOVE", 1000, 1, nil))
id := g.Items[0].Id
// First set a marking
applyOK(t, reg, g, msgLineItemMarking(id, 1, "Test marking"))
if g.Items[0].Marking == nil || g.Items[0].Marking.Text != "Test marking" {
t.Fatalf("marking not set")
}
// Now remove it
applyOK(t, reg, g, msgRemoveLineItemMarking(id))
if g.Items[0].Marking != nil {
t.Fatalf("marking not removed")
}
applyErrorContains(t, reg, g, msgRemoveLineItemMarking(9999), "not found")
}
func TestSubscriptionAdded(t *testing.T) {
reg := newRegistry()
g := newTestGrain()
applyOK(t, reg, g, msgAddItem("SUB", 1000, 1, nil))
id := g.Items[0].Id
applyOK(t, reg, g, msgSubscriptionAdded(id, "det123", "ord456"))
if g.Items[0].SubscriptionDetailsId != "det123" || g.Items[0].OrderReference != "ord456" || !g.Items[0].IsSubscribed {
t.Fatalf("subscription not added: detailsId=%s orderRef=%s isSubscribed=%v",
g.Items[0].SubscriptionDetailsId, g.Items[0].OrderReference, g.Items[0].IsSubscribed)
}
applyErrorContains(t, reg, g, msgSubscriptionAdded(9999, "", ""), "not found")
}
func TestPaymentDeclined(t *testing.T) {
reg := newRegistry()
g := newTestGrain()
g.CheckoutOrderId = "test-order"
applyOK(t, reg, g, msgPaymentDeclined())
if g.PaymentStatus != "declined" || g.CheckoutOrderId != "" {
t.Fatalf("payment declined not handled: status=%s checkoutId=%s", g.PaymentStatus, g.CheckoutOrderId)
}
if g.PaymentDeclinedAt.IsZero() {
t.Fatalf("PaymentDeclinedAt not set")
}
}
func TestConfirmationViewed(t *testing.T) {
reg := newRegistry()
g := newTestGrain()
// Initial state
if g.ConfirmationViewCount != 0 {
t.Fatalf("initial view count should be 0, got %d", g.ConfirmationViewCount)
}
if !g.ConfirmationLastViewedAt.IsZero() {
t.Fatalf("initial last viewed should be zero")
}
// First view
applyOK(t, reg, g, msgConfirmationViewed())
if g.ConfirmationViewCount != 1 {
t.Fatalf("view count should be 1, got %d", g.ConfirmationViewCount)
}
if g.ConfirmationLastViewedAt.IsZero() {
t.Fatalf("ConfirmationLastViewedAt not set")
}
firstTime := g.ConfirmationLastViewedAt
// Second view
applyOK(t, reg, g, msgConfirmationViewed())
if g.ConfirmationViewCount != 2 {
t.Fatalf("view count should be 2, got %d", g.ConfirmationViewCount)
}
if g.ConfirmationLastViewedAt == firstTime {
t.Fatalf("ConfirmationLastViewedAt should have updated")
}
}
func TestCreateCheckoutOrder(t *testing.T) {
reg := newRegistry()
g := newTestGrain()
applyOK(t, reg, g, msgAddItem("CHECKOUT", 1000, 1, nil))
applyOK(t, reg, g, msgCreateCheckoutOrder("accepted", "SE"))
if g.CheckoutOrderId == "" || g.CheckoutStatus != "pending" || g.CheckoutCountry != "SE" {
t.Fatalf("checkout order not created: id=%s status=%s country=%s",
g.CheckoutOrderId, g.CheckoutStatus, g.CheckoutCountry)
}
// Empty cart
g2 := newTestGrain()
applyErrorContains(t, reg, g2, msgCreateCheckoutOrder("accepted", ""), "empty cart")
// Terms not accepted
applyErrorContains(t, reg, g, msgCreateCheckoutOrder("no", ""), "terms must be accepted")
}

View File

@@ -39,12 +39,7 @@ func UpsertSubscriptionDetails(g *CartGrain, m *messages.UpsertSubscriptionDetai
// Update existing entry. // Update existing entry.
existing, ok := g.SubscriptionDetails[*m.Id] existing, ok := g.SubscriptionDetails[*m.Id]
if !ok { if !ok {
n := &SubscriptionDetails{ return fmt.Errorf("subscription details with id %s not found", *m.Id)
Id: *m.Id,
Version: 0,
}
g.SubscriptionDetails[*m.Id] = n
existing = n
} }
changed := false changed := false
if m.OfferingCode != "" { if m.OfferingCode != "" {

View File

@@ -84,6 +84,7 @@ type AddItem struct {
Outlet *string `protobuf:"bytes,12,opt,name=outlet,proto3,oneof" json:"outlet,omitempty"` Outlet *string `protobuf:"bytes,12,opt,name=outlet,proto3,oneof" json:"outlet,omitempty"`
StoreId *string `protobuf:"bytes,22,opt,name=storeId,proto3,oneof" json:"storeId,omitempty"` StoreId *string `protobuf:"bytes,22,opt,name=storeId,proto3,oneof" json:"storeId,omitempty"`
ParentId *uint32 `protobuf:"varint,23,opt,name=parentId,proto3,oneof" json:"parentId,omitempty"` ParentId *uint32 `protobuf:"varint,23,opt,name=parentId,proto3,oneof" json:"parentId,omitempty"`
Cgm string `protobuf:"bytes,25,opt,name=cgm,proto3" json:"cgm,omitempty"`
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
} }
@@ -286,6 +287,13 @@ func (x *AddItem) GetParentId() uint32 {
return 0 return 0
} }
func (x *AddItem) GetCgm() string {
if x != nil {
return x.Cgm
}
return ""
}
type RemoveItem struct { type RemoveItem struct {
state protoimpl.MessageState `protogen:"open.v1"` state protoimpl.MessageState `protogen:"open.v1"`
Id uint32 `protobuf:"varint,1,opt,name=Id,proto3" json:"Id,omitempty"` Id uint32 `protobuf:"varint,1,opt,name=Id,proto3" json:"Id,omitempty"`
@@ -694,6 +702,286 @@ func (x *RemoveDelivery) GetId() uint32 {
return 0 return 0
} }
type SetUserId struct {
state protoimpl.MessageState `protogen:"open.v1"`
UserId string `protobuf:"bytes,1,opt,name=userId,proto3" json:"userId,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *SetUserId) Reset() {
*x = SetUserId{}
mi := &file_messages_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *SetUserId) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SetUserId) ProtoMessage() {}
func (x *SetUserId) ProtoReflect() protoreflect.Message {
mi := &file_messages_proto_msgTypes[8]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SetUserId.ProtoReflect.Descriptor instead.
func (*SetUserId) Descriptor() ([]byte, []int) {
return file_messages_proto_rawDescGZIP(), []int{8}
}
func (x *SetUserId) GetUserId() string {
if x != nil {
return x.UserId
}
return ""
}
type LineItemMarking struct {
state protoimpl.MessageState `protogen:"open.v1"`
Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
Type uint32 `protobuf:"varint,2,opt,name=type,proto3" json:"type,omitempty"`
Marking string `protobuf:"bytes,3,opt,name=marking,proto3" json:"marking,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *LineItemMarking) Reset() {
*x = LineItemMarking{}
mi := &file_messages_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *LineItemMarking) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*LineItemMarking) ProtoMessage() {}
func (x *LineItemMarking) ProtoReflect() protoreflect.Message {
mi := &file_messages_proto_msgTypes[9]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use LineItemMarking.ProtoReflect.Descriptor instead.
func (*LineItemMarking) Descriptor() ([]byte, []int) {
return file_messages_proto_rawDescGZIP(), []int{9}
}
func (x *LineItemMarking) GetId() uint32 {
if x != nil {
return x.Id
}
return 0
}
func (x *LineItemMarking) GetType() uint32 {
if x != nil {
return x.Type
}
return 0
}
func (x *LineItemMarking) GetMarking() string {
if x != nil {
return x.Marking
}
return ""
}
type RemoveLineItemMarking struct {
state protoimpl.MessageState `protogen:"open.v1"`
Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *RemoveLineItemMarking) Reset() {
*x = RemoveLineItemMarking{}
mi := &file_messages_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *RemoveLineItemMarking) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RemoveLineItemMarking) ProtoMessage() {}
func (x *RemoveLineItemMarking) ProtoReflect() protoreflect.Message {
mi := &file_messages_proto_msgTypes[10]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RemoveLineItemMarking.ProtoReflect.Descriptor instead.
func (*RemoveLineItemMarking) Descriptor() ([]byte, []int) {
return file_messages_proto_rawDescGZIP(), []int{10}
}
func (x *RemoveLineItemMarking) GetId() uint32 {
if x != nil {
return x.Id
}
return 0
}
type SubscriptionAdded struct {
state protoimpl.MessageState `protogen:"open.v1"`
ItemId uint32 `protobuf:"varint,1,opt,name=itemId,proto3" json:"itemId,omitempty"`
DetailsId string `protobuf:"bytes,3,opt,name=detailsId,proto3" json:"detailsId,omitempty"`
OrderReference string `protobuf:"bytes,4,opt,name=orderReference,proto3" json:"orderReference,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *SubscriptionAdded) Reset() {
*x = SubscriptionAdded{}
mi := &file_messages_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *SubscriptionAdded) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SubscriptionAdded) ProtoMessage() {}
func (x *SubscriptionAdded) ProtoReflect() protoreflect.Message {
mi := &file_messages_proto_msgTypes[11]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SubscriptionAdded.ProtoReflect.Descriptor instead.
func (*SubscriptionAdded) Descriptor() ([]byte, []int) {
return file_messages_proto_rawDescGZIP(), []int{11}
}
func (x *SubscriptionAdded) GetItemId() uint32 {
if x != nil {
return x.ItemId
}
return 0
}
func (x *SubscriptionAdded) GetDetailsId() string {
if x != nil {
return x.DetailsId
}
return ""
}
func (x *SubscriptionAdded) GetOrderReference() string {
if x != nil {
return x.OrderReference
}
return ""
}
type PaymentDeclined struct {
state protoimpl.MessageState `protogen:"open.v1"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *PaymentDeclined) Reset() {
*x = PaymentDeclined{}
mi := &file_messages_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *PaymentDeclined) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*PaymentDeclined) ProtoMessage() {}
func (x *PaymentDeclined) ProtoReflect() protoreflect.Message {
mi := &file_messages_proto_msgTypes[12]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use PaymentDeclined.ProtoReflect.Descriptor instead.
func (*PaymentDeclined) Descriptor() ([]byte, []int) {
return file_messages_proto_rawDescGZIP(), []int{12}
}
type ConfirmationViewed struct {
state protoimpl.MessageState `protogen:"open.v1"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ConfirmationViewed) Reset() {
*x = ConfirmationViewed{}
mi := &file_messages_proto_msgTypes[13]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *ConfirmationViewed) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ConfirmationViewed) ProtoMessage() {}
func (x *ConfirmationViewed) ProtoReflect() protoreflect.Message {
mi := &file_messages_proto_msgTypes[13]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ConfirmationViewed.ProtoReflect.Descriptor instead.
func (*ConfirmationViewed) Descriptor() ([]byte, []int) {
return file_messages_proto_rawDescGZIP(), []int{13}
}
type CreateCheckoutOrder struct { type CreateCheckoutOrder struct {
state protoimpl.MessageState `protogen:"open.v1"` state protoimpl.MessageState `protogen:"open.v1"`
Terms string `protobuf:"bytes,1,opt,name=terms,proto3" json:"terms,omitempty"` Terms string `protobuf:"bytes,1,opt,name=terms,proto3" json:"terms,omitempty"`
@@ -708,7 +996,7 @@ type CreateCheckoutOrder struct {
func (x *CreateCheckoutOrder) Reset() { func (x *CreateCheckoutOrder) Reset() {
*x = CreateCheckoutOrder{} *x = CreateCheckoutOrder{}
mi := &file_messages_proto_msgTypes[8] mi := &file_messages_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -720,7 +1008,7 @@ func (x *CreateCheckoutOrder) String() string {
func (*CreateCheckoutOrder) ProtoMessage() {} func (*CreateCheckoutOrder) ProtoMessage() {}
func (x *CreateCheckoutOrder) ProtoReflect() protoreflect.Message { func (x *CreateCheckoutOrder) ProtoReflect() protoreflect.Message {
mi := &file_messages_proto_msgTypes[8] mi := &file_messages_proto_msgTypes[14]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -733,7 +1021,7 @@ func (x *CreateCheckoutOrder) ProtoReflect() protoreflect.Message {
// Deprecated: Use CreateCheckoutOrder.ProtoReflect.Descriptor instead. // Deprecated: Use CreateCheckoutOrder.ProtoReflect.Descriptor instead.
func (*CreateCheckoutOrder) Descriptor() ([]byte, []int) { func (*CreateCheckoutOrder) Descriptor() ([]byte, []int) {
return file_messages_proto_rawDescGZIP(), []int{8} return file_messages_proto_rawDescGZIP(), []int{14}
} }
func (x *CreateCheckoutOrder) GetTerms() string { func (x *CreateCheckoutOrder) GetTerms() string {
@@ -788,7 +1076,7 @@ type OrderCreated struct {
func (x *OrderCreated) Reset() { func (x *OrderCreated) Reset() {
*x = OrderCreated{} *x = OrderCreated{}
mi := &file_messages_proto_msgTypes[9] mi := &file_messages_proto_msgTypes[15]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -800,7 +1088,7 @@ func (x *OrderCreated) String() string {
func (*OrderCreated) ProtoMessage() {} func (*OrderCreated) ProtoMessage() {}
func (x *OrderCreated) ProtoReflect() protoreflect.Message { func (x *OrderCreated) ProtoReflect() protoreflect.Message {
mi := &file_messages_proto_msgTypes[9] mi := &file_messages_proto_msgTypes[15]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -813,7 +1101,7 @@ func (x *OrderCreated) ProtoReflect() protoreflect.Message {
// Deprecated: Use OrderCreated.ProtoReflect.Descriptor instead. // Deprecated: Use OrderCreated.ProtoReflect.Descriptor instead.
func (*OrderCreated) Descriptor() ([]byte, []int) { func (*OrderCreated) Descriptor() ([]byte, []int) {
return file_messages_proto_rawDescGZIP(), []int{9} return file_messages_proto_rawDescGZIP(), []int{15}
} }
func (x *OrderCreated) GetOrderId() string { func (x *OrderCreated) GetOrderId() string {
@@ -838,7 +1126,7 @@ type Noop struct {
func (x *Noop) Reset() { func (x *Noop) Reset() {
*x = Noop{} *x = Noop{}
mi := &file_messages_proto_msgTypes[10] mi := &file_messages_proto_msgTypes[16]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -850,7 +1138,7 @@ func (x *Noop) String() string {
func (*Noop) ProtoMessage() {} func (*Noop) ProtoMessage() {}
func (x *Noop) ProtoReflect() protoreflect.Message { func (x *Noop) ProtoReflect() protoreflect.Message {
mi := &file_messages_proto_msgTypes[10] mi := &file_messages_proto_msgTypes[16]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -863,7 +1151,7 @@ func (x *Noop) ProtoReflect() protoreflect.Message {
// Deprecated: Use Noop.ProtoReflect.Descriptor instead. // Deprecated: Use Noop.ProtoReflect.Descriptor instead.
func (*Noop) Descriptor() ([]byte, []int) { func (*Noop) Descriptor() ([]byte, []int) {
return file_messages_proto_rawDescGZIP(), []int{10} return file_messages_proto_rawDescGZIP(), []int{16}
} }
type InitializeCheckout struct { type InitializeCheckout struct {
@@ -877,7 +1165,7 @@ type InitializeCheckout struct {
func (x *InitializeCheckout) Reset() { func (x *InitializeCheckout) Reset() {
*x = InitializeCheckout{} *x = InitializeCheckout{}
mi := &file_messages_proto_msgTypes[11] mi := &file_messages_proto_msgTypes[17]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -889,7 +1177,7 @@ func (x *InitializeCheckout) String() string {
func (*InitializeCheckout) ProtoMessage() {} func (*InitializeCheckout) ProtoMessage() {}
func (x *InitializeCheckout) ProtoReflect() protoreflect.Message { func (x *InitializeCheckout) ProtoReflect() protoreflect.Message {
mi := &file_messages_proto_msgTypes[11] mi := &file_messages_proto_msgTypes[17]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -902,7 +1190,7 @@ func (x *InitializeCheckout) ProtoReflect() protoreflect.Message {
// Deprecated: Use InitializeCheckout.ProtoReflect.Descriptor instead. // Deprecated: Use InitializeCheckout.ProtoReflect.Descriptor instead.
func (*InitializeCheckout) Descriptor() ([]byte, []int) { func (*InitializeCheckout) Descriptor() ([]byte, []int) {
return file_messages_proto_rawDescGZIP(), []int{11} return file_messages_proto_rawDescGZIP(), []int{17}
} }
func (x *InitializeCheckout) GetOrderId() string { func (x *InitializeCheckout) GetOrderId() string {
@@ -937,7 +1225,7 @@ type InventoryReserved struct {
func (x *InventoryReserved) Reset() { func (x *InventoryReserved) Reset() {
*x = InventoryReserved{} *x = InventoryReserved{}
mi := &file_messages_proto_msgTypes[12] mi := &file_messages_proto_msgTypes[18]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -949,7 +1237,7 @@ func (x *InventoryReserved) String() string {
func (*InventoryReserved) ProtoMessage() {} func (*InventoryReserved) ProtoMessage() {}
func (x *InventoryReserved) ProtoReflect() protoreflect.Message { func (x *InventoryReserved) ProtoReflect() protoreflect.Message {
mi := &file_messages_proto_msgTypes[12] mi := &file_messages_proto_msgTypes[18]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -962,7 +1250,7 @@ func (x *InventoryReserved) ProtoReflect() protoreflect.Message {
// Deprecated: Use InventoryReserved.ProtoReflect.Descriptor instead. // Deprecated: Use InventoryReserved.ProtoReflect.Descriptor instead.
func (*InventoryReserved) Descriptor() ([]byte, []int) { func (*InventoryReserved) Descriptor() ([]byte, []int) {
return file_messages_proto_rawDescGZIP(), []int{12} return file_messages_proto_rawDescGZIP(), []int{18}
} }
func (x *InventoryReserved) GetId() string { func (x *InventoryReserved) GetId() string {
@@ -998,7 +1286,7 @@ type AddVoucher struct {
func (x *AddVoucher) Reset() { func (x *AddVoucher) Reset() {
*x = AddVoucher{} *x = AddVoucher{}
mi := &file_messages_proto_msgTypes[13] mi := &file_messages_proto_msgTypes[19]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -1010,7 +1298,7 @@ func (x *AddVoucher) String() string {
func (*AddVoucher) ProtoMessage() {} func (*AddVoucher) ProtoMessage() {}
func (x *AddVoucher) ProtoReflect() protoreflect.Message { func (x *AddVoucher) ProtoReflect() protoreflect.Message {
mi := &file_messages_proto_msgTypes[13] mi := &file_messages_proto_msgTypes[19]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -1023,7 +1311,7 @@ func (x *AddVoucher) ProtoReflect() protoreflect.Message {
// Deprecated: Use AddVoucher.ProtoReflect.Descriptor instead. // Deprecated: Use AddVoucher.ProtoReflect.Descriptor instead.
func (*AddVoucher) Descriptor() ([]byte, []int) { func (*AddVoucher) Descriptor() ([]byte, []int) {
return file_messages_proto_rawDescGZIP(), []int{13} return file_messages_proto_rawDescGZIP(), []int{19}
} }
func (x *AddVoucher) GetCode() string { func (x *AddVoucher) GetCode() string {
@@ -1063,7 +1351,7 @@ type RemoveVoucher struct {
func (x *RemoveVoucher) Reset() { func (x *RemoveVoucher) Reset() {
*x = RemoveVoucher{} *x = RemoveVoucher{}
mi := &file_messages_proto_msgTypes[14] mi := &file_messages_proto_msgTypes[20]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -1075,7 +1363,7 @@ func (x *RemoveVoucher) String() string {
func (*RemoveVoucher) ProtoMessage() {} func (*RemoveVoucher) ProtoMessage() {}
func (x *RemoveVoucher) ProtoReflect() protoreflect.Message { func (x *RemoveVoucher) ProtoReflect() protoreflect.Message {
mi := &file_messages_proto_msgTypes[14] mi := &file_messages_proto_msgTypes[20]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -1088,7 +1376,7 @@ func (x *RemoveVoucher) ProtoReflect() protoreflect.Message {
// Deprecated: Use RemoveVoucher.ProtoReflect.Descriptor instead. // Deprecated: Use RemoveVoucher.ProtoReflect.Descriptor instead.
func (*RemoveVoucher) Descriptor() ([]byte, []int) { func (*RemoveVoucher) Descriptor() ([]byte, []int) {
return file_messages_proto_rawDescGZIP(), []int{14} return file_messages_proto_rawDescGZIP(), []int{20}
} }
func (x *RemoveVoucher) GetId() uint32 { func (x *RemoveVoucher) GetId() uint32 {
@@ -1110,7 +1398,7 @@ type UpsertSubscriptionDetails struct {
func (x *UpsertSubscriptionDetails) Reset() { func (x *UpsertSubscriptionDetails) Reset() {
*x = UpsertSubscriptionDetails{} *x = UpsertSubscriptionDetails{}
mi := &file_messages_proto_msgTypes[15] mi := &file_messages_proto_msgTypes[21]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -1122,7 +1410,7 @@ func (x *UpsertSubscriptionDetails) String() string {
func (*UpsertSubscriptionDetails) ProtoMessage() {} func (*UpsertSubscriptionDetails) ProtoMessage() {}
func (x *UpsertSubscriptionDetails) ProtoReflect() protoreflect.Message { func (x *UpsertSubscriptionDetails) ProtoReflect() protoreflect.Message {
mi := &file_messages_proto_msgTypes[15] mi := &file_messages_proto_msgTypes[21]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -1135,7 +1423,7 @@ func (x *UpsertSubscriptionDetails) ProtoReflect() protoreflect.Message {
// Deprecated: Use UpsertSubscriptionDetails.ProtoReflect.Descriptor instead. // Deprecated: Use UpsertSubscriptionDetails.ProtoReflect.Descriptor instead.
func (*UpsertSubscriptionDetails) Descriptor() ([]byte, []int) { func (*UpsertSubscriptionDetails) Descriptor() ([]byte, []int) {
return file_messages_proto_rawDescGZIP(), []int{15} return file_messages_proto_rawDescGZIP(), []int{21}
} }
func (x *UpsertSubscriptionDetails) GetId() string { func (x *UpsertSubscriptionDetails) GetId() string {
@@ -1177,7 +1465,7 @@ type PreConditionFailed struct {
func (x *PreConditionFailed) Reset() { func (x *PreConditionFailed) Reset() {
*x = PreConditionFailed{} *x = PreConditionFailed{}
mi := &file_messages_proto_msgTypes[16] mi := &file_messages_proto_msgTypes[22]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -1189,7 +1477,7 @@ func (x *PreConditionFailed) String() string {
func (*PreConditionFailed) ProtoMessage() {} func (*PreConditionFailed) ProtoMessage() {}
func (x *PreConditionFailed) ProtoReflect() protoreflect.Message { func (x *PreConditionFailed) ProtoReflect() protoreflect.Message {
mi := &file_messages_proto_msgTypes[16] mi := &file_messages_proto_msgTypes[22]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -1202,7 +1490,7 @@ func (x *PreConditionFailed) ProtoReflect() protoreflect.Message {
// Deprecated: Use PreConditionFailed.ProtoReflect.Descriptor instead. // Deprecated: Use PreConditionFailed.ProtoReflect.Descriptor instead.
func (*PreConditionFailed) Descriptor() ([]byte, []int) { func (*PreConditionFailed) Descriptor() ([]byte, []int) {
return file_messages_proto_rawDescGZIP(), []int{16} return file_messages_proto_rawDescGZIP(), []int{22}
} }
func (x *PreConditionFailed) GetOperation() string { func (x *PreConditionFailed) GetOperation() string {
@@ -1233,7 +1521,7 @@ var file_messages_proto_rawDesc = string([]byte{
0x12, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x12, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x12, 0x0a, 0x10, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x43, 0x61, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x12, 0x0a, 0x10, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x43, 0x61,
0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xb7, 0x05, 0x0a, 0x07, 0x41, 0x64, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xc9, 0x05, 0x0a, 0x07, 0x41, 0x64,
0x64, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64, 0x64, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x69, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x1a, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x69, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x1a,
0x0a, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x0a, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05,
@@ -1274,125 +1562,146 @@ var file_messages_proto_rawDesc = string([]byte{
0x1d, 0x0a, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x64, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x1d, 0x0a, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x64, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09,
0x48, 0x01, 0x52, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x48, 0x01, 0x52, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x1f,
0x0a, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0d, 0x0a, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0d,
0x48, 0x02, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x88, 0x01, 0x01, 0x42, 0x48, 0x02, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12,
0x09, 0x0a, 0x07, 0x5f, 0x6f, 0x75, 0x74, 0x6c, 0x65, 0x74, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x73, 0x10, 0x0a, 0x03, 0x63, 0x67, 0x6d, 0x18, 0x19, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x63, 0x67,
0x74, 0x6f, 0x72, 0x65, 0x49, 0x64, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x6d, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x6f, 0x75, 0x74, 0x6c, 0x65, 0x74, 0x42, 0x0a, 0x0a, 0x08,
0x74, 0x49, 0x64, 0x22, 0x1c, 0x0a, 0x0a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49, 0x74, 0x65, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x64, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x61, 0x72,
0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x49, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x1c, 0x0a, 0x0a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49,
0x64, 0x22, 0x3c, 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x74, 0x65, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52,
0x69, 0x74, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x49, 0x64, 0x22, 0x3c, 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x51, 0x75, 0x61,
0x02, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x0d, 0x52, 0x02, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74,
0x86, 0x02, 0x0a, 0x0b, 0x53, 0x65, 0x74, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x12, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74,
0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x79, 0x22, 0x86, 0x02, 0x0a, 0x0b, 0x53, 0x65, 0x74, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72,
0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20,
0x74, 0x65, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x14, 0x0a,
0x73, 0x12, 0x3c, 0x0a, 0x0b, 0x70, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x05, 0x69, 0x74,
0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x65, 0x6d, 0x73, 0x12, 0x3c, 0x0a, 0x0b, 0x70, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x6f, 0x69,
0x73, 0x2e, 0x50, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61,
0x0b, 0x70, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12, 0x67, 0x65, 0x73, 0x2e, 0x50, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x48,
0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x00, 0x52, 0x0b, 0x70, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x88, 0x01,
0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x7a, 0x69, 0x70, 0x01, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01,
0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x7a, 0x69, 0x70, 0x12, 0x1d, 0x0a, 0x07, 0x61, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x7a,
0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x07, 0x69, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x7a, 0x69, 0x70, 0x12, 0x1d, 0x0a,
0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x88, 0x01, 0x01, 0x12, 0x17, 0x0a, 0x04, 0x63, 0x69, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01,
0x74, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x04, 0x63, 0x69, 0x74, 0x79,
0x88, 0x01, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x70, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x6f,
0x69, 0x6e, 0x74, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42,
0x07, 0x0a, 0x05, 0x5f, 0x63, 0x69, 0x74, 0x79, 0x22, 0xf9, 0x01, 0x0a, 0x0e, 0x53, 0x65, 0x74,
0x50, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x64,
0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52,
0x0a, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x49, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69,
0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x04, 0x6e,
0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x61, 0x6d,
0x65, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18,
0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
0x88, 0x01, 0x01, 0x12, 0x17, 0x0a, 0x04, 0x63, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28,
0x09, 0x48, 0x02, 0x52, 0x04, 0x63, 0x69, 0x74, 0x79, 0x88, 0x01, 0x01, 0x12, 0x15, 0x0a, 0x03,
0x7a, 0x69, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x03, 0x7a, 0x69, 0x70,
0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x07,
0x20, 0x01, 0x28, 0x09, 0x48, 0x04, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x88,
0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x5f,
0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x63, 0x69, 0x74, 0x79,
0x42, 0x06, 0x0a, 0x04, 0x5f, 0x7a, 0x69, 0x70, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x63, 0x6f, 0x75,
0x6e, 0x74, 0x72, 0x79, 0x22, 0xd6, 0x01, 0x0a, 0x0b, 0x50, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x50,
0x6f, 0x69, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x02, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a,
0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01,
0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x88, 0x01, 0x01, 0x12, 0x17, 0x0a, 0x04, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x88, 0x01, 0x01, 0x12, 0x17, 0x0a, 0x04,
0x63, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x04, 0x63, 0x69, 0x63, 0x69, 0x74, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x04, 0x63, 0x69,
0x74, 0x79, 0x88, 0x01, 0x01, 0x12, 0x15, 0x0a, 0x03, 0x7a, 0x69, 0x70, 0x18, 0x05, 0x20, 0x01, 0x74, 0x79, 0x88, 0x01, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x70, 0x69, 0x63, 0x6b, 0x75, 0x70,
0x28, 0x09, 0x48, 0x03, 0x52, 0x03, 0x7a, 0x69, 0x70, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73,
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x04, 0x52, 0x73, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x63, 0x69, 0x74, 0x79, 0x22, 0xf9, 0x01, 0x0a, 0x0e, 0x53,
0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x65, 0x74, 0x50, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1e, 0x0a,
0x6e, 0x61, 0x6d, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x0a, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x42, 0x07, 0x0a, 0x05, 0x5f, 0x63, 0x69, 0x74, 0x79, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x7a, 0x69, 0x0d, 0x52, 0x0a, 0x64, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x49, 0x64, 0x12, 0x0e, 0x0a,
0x70, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x20, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x17, 0x0a,
0x0e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x12, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6e,
0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73,
0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65,
0x73, 0x73, 0x88, 0x01, 0x01, 0x12, 0x17, 0x0a, 0x04, 0x63, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20,
0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x04, 0x63, 0x69, 0x74, 0x79, 0x88, 0x01, 0x01, 0x12, 0x15,
0x0a, 0x03, 0x7a, 0x69, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x03, 0x7a,
0x69, 0x70, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79,
0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x04, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72,
0x79, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x0a, 0x0a,
0x08, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x63, 0x69,
0x74, 0x79, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x7a, 0x69, 0x70, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x63,
0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x22, 0xd6, 0x01, 0x0a, 0x0b, 0x50, 0x69, 0x63, 0x6b, 0x75,
0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x17, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12,
0x1d, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
0x48, 0x01, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x88, 0x01, 0x01, 0x12, 0x17,
0x0a, 0x04, 0x63, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x04,
0x63, 0x69, 0x74, 0x79, 0x88, 0x01, 0x01, 0x12, 0x15, 0x0a, 0x03, 0x7a, 0x69, 0x70, 0x18, 0x05,
0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x03, 0x7a, 0x69, 0x70, 0x88, 0x01, 0x01, 0x12, 0x1d,
0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48,
0x04, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a,
0x05, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65,
0x73, 0x73, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x63, 0x69, 0x74, 0x79, 0x42, 0x06, 0x0a, 0x04, 0x5f,
0x7a, 0x69, 0x70, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x22,
0x20, 0x0a, 0x0e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72,
0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69,
0x64, 0x22, 0x23, 0x0a, 0x09, 0x53, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x16,
0x0a, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x22, 0x4f, 0x0a, 0x0f, 0x4c, 0x69, 0x6e, 0x65, 0x49, 0x74,
0x65, 0x6d, 0x4d, 0x61, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a,
0x07, 0x6d, 0x61, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
0x6d, 0x61, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x22, 0x27, 0x0a, 0x15, 0x52, 0x65, 0x6d, 0x6f, 0x76,
0x65, 0x4c, 0x69, 0x6e, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x4d, 0x61, 0x72, 0x6b, 0x69, 0x6e, 0x67,
0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64,
0x22, 0x71, 0x0a, 0x11, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
0x41, 0x64, 0x64, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x69, 0x74, 0x65, 0x6d, 0x49, 0x64, 0x12, 0x1c, 0x0a,
0x09, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
0x52, 0x09, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x0e, 0x6f,
0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x04, 0x20,
0x01, 0x28, 0x09, 0x52, 0x0e, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65,
0x6e, 0x63, 0x65, 0x22, 0x11, 0x0a, 0x0f, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x65,
0x63, 0x6c, 0x69, 0x6e, 0x65, 0x64, 0x22, 0x14, 0x0a, 0x12, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72,
0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x69, 0x65, 0x77, 0x65, 0x64, 0x22, 0xb9, 0x01, 0x0a,
0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x4f,
0x72, 0x64, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x68,
0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x68,
0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72,
0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6f,
0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x75,
0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x75, 0x73, 0x68, 0x12, 0x1e,
0x0a, 0x0a, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0a, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18,
0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52,
0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x40, 0x0a, 0x0c, 0x4f, 0x72, 0x64, 0x65,
0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x72, 0x64, 0x65,
0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72,
0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x06, 0x0a, 0x04, 0x4e, 0x6f,
0x6f, 0x70, 0x22, 0x74, 0x0a, 0x12, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65,
0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x72, 0x64, 0x65,
0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72,
0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x70, 0x61,
0x79, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18,
0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x6e,
0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x22, 0x66, 0x0a, 0x11, 0x49, 0x6e, 0x76, 0x65,
0x6e, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x12, 0x0e, 0x0a,
0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a,
0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73,
0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x88, 0x01, 0x01, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x22, 0x7c, 0x0a, 0x0a, 0x41, 0x64, 0x64, 0x56, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x12, 0x12,
0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f,
0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x76, 0x6f, 0x75, 0x63,
0x68, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c,
0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x20, 0x0a, 0x0b,
0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x1f,
0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x56, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x12,
0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x22, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x22,
0xb9, 0x01, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0xa7, 0x01, 0x0a, 0x19, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72,
0x75, 0x74, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0x13, 0x0a,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x12, 0x1a, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x88,
0x08, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x01, 0x01, 0x12, 0x22, 0x0a, 0x0c, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x43, 0x6f,
0x08, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x69,
0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x6e, 0x67, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e,
0x0c, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x67, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x69, 0x67,
0x04, 0x70, 0x75, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x75, 0x73, 0x6e, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x28, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61,
0x68, 0x12, 0x1e, 0x0a, 0x0a, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x04, 0x64, 0x61,
0x6e, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x06, 0x20, 0x01, 0x74, 0x61, 0x42, 0x05, 0x0a, 0x03, 0x5f, 0x69, 0x64, 0x22, 0x74, 0x0a, 0x12, 0x50, 0x72, 0x65,
0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x40, 0x0a, 0x0c, 0x4f, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12,
0x72, 0x64, 0x65, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x1c, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,
0x72, 0x64, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x28, 0x09, 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a,
0x64, 0x65, 0x72, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x06, 0x0a, 0x72, 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x03, 0x20, 0x01,
0x04, 0x4e, 0x6f, 0x6f, 0x70, 0x22, 0x74, 0x0a, 0x12, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x69, 0x7a, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x42,
0x72, 0x64, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x2e, 0x74, 0x6f, 0x72, 0x6e, 0x62, 0x65, 0x72, 0x67, 0x2e,
0x64, 0x65, 0x72, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x6d, 0x65, 0x2f, 0x67, 0x6f, 0x2d, 0x63, 0x61, 0x72, 0x74, 0x2d, 0x61, 0x63, 0x74, 0x6f, 0x72,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2c, 0x0a, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x62,
0x11, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e,
0x74, 0x49, 0x6e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x22, 0x66, 0x0a, 0x11, 0x49,
0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64,
0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64,
0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1d, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x6d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x6d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x22, 0x7c, 0x0a, 0x0a, 0x41, 0x64, 0x64, 0x56, 0x6f, 0x75, 0x63, 0x68, 0x65,
0x72, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,
0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x76,
0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28,
0x09, 0x52, 0x0c, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12,
0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
0x6e, 0x22, 0x1f, 0x0a, 0x0d, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x56, 0x6f, 0x75, 0x63, 0x68,
0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02,
0x69, 0x64, 0x22, 0xa7, 0x01, 0x0a, 0x19, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x53, 0x75, 0x62,
0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73,
0x12, 0x13, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x02,
0x69, 0x64, 0x88, 0x01, 0x01, 0x12, 0x22, 0x0a, 0x0c, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x69, 0x6e,
0x67, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6f, 0x66, 0x66,
0x65, 0x72, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x69, 0x67,
0x6e, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,
0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x54, 0x79, 0x70, 0x65, 0x12, 0x28, 0x0a, 0x04, 0x64,
0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52,
0x04, 0x64, 0x61, 0x74, 0x61, 0x42, 0x05, 0x0a, 0x03, 0x5f, 0x69, 0x64, 0x22, 0x74, 0x0a, 0x12,
0x50, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x61, 0x69, 0x6c,
0x65, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2a, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18,
0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x05, 0x69, 0x6e, 0x70,
0x75, 0x74, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x2e, 0x74, 0x6f, 0x72, 0x6e, 0x62, 0x65,
0x72, 0x67, 0x2e, 0x6d, 0x65, 0x2f, 0x67, 0x6f, 0x2d, 0x63, 0x61, 0x72, 0x74, 0x2d, 0x61, 0x63,
0x74, 0x6f, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}) })
var ( var (
@@ -1407,7 +1716,7 @@ func file_messages_proto_rawDescGZIP() []byte {
return file_messages_proto_rawDescData return file_messages_proto_rawDescData
} }
var file_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 17) var file_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 23)
var file_messages_proto_goTypes = []any{ var file_messages_proto_goTypes = []any{
(*ClearCartRequest)(nil), // 0: messages.ClearCartRequest (*ClearCartRequest)(nil), // 0: messages.ClearCartRequest
(*AddItem)(nil), // 1: messages.AddItem (*AddItem)(nil), // 1: messages.AddItem
@@ -1417,21 +1726,27 @@ var file_messages_proto_goTypes = []any{
(*SetPickupPoint)(nil), // 5: messages.SetPickupPoint (*SetPickupPoint)(nil), // 5: messages.SetPickupPoint
(*PickupPoint)(nil), // 6: messages.PickupPoint (*PickupPoint)(nil), // 6: messages.PickupPoint
(*RemoveDelivery)(nil), // 7: messages.RemoveDelivery (*RemoveDelivery)(nil), // 7: messages.RemoveDelivery
(*CreateCheckoutOrder)(nil), // 8: messages.CreateCheckoutOrder (*SetUserId)(nil), // 8: messages.SetUserId
(*OrderCreated)(nil), // 9: messages.OrderCreated (*LineItemMarking)(nil), // 9: messages.LineItemMarking
(*Noop)(nil), // 10: messages.Noop (*RemoveLineItemMarking)(nil), // 10: messages.RemoveLineItemMarking
(*InitializeCheckout)(nil), // 11: messages.InitializeCheckout (*SubscriptionAdded)(nil), // 11: messages.SubscriptionAdded
(*InventoryReserved)(nil), // 12: messages.InventoryReserved (*PaymentDeclined)(nil), // 12: messages.PaymentDeclined
(*AddVoucher)(nil), // 13: messages.AddVoucher (*ConfirmationViewed)(nil), // 13: messages.ConfirmationViewed
(*RemoveVoucher)(nil), // 14: messages.RemoveVoucher (*CreateCheckoutOrder)(nil), // 14: messages.CreateCheckoutOrder
(*UpsertSubscriptionDetails)(nil), // 15: messages.UpsertSubscriptionDetails (*OrderCreated)(nil), // 15: messages.OrderCreated
(*PreConditionFailed)(nil), // 16: messages.PreConditionFailed (*Noop)(nil), // 16: messages.Noop
(*anypb.Any)(nil), // 17: google.protobuf.Any (*InitializeCheckout)(nil), // 17: messages.InitializeCheckout
(*InventoryReserved)(nil), // 18: messages.InventoryReserved
(*AddVoucher)(nil), // 19: messages.AddVoucher
(*RemoveVoucher)(nil), // 20: messages.RemoveVoucher
(*UpsertSubscriptionDetails)(nil), // 21: messages.UpsertSubscriptionDetails
(*PreConditionFailed)(nil), // 22: messages.PreConditionFailed
(*anypb.Any)(nil), // 23: google.protobuf.Any
} }
var file_messages_proto_depIdxs = []int32{ var file_messages_proto_depIdxs = []int32{
6, // 0: messages.SetDelivery.pickupPoint:type_name -> messages.PickupPoint 6, // 0: messages.SetDelivery.pickupPoint:type_name -> messages.PickupPoint
17, // 1: messages.UpsertSubscriptionDetails.data:type_name -> google.protobuf.Any 23, // 1: messages.UpsertSubscriptionDetails.data:type_name -> google.protobuf.Any
17, // 2: messages.PreConditionFailed.input:type_name -> google.protobuf.Any 23, // 2: messages.PreConditionFailed.input:type_name -> google.protobuf.Any
3, // [3:3] is the sub-list for method output_type 3, // [3:3] is the sub-list for method output_type
3, // [3:3] is the sub-list for method input_type 3, // [3:3] is the sub-list for method input_type
3, // [3:3] is the sub-list for extension type_name 3, // [3:3] is the sub-list for extension type_name
@@ -1448,15 +1763,15 @@ func file_messages_proto_init() {
file_messages_proto_msgTypes[4].OneofWrappers = []any{} file_messages_proto_msgTypes[4].OneofWrappers = []any{}
file_messages_proto_msgTypes[5].OneofWrappers = []any{} file_messages_proto_msgTypes[5].OneofWrappers = []any{}
file_messages_proto_msgTypes[6].OneofWrappers = []any{} file_messages_proto_msgTypes[6].OneofWrappers = []any{}
file_messages_proto_msgTypes[12].OneofWrappers = []any{} file_messages_proto_msgTypes[18].OneofWrappers = []any{}
file_messages_proto_msgTypes[15].OneofWrappers = []any{} file_messages_proto_msgTypes[21].OneofWrappers = []any{}
type x struct{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_messages_proto_rawDesc), len(file_messages_proto_rawDesc)), RawDescriptor: unsafe.Slice(unsafe.StringData(file_messages_proto_rawDesc), len(file_messages_proto_rawDesc)),
NumEnums: 0, NumEnums: 0,
NumMessages: 17, NumMessages: 23,
NumExtensions: 0, NumExtensions: 0,
NumServices: 0, NumServices: 0,
}, },

View File

@@ -31,6 +31,7 @@ message AddItem {
optional string outlet = 12; optional string outlet = 12;
optional string storeId = 22; optional string storeId = 22;
optional uint32 parentId = 23; optional uint32 parentId = 23;
string cgm = 25;
} }
message RemoveItem { uint32 Id = 1; } message RemoveItem { uint32 Id = 1; }
@@ -71,6 +72,34 @@ message PickupPoint {
message RemoveDelivery { uint32 id = 1; } message RemoveDelivery { uint32 id = 1; }
message SetUserId {
string userId = 1;
}
message LineItemMarking {
uint32 id = 1;
uint32 type = 2;
string marking = 3;
}
message RemoveLineItemMarking {
uint32 id = 1;
}
message SubscriptionAdded {
uint32 itemId = 1;
string detailsId = 3;
string orderReference = 4;
}
message PaymentDeclined {
}
message ConfirmationViewed {
}
message CreateCheckoutOrder { message CreateCheckoutOrder {
string terms = 1; string terms = 1;
string checkout = 2; string checkout = 2;