165 lines
5.0 KiB
Markdown
165 lines
5.0 KiB
Markdown
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. |