From 915d845014daa1b3c3c5d7d6d1989c5aa8b5c75e Mon Sep 17 00:00:00 2001 From: matst80 Date: Sat, 18 Oct 2025 13:37:33 +0200 Subject: [PATCH 01/10] update --- cmd/cart/main.go | 117 +++++++++++++++++++++++++---------------------- 1 file changed, 62 insertions(+), 55 deletions(-) diff --git a/cmd/cart/main.go b/cmd/cart/main.go index c767309..03fb479 100644 --- a/cmd/cart/main.go +++ b/cmd/cart/main.go @@ -138,19 +138,69 @@ func main() { pool: pool, } - conn, err := amqp.Dial(amqpUrl) - if err != nil { - fmt.Errorf("failed to connect to RabbitMQ: %w", err) - } + klarnaClient := NewKlarnaClient(KlarnaPlaygroundUrl, os.Getenv("KLARNA_API_USERNAME"), os.Getenv("KLARNA_API_PASSWORD")) - amqpListener := actor.NewAmqpListener(conn, func(id uint64, msg []actor.ApplyResult) (any, error) { - return &CartChangeEvent{ - CartId: cart.CartId(id), - Mutations: msg, - }, nil - }) - amqpListener.DefineTopics() - pool.AddListener(amqpListener) + syncedServer := NewPoolServer(pool, fmt.Sprintf("%s, %s", name, podIp), klarnaClient) + + mux := http.NewServeMux() + + if amqpUrl == "" { + log.Printf("no connection to amqp defined") + } else { + conn, err := amqp.Dial(amqpUrl) + if err != nil { + fmt.Errorf("failed to connect to RabbitMQ: %w", err) + } + + amqpListener := actor.NewAmqpListener(conn, func(id uint64, msg []actor.ApplyResult) (any, error) { + return &CartChangeEvent{ + CartId: cart.CartId(id), + Mutations: msg, + }, nil + }) + amqpListener.DefineTopics() + pool.AddListener(amqpListener) + orderHandler := NewAmqpOrderHandler(conn) + orderHandler.DefineTopics() + + mux.HandleFunc("/push", func(w http.ResponseWriter, r *http.Request) { + + if r.Method != http.MethodPost { + w.WriteHeader(http.StatusMethodNotAllowed) + return + } + orderId := r.URL.Query().Get("order_id") + log.Printf("Order confirmation push: %s", orderId) + + order, err := klarnaClient.GetOrder(orderId) + + if err != nil { + log.Printf("Error creating request: %v\n", err) + w.WriteHeader(http.StatusInternalServerError) + return + } + + err = confirmOrder(order, orderHandler) + if err != nil { + log.Printf("Error confirming order: %v\n", err) + w.WriteHeader(http.StatusInternalServerError) + return + } + + err = triggerOrderCompleted(syncedServer, order) + if err != nil { + log.Printf("Error processing cart message: %v\n", err) + w.WriteHeader(http.StatusInternalServerError) + return + } + err = klarnaClient.AcknowledgeOrder(orderId) + if err != nil { + log.Printf("Error acknowledging order: %v\n", err) + } + + w.WriteHeader(http.StatusOK) + }) + } grpcSrv, err := actor.NewControlServer[*cart.CartGrain](controlPlaneConfig, pool) if err != nil { @@ -188,13 +238,6 @@ func main() { } }(GetDiscovery()) - orderHandler := NewAmqpOrderHandler(conn) - orderHandler.DefineTopics() - klarnaClient := NewKlarnaClient(KlarnaPlaygroundUrl, os.Getenv("KLARNA_API_USERNAME"), os.Getenv("KLARNA_API_PASSWORD")) - - syncedServer := NewPoolServer(pool, fmt.Sprintf("%s, %s", name, podIp), klarnaClient) - - mux := http.NewServeMux() mux.Handle("/cart/", http.StripPrefix("/cart", syncedServer.Serve())) // only for local mux.HandleFunc("GET /add/remote/{host}", func(w http.ResponseWriter, r *http.Request) { @@ -295,43 +338,7 @@ func main() { //} w.WriteHeader(http.StatusOK) }) - mux.HandleFunc("/push", func(w http.ResponseWriter, r *http.Request) { - if r.Method != http.MethodPost { - w.WriteHeader(http.StatusMethodNotAllowed) - return - } - orderId := r.URL.Query().Get("order_id") - log.Printf("Order confirmation push: %s", orderId) - - order, err := klarnaClient.GetOrder(orderId) - - if err != nil { - log.Printf("Error creating request: %v\n", err) - w.WriteHeader(http.StatusInternalServerError) - return - } - - err = confirmOrder(order, orderHandler) - if err != nil { - log.Printf("Error confirming order: %v\n", err) - w.WriteHeader(http.StatusInternalServerError) - return - } - - err = triggerOrderCompleted(syncedServer, order) - if err != nil { - log.Printf("Error processing cart message: %v\n", err) - w.WriteHeader(http.StatusInternalServerError) - return - } - err = klarnaClient.AcknowledgeOrder(orderId) - if err != nil { - log.Printf("Error acknowledging order: %v\n", err) - } - - w.WriteHeader(http.StatusOK) - }) mux.HandleFunc("/version", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("1.0.0")) From dc352e3b747be915a0390c0646fdfb6a4eb21379 Mon Sep 17 00:00:00 2001 From: matst80 Date: Sat, 18 Oct 2025 14:33:21 +0200 Subject: [PATCH 02/10] voucher change --- cmd/cart/main.go | 2 +- cmd/cart/pool-server.go | 4 + pkg/cart/cart-mutation-helper.go | 3 + pkg/cart/mutation_precondition.go | 7 + pkg/messages/control_plane.pb.go | 95 +++---- pkg/messages/control_plane_grpc.pb.go | 2 +- pkg/messages/messages.pb.go | 373 ++++++++++++++------------ pkg/voucher/service.go | 58 +++- proto/messages.proto | 16 +- 9 files changed, 313 insertions(+), 247 deletions(-) create mode 100644 pkg/cart/mutation_precondition.go diff --git a/cmd/cart/main.go b/cmd/cart/main.go index 03fb479..6400d78 100644 --- a/cmd/cart/main.go +++ b/cmd/cart/main.go @@ -149,7 +149,7 @@ func main() { } else { conn, err := amqp.Dial(amqpUrl) if err != nil { - fmt.Errorf("failed to connect to RabbitMQ: %w", err) + log.Fatalf("failed to connect to RabbitMQ: %w", err) } amqpListener := actor.NewAmqpListener(conn, func(id uint64, msg []actor.ApplyResult) (any, error) { diff --git a/cmd/cart/pool-server.go b/cmd/cart/pool-server.go index e6e0720..bef6074 100644 --- a/cmd/cart/pool-server.go +++ b/cmd/cart/pool-server.go @@ -456,6 +456,10 @@ func (s *PoolServer) AddVoucherHandler(w http.ResponseWriter, r *http.Request, c v := voucher.Service{} msg, err := v.GetVoucher(data.VoucherCode) if err != nil { + s.ApplyLocal(cartId, &messages.PreConditionFailed{ + Operation: "AddVoucher", + Error: err.Error(), + }) w.WriteHeader(http.StatusInternalServerError) w.Write([]byte(err.Error())) return err diff --git a/pkg/cart/cart-mutation-helper.go b/pkg/cart/cart-mutation-helper.go index 69035bf..70a973d 100644 --- a/pkg/cart/cart-mutation-helper.go +++ b/pkg/cart/cart-mutation-helper.go @@ -45,6 +45,9 @@ func NewCartMultationRegistry() actor.MutationRegistry { actor.NewMutation(UpsertSubscriptionDetails, func() *messages.UpsertSubscriptionDetails { return &messages.UpsertSubscriptionDetails{} }), + actor.NewMutation(PreConditionFailed, func() *messages.PreConditionFailed { + return &messages.PreConditionFailed{} + }), ) return reg diff --git a/pkg/cart/mutation_precondition.go b/pkg/cart/mutation_precondition.go new file mode 100644 index 0000000..8fa6d98 --- /dev/null +++ b/pkg/cart/mutation_precondition.go @@ -0,0 +1,7 @@ +package cart + +import messages "git.tornberg.me/go-cart-actor/pkg/messages" + +func PreConditionFailed(g *CartGrain, m *messages.PreConditionFailed) error { + return nil +} diff --git a/pkg/messages/control_plane.pb.go b/pkg/messages/control_plane.pb.go index 95aed7d..1bd4ef8 100644 --- a/pkg/messages/control_plane.pb.go +++ b/pkg/messages/control_plane.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.5 -// protoc v5.29.3 +// protoc-gen-go v1.36.10 +// protoc v6.32.1 // source: control_plane.proto package messages @@ -453,65 +453,38 @@ func (x *ExpiryAnnounce) GetIds() []uint64 { var File_control_plane_proto protoreflect.FileDescriptor -var file_control_plane_proto_rawDesc = string([]byte{ - 0x0a, 0x13, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x5f, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, - 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x3c, 0x0a, 0x09, 0x50, 0x69, 0x6e, 0x67, - 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x75, 0x6e, 0x69, - 0x78, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x75, 0x6e, - 0x69, 0x78, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x33, 0x0a, 0x10, 0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6b, 0x6e, - 0x6f, 0x77, 0x6e, 0x5f, 0x68, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x0a, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x48, 0x6f, 0x73, 0x74, 0x73, 0x22, 0x26, 0x0a, 0x0e, 0x4e, - 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x14, 0x0a, - 0x05, 0x68, 0x6f, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x68, 0x6f, - 0x73, 0x74, 0x73, 0x22, 0x21, 0x0a, 0x0d, 0x41, 0x63, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x73, 0x52, - 0x65, 0x70, 0x6c, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x04, 0x52, 0x03, 0x69, 0x64, 0x73, 0x22, 0x46, 0x0a, 0x0e, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x43, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x41, 0x63, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x63, 0x63, 0x65, - 0x70, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x61, 0x63, 0x63, 0x65, - 0x70, 0x74, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x23, - 0x0a, 0x0d, 0x43, 0x6c, 0x6f, 0x73, 0x69, 0x6e, 0x67, 0x4e, 0x6f, 0x74, 0x69, 0x63, 0x65, 0x12, - 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, - 0x6f, 0x73, 0x74, 0x22, 0x39, 0x0a, 0x11, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, - 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, - 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x04, 0x52, 0x03, 0x69, 0x64, 0x73, 0x22, 0x36, - 0x0a, 0x0e, 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, - 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x68, 0x6f, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x04, 0x52, 0x03, 0x69, 0x64, 0x73, 0x32, 0x8d, 0x03, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x74, 0x72, - 0x6f, 0x6c, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x12, 0x2c, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, - 0x0f, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x1a, 0x13, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x50, 0x69, 0x6e, 0x67, - 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x41, 0x0a, 0x09, 0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, 0x61, - 0x74, 0x65, 0x12, 0x1a, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x4e, 0x65, - 0x67, 0x6f, 0x74, 0x69, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, - 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x4e, 0x65, 0x67, 0x6f, 0x74, 0x69, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x3c, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x4c, - 0x6f, 0x63, 0x61, 0x6c, 0x41, 0x63, 0x74, 0x6f, 0x72, 0x49, 0x64, 0x73, 0x12, 0x0f, 0x2e, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x17, 0x2e, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x41, 0x63, 0x74, 0x6f, 0x72, 0x49, 0x64, - 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x4a, 0x0a, 0x11, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, - 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x12, 0x1b, 0x2e, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, - 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x1a, 0x18, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x73, 0x2e, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x41, - 0x63, 0x6b, 0x12, 0x44, 0x0a, 0x0e, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x45, 0x78, - 0x70, 0x69, 0x72, 0x79, 0x12, 0x18, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, - 0x45, 0x78, 0x70, 0x69, 0x72, 0x79, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x1a, 0x18, - 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x43, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x41, 0x63, 0x6b, 0x12, 0x3c, 0x0a, 0x07, 0x43, 0x6c, 0x6f, 0x73, - 0x69, 0x6e, 0x67, 0x12, 0x17, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x43, - 0x6c, 0x6f, 0x73, 0x69, 0x6e, 0x67, 0x4e, 0x6f, 0x74, 0x69, 0x63, 0x65, 0x1a, 0x18, 0x2e, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x43, 0x68, 0x61, - 0x6e, 0x67, 0x65, 0x41, 0x63, 0x6b, 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, -}) +const file_control_plane_proto_rawDesc = "" + + "\n" + + "\x13control_plane.proto\x12\bmessages\"\a\n" + + "\x05Empty\"<\n" + + "\tPingReply\x12\x12\n" + + "\x04host\x18\x01 \x01(\tR\x04host\x12\x1b\n" + + "\tunix_time\x18\x02 \x01(\x03R\bunixTime\"3\n" + + "\x10NegotiateRequest\x12\x1f\n" + + "\vknown_hosts\x18\x01 \x03(\tR\n" + + "knownHosts\"&\n" + + "\x0eNegotiateReply\x12\x14\n" + + "\x05hosts\x18\x01 \x03(\tR\x05hosts\"!\n" + + "\rActorIdsReply\x12\x10\n" + + "\x03ids\x18\x01 \x03(\x04R\x03ids\"F\n" + + "\x0eOwnerChangeAck\x12\x1a\n" + + "\baccepted\x18\x01 \x01(\bR\baccepted\x12\x18\n" + + "\amessage\x18\x02 \x01(\tR\amessage\"#\n" + + "\rClosingNotice\x12\x12\n" + + "\x04host\x18\x01 \x01(\tR\x04host\"9\n" + + "\x11OwnershipAnnounce\x12\x12\n" + + "\x04host\x18\x01 \x01(\tR\x04host\x12\x10\n" + + "\x03ids\x18\x02 \x03(\x04R\x03ids\"6\n" + + "\x0eExpiryAnnounce\x12\x12\n" + + "\x04host\x18\x01 \x01(\tR\x04host\x12\x10\n" + + "\x03ids\x18\x02 \x03(\x04R\x03ids2\x8d\x03\n" + + "\fControlPlane\x12,\n" + + "\x04Ping\x12\x0f.messages.Empty\x1a\x13.messages.PingReply\x12A\n" + + "\tNegotiate\x12\x1a.messages.NegotiateRequest\x1a\x18.messages.NegotiateReply\x12<\n" + + "\x10GetLocalActorIds\x12\x0f.messages.Empty\x1a\x17.messages.ActorIdsReply\x12J\n" + + "\x11AnnounceOwnership\x12\x1b.messages.OwnershipAnnounce\x1a\x18.messages.OwnerChangeAck\x12D\n" + + "\x0eAnnounceExpiry\x12\x18.messages.ExpiryAnnounce\x1a\x18.messages.OwnerChangeAck\x12<\n" + + "\aClosing\x12\x17.messages.ClosingNotice\x1a\x18.messages.OwnerChangeAckB.Z,git.tornberg.me/go-cart-actor/proto;messagesb\x06proto3" var ( file_control_plane_proto_rawDescOnce sync.Once diff --git a/pkg/messages/control_plane_grpc.pb.go b/pkg/messages/control_plane_grpc.pb.go index d0c9cf5..08e2815 100644 --- a/pkg/messages/control_plane_grpc.pb.go +++ b/pkg/messages/control_plane_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.5.1 -// - protoc v5.29.3 +// - protoc v6.32.1 // source: control_plane.proto package messages diff --git a/pkg/messages/messages.pb.go b/pkg/messages/messages.pb.go index 237cd4d..7303467 100644 --- a/pkg/messages/messages.pb.go +++ b/pkg/messages/messages.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.5 -// protoc v5.29.3 +// protoc-gen-go v1.36.10 +// protoc v6.32.1 // source: messages.proto package messages @@ -1166,167 +1166,198 @@ func (x *UpsertSubscriptionDetails) GetData() *anypb.Any { return nil } +type PreConditionFailed struct { + state protoimpl.MessageState `protogen:"open.v1"` + Operation string `protobuf:"bytes,1,opt,name=operation,proto3" json:"operation,omitempty"` + Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` + Input *anypb.Any `protobuf:"bytes,3,opt,name=input,proto3" json:"input,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *PreConditionFailed) Reset() { + *x = PreConditionFailed{} + mi := &file_messages_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PreConditionFailed) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PreConditionFailed) ProtoMessage() {} + +func (x *PreConditionFailed) ProtoReflect() protoreflect.Message { + mi := &file_messages_proto_msgTypes[16] + 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 PreConditionFailed.ProtoReflect.Descriptor instead. +func (*PreConditionFailed) Descriptor() ([]byte, []int) { + return file_messages_proto_rawDescGZIP(), []int{16} +} + +func (x *PreConditionFailed) GetOperation() string { + if x != nil { + return x.Operation + } + return "" +} + +func (x *PreConditionFailed) GetError() string { + if x != nil { + return x.Error + } + return "" +} + +func (x *PreConditionFailed) GetInput() *anypb.Any { + if x != nil { + return x.Input + } + return nil +} + var File_messages_proto protoreflect.FileDescriptor -var file_messages_proto_rawDesc = string([]byte{ - 0x0a, 0x0e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 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, - 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, - 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, - 0x0a, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72, - 0x69, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x70, 0x72, 0x69, 0x63, 0x65, - 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x72, 0x67, 0x50, 0x72, 0x69, 0x63, 0x65, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x08, 0x6f, 0x72, 0x67, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, - 0x73, 0x6b, 0x75, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x6b, 0x75, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x63, - 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x12, 0x10, - 0x0a, 0x03, 0x74, 0x61, 0x78, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x74, 0x61, 0x78, - 0x12, 0x14, 0x0a, 0x05, 0x62, 0x72, 0x61, 0x6e, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x62, 0x72, 0x61, 0x6e, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, - 0x72, 0x79, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, - 0x72, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x32, 0x18, - 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x32, - 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x33, 0x18, 0x10, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x33, 0x12, 0x1c, - 0x0a, 0x09, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x34, 0x18, 0x11, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x34, 0x12, 0x1c, 0x0a, 0x09, - 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x35, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x35, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x69, - 0x73, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x64, 0x69, 0x73, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x72, - 0x74, 0x69, 0x63, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, - 0x73, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x73, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x65, 0x6c, 0x6c, - 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, - 0x6c, 0x6c, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x72, 0x79, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x61, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x18, 0x18, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x61, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x12, 0x1b, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x6c, 0x65, 0x74, 0x18, 0x0c, 0x20, 0x01, - 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x6c, 0x65, 0x74, 0x88, 0x01, 0x01, 0x12, - 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, - 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, - 0x09, 0x0a, 0x07, 0x5f, 0x6f, 0x75, 0x74, 0x6c, 0x65, 0x74, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x73, - 0x74, 0x6f, 0x72, 0x65, 0x49, 0x64, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, - 0x74, 0x49, 0x64, 0x22, 0x1c, 0x0a, 0x0a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49, 0x74, 0x65, - 0x6d, 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, 0x6e, 0x74, - 0x69, 0x74, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x02, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, - 0x86, 0x02, 0x0a, 0x0b, 0x53, 0x65, 0x74, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x12, - 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x69, - 0x74, 0x65, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, - 0x73, 0x12, 0x3c, 0x0a, 0x0b, 0x70, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x73, 0x2e, 0x50, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x48, 0x00, 0x52, - 0x0b, 0x70, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12, - 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x7a, 0x69, 0x70, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x7a, 0x69, 0x70, 0x12, 0x1d, 0x0a, 0x07, 0x61, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x06, 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, 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, - 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, - 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, 0x79, 0x0a, 0x0b, 0x56, - 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x20, - 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, - 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x71, 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, 0x39, - 0x0a, 0x0c, 0x76, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x03, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, - 0x56, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x0c, 0x76, 0x6f, 0x75, - 0x63, 0x68, 0x65, 0x72, 0x52, 0x75, 0x6c, 0x65, 0x73, 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, 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, -}) +const file_messages_proto_rawDesc = "" + + "\n" + + "\x0emessages.proto\x12\bmessages\x1a\x19google/protobuf/any.proto\"\x12\n" + + "\x10ClearCartRequest\"\xb7\x05\n" + + "\aAddItem\x12\x17\n" + + "\aitem_id\x18\x01 \x01(\rR\x06itemId\x12\x1a\n" + + "\bquantity\x18\x02 \x01(\x05R\bquantity\x12\x14\n" + + "\x05price\x18\x03 \x01(\x03R\x05price\x12\x1a\n" + + "\borgPrice\x18\t \x01(\x03R\borgPrice\x12\x10\n" + + "\x03sku\x18\x04 \x01(\tR\x03sku\x12\x12\n" + + "\x04name\x18\x05 \x01(\tR\x04name\x12\x14\n" + + "\x05image\x18\x06 \x01(\tR\x05image\x12\x14\n" + + "\x05stock\x18\a \x01(\x05R\x05stock\x12\x10\n" + + "\x03tax\x18\b \x01(\x05R\x03tax\x12\x14\n" + + "\x05brand\x18\r \x01(\tR\x05brand\x12\x1a\n" + + "\bcategory\x18\x0e \x01(\tR\bcategory\x12\x1c\n" + + "\tcategory2\x18\x0f \x01(\tR\tcategory2\x12\x1c\n" + + "\tcategory3\x18\x10 \x01(\tR\tcategory3\x12\x1c\n" + + "\tcategory4\x18\x11 \x01(\tR\tcategory4\x12\x1c\n" + + "\tcategory5\x18\x12 \x01(\tR\tcategory5\x12\x1e\n" + + "\n" + + "disclaimer\x18\n" + + " \x01(\tR\n" + + "disclaimer\x12 \n" + + "\varticleType\x18\v \x01(\tR\varticleType\x12\x1a\n" + + "\bsellerId\x18\x13 \x01(\tR\bsellerId\x12\x1e\n" + + "\n" + + "sellerName\x18\x14 \x01(\tR\n" + + "sellerName\x12\x18\n" + + "\acountry\x18\x15 \x01(\tR\acountry\x12\x1e\n" + + "\n" + + "saleStatus\x18\x18 \x01(\tR\n" + + "saleStatus\x12\x1b\n" + + "\x06outlet\x18\f \x01(\tH\x00R\x06outlet\x88\x01\x01\x12\x1d\n" + + "\astoreId\x18\x16 \x01(\tH\x01R\astoreId\x88\x01\x01\x12\x1f\n" + + "\bparentId\x18\x17 \x01(\rH\x02R\bparentId\x88\x01\x01B\t\n" + + "\a_outletB\n" + + "\n" + + "\b_storeIdB\v\n" + + "\t_parentId\"\x1c\n" + + "\n" + + "RemoveItem\x12\x0e\n" + + "\x02Id\x18\x01 \x01(\rR\x02Id\"<\n" + + "\x0eChangeQuantity\x12\x0e\n" + + "\x02Id\x18\x01 \x01(\rR\x02Id\x12\x1a\n" + + "\bquantity\x18\x02 \x01(\x05R\bquantity\"\x86\x02\n" + + "\vSetDelivery\x12\x1a\n" + + "\bprovider\x18\x01 \x01(\tR\bprovider\x12\x14\n" + + "\x05items\x18\x02 \x03(\rR\x05items\x12<\n" + + "\vpickupPoint\x18\x03 \x01(\v2\x15.messages.PickupPointH\x00R\vpickupPoint\x88\x01\x01\x12\x18\n" + + "\acountry\x18\x04 \x01(\tR\acountry\x12\x10\n" + + "\x03zip\x18\x05 \x01(\tR\x03zip\x12\x1d\n" + + "\aaddress\x18\x06 \x01(\tH\x01R\aaddress\x88\x01\x01\x12\x17\n" + + "\x04city\x18\a \x01(\tH\x02R\x04city\x88\x01\x01B\x0e\n" + + "\f_pickupPointB\n" + + "\n" + + "\b_addressB\a\n" + + "\x05_city\"\xf9\x01\n" + + "\x0eSetPickupPoint\x12\x1e\n" + + "\n" + + "deliveryId\x18\x01 \x01(\rR\n" + + "deliveryId\x12\x0e\n" + + "\x02id\x18\x02 \x01(\tR\x02id\x12\x17\n" + + "\x04name\x18\x03 \x01(\tH\x00R\x04name\x88\x01\x01\x12\x1d\n" + + "\aaddress\x18\x04 \x01(\tH\x01R\aaddress\x88\x01\x01\x12\x17\n" + + "\x04city\x18\x05 \x01(\tH\x02R\x04city\x88\x01\x01\x12\x15\n" + + "\x03zip\x18\x06 \x01(\tH\x03R\x03zip\x88\x01\x01\x12\x1d\n" + + "\acountry\x18\a \x01(\tH\x04R\acountry\x88\x01\x01B\a\n" + + "\x05_nameB\n" + + "\n" + + "\b_addressB\a\n" + + "\x05_cityB\x06\n" + + "\x04_zipB\n" + + "\n" + + "\b_country\"\xd6\x01\n" + + "\vPickupPoint\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x17\n" + + "\x04name\x18\x02 \x01(\tH\x00R\x04name\x88\x01\x01\x12\x1d\n" + + "\aaddress\x18\x03 \x01(\tH\x01R\aaddress\x88\x01\x01\x12\x17\n" + + "\x04city\x18\x04 \x01(\tH\x02R\x04city\x88\x01\x01\x12\x15\n" + + "\x03zip\x18\x05 \x01(\tH\x03R\x03zip\x88\x01\x01\x12\x1d\n" + + "\acountry\x18\x06 \x01(\tH\x04R\acountry\x88\x01\x01B\a\n" + + "\x05_nameB\n" + + "\n" + + "\b_addressB\a\n" + + "\x05_cityB\x06\n" + + "\x04_zipB\n" + + "\n" + + "\b_country\" \n" + + "\x0eRemoveDelivery\x12\x0e\n" + + "\x02id\x18\x01 \x01(\rR\x02id\"\xb9\x01\n" + + "\x13CreateCheckoutOrder\x12\x14\n" + + "\x05terms\x18\x01 \x01(\tR\x05terms\x12\x1a\n" + + "\bcheckout\x18\x02 \x01(\tR\bcheckout\x12\"\n" + + "\fconfirmation\x18\x03 \x01(\tR\fconfirmation\x12\x12\n" + + "\x04push\x18\x04 \x01(\tR\x04push\x12\x1e\n" + + "\n" + + "validation\x18\x05 \x01(\tR\n" + + "validation\x12\x18\n" + + "\acountry\x18\x06 \x01(\tR\acountry\"@\n" + + "\fOrderCreated\x12\x18\n" + + "\aorderId\x18\x01 \x01(\tR\aorderId\x12\x16\n" + + "\x06status\x18\x02 \x01(\tR\x06status\"\x06\n" + + "\x04Noop\"t\n" + + "\x12InitializeCheckout\x12\x18\n" + + "\aorderId\x18\x01 \x01(\tR\aorderId\x12\x16\n" + + "\x06status\x18\x02 \x01(\tR\x06status\x12,\n" + + "\x11paymentInProgress\x18\x03 \x01(\bR\x11paymentInProgress\"y\n" + + "\vVoucherRule\x12\x12\n" + + "\x04type\x18\x02 \x01(\tR\x04type\x12 \n" + + "\vdescription\x18\x03 \x01(\tR\vdescription\x12\x1c\n" + + "\tcondition\x18\x04 \x01(\tR\tcondition\x12\x16\n" + + "\x06action\x18\x05 \x01(\tR\x06action\"q\n" + + "\n" + + "AddVoucher\x12\x12\n" + + "\x04code\x18\x01 \x01(\tR\x04code\x12\x14\n" + + "\x05value\x18\x02 \x01(\x03R\x05value\x129\n" + + "\fvoucherRules\x18\x03 \x03(\v2\x15.messages.VoucherRuleR\fvoucherRules\"\x1f\n" + + "\rRemoveVoucher\x12\x0e\n" + + "\x02id\x18\x01 \x01(\rR\x02id\"\xa7\x01\n" + + "\x19UpsertSubscriptionDetails\x12\x13\n" + + "\x02id\x18\x01 \x01(\tH\x00R\x02id\x88\x01\x01\x12\"\n" + + "\fofferingCode\x18\x02 \x01(\tR\fofferingCode\x12 \n" + + "\vsigningType\x18\x03 \x01(\tR\vsigningType\x12(\n" + + "\x04data\x18\x04 \x01(\v2\x14.google.protobuf.AnyR\x04dataB\x05\n" + + "\x03_id\"t\n" + + "\x12PreConditionFailed\x12\x1c\n" + + "\toperation\x18\x01 \x01(\tR\toperation\x12\x14\n" + + "\x05error\x18\x02 \x01(\tR\x05error\x12*\n" + + "\x05input\x18\x03 \x01(\v2\x14.google.protobuf.AnyR\x05inputB.Z,git.tornberg.me/go-cart-actor/proto;messagesb\x06proto3" var ( file_messages_proto_rawDescOnce sync.Once @@ -1340,7 +1371,7 @@ func file_messages_proto_rawDescGZIP() []byte { return file_messages_proto_rawDescData } -var file_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 16) +var file_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 17) var file_messages_proto_goTypes = []any{ (*ClearCartRequest)(nil), // 0: messages.ClearCartRequest (*AddItem)(nil), // 1: messages.AddItem @@ -1358,17 +1389,19 @@ var file_messages_proto_goTypes = []any{ (*AddVoucher)(nil), // 13: messages.AddVoucher (*RemoveVoucher)(nil), // 14: messages.RemoveVoucher (*UpsertSubscriptionDetails)(nil), // 15: messages.UpsertSubscriptionDetails - (*anypb.Any)(nil), // 16: google.protobuf.Any + (*PreConditionFailed)(nil), // 16: messages.PreConditionFailed + (*anypb.Any)(nil), // 17: google.protobuf.Any } var file_messages_proto_depIdxs = []int32{ 6, // 0: messages.SetDelivery.pickupPoint:type_name -> messages.PickupPoint 12, // 1: messages.AddVoucher.voucherRules:type_name -> messages.VoucherRule - 16, // 2: messages.UpsertSubscriptionDetails.data: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 input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name + 17, // 2: messages.UpsertSubscriptionDetails.data:type_name -> google.protobuf.Any + 17, // 3: messages.PreConditionFailed.input:type_name -> google.protobuf.Any + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name } func init() { file_messages_proto_init() } @@ -1387,7 +1420,7 @@ func file_messages_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_messages_proto_rawDesc), len(file_messages_proto_rawDesc)), NumEnums: 0, - NumMessages: 16, + NumMessages: 17, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/voucher/service.go b/pkg/voucher/service.go index d75877e..e4dc5f0 100644 --- a/pkg/voucher/service.go +++ b/pkg/voucher/service.go @@ -1,7 +1,10 @@ package voucher import ( + "encoding/json" "errors" + "fmt" + "os" "git.tornberg.me/go-cart-actor/pkg/messages" ) @@ -12,11 +15,9 @@ type Rule struct { } type Voucher struct { - Code string `json:"code"` - Value int64 `json:"discount"` - TaxValue int64 `json:"taxValue"` - TaxRate int `json:"taxRate"` - rules []Rule `json:"rules"` + Code string `json:"code"` + Value int64 `json:"discount"` + rules []*messages.VoucherRule `json:"rules"` } type Service struct { @@ -29,10 +30,51 @@ func (s *Service) GetVoucher(code string) (*messages.AddVoucher, error) { if code == "" { return nil, ErrInvalidCode } - value := int64(250_00) + sf, err := LoadStateFile("data/vouchers.json") + if err != nil { + return nil, err + } + v, ok := sf.GetVoucher(code) + if !ok { + return nil, fmt.Errorf("no voucher found for code: %s", code) + } + return &messages.AddVoucher{ Code: code, - Value: value, - VoucherRules: make([]*messages.VoucherRule, 0), + Value: v.Value, + VoucherRules: v.rules, }, nil } + +type State struct { + Vouchers []Voucher `json:"vouchers"` +} + +type StateFile struct { + State State `json:"state"` + Vercion int `json:"version"` +} + +func (sf *StateFile) GetVoucher(code string) (*Voucher, bool) { + for _, v := range sf.State.Vouchers { + if v.Code == code { + return &v, true + } + } + return nil, false +} + +func LoadStateFile(fileName string) (*StateFile, error) { + f, err := os.Open(fileName) + if err != nil { + return nil, err + } + defer f.Close() + dec := json.NewDecoder(f) + sf := &StateFile{} + err = dec.Decode(sf) + if err != nil { + return nil, err + } + return sf, nil +} diff --git a/proto/messages.proto b/proto/messages.proto index 1b281a1..0b9f827 100644 --- a/proto/messages.proto +++ b/proto/messages.proto @@ -119,10 +119,14 @@ message RemoveVoucher { } message UpsertSubscriptionDetails { - - optional string id = 1; - string offeringCode = 2; - string signingType = 3; - google.protobuf.Any data = 4; - + optional string id = 1; + string offeringCode = 2; + string signingType = 3; + google.protobuf.Any data = 4; +} + +message PreConditionFailed { + string operation = 1; + string error = 2; + google.protobuf.Any input = 3; } From 2ce45656d9df3cf93a949ba829b5709cbce8e2cc Mon Sep 17 00:00:00 2001 From: matst80 Date: Sat, 18 Oct 2025 14:42:52 +0200 Subject: [PATCH 03/10] test --- pkg/voucher/service.go | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/pkg/voucher/service.go b/pkg/voucher/service.go index e4dc5f0..e5913c3 100644 --- a/pkg/voucher/service.go +++ b/pkg/voucher/service.go @@ -15,9 +15,9 @@ type Rule struct { } type Voucher struct { - Code string `json:"code"` - Value int64 `json:"discount"` - rules []*messages.VoucherRule `json:"rules"` + Code string `json:"code"` + Value int64 `json:"value"` + rules string `json:"rules"` } type Service struct { @@ -40,9 +40,16 @@ func (s *Service) GetVoucher(code string) (*messages.AddVoucher, error) { } return &messages.AddVoucher{ - Code: code, - Value: v.Value, - VoucherRules: v.rules, + Code: code, + Value: v.Value, + VoucherRules: []*messages.VoucherRule{ + { + Condition: v.rules, + Type: "", + Description: "", + Action: "", + }, + }, }, nil } From d58409e3fcec8a2323dcb160b4e243d5a95fb919 Mon Sep 17 00:00:00 2001 From: matst80 Date: Sat, 18 Oct 2025 15:14:22 +0200 Subject: [PATCH 04/10] add total test --- pkg/voucher/parser_test.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/pkg/voucher/parser_test.go b/pkg/voucher/parser_test.go index c618e69..d9f4de4 100644 --- a/pkg/voucher/parser_test.go +++ b/pkg/voucher/parser_test.go @@ -28,6 +28,32 @@ func TestParseRules_SimpleSku(t *testing.T) { } } +func TestRuleCartTotal(t *testing.T) { + rs, err := ParseRules("min_total>=500000") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if len(rs.Conditions) != 1 { + t.Fatalf("expected 1 condition got %d", len(rs.Conditions)) + } + c := rs.Conditions[0] + if c.Kind != RuleMinTotal { + t.Fatalf("expected kind cart total got %s", c.Kind) + } + ctx := EvalContext{ + Items: []Item{ + Item{ + Sku: "123", + }, + }, + CartTotalInc: 400000, + } + applied := rs.Applies(ctx) + if applied { + t.Fatalf("expected") + } +} + func TestParseRules_CategoryAndSkuMixedSeparators(t *testing.T) { rs, err := ParseRules(" category=Shoes|Bags ; sku= A | B , min_total>=1000\nmin_item_price>=500") if err != nil { From b7f0990269802ae684392e185ff17be0a32baa5d Mon Sep 17 00:00:00 2001 From: matst80 Date: Sat, 18 Oct 2025 15:21:11 +0200 Subject: [PATCH 05/10] simpler rules --- pkg/cart/cart-grain.go | 12 +-- pkg/messages/messages.pb.go | 139 ++++++++----------------------- pkg/voucher/service.go | 13 +-- proto/messages.proto | 159 ++++++++++++++++-------------------- 4 files changed, 114 insertions(+), 209 deletions(-) diff --git a/pkg/cart/cart-grain.go b/pkg/cart/cart-grain.go index 712f20e..8682d4d 100644 --- a/pkg/cart/cart-grain.go +++ b/pkg/cart/cart-grain.go @@ -92,10 +92,10 @@ type CartGrain struct { } type Voucher struct { - Code string `json:"code"` - Rules []*messages.VoucherRule `json:"rules"` - Id uint32 `json:"id"` - Value int64 `json:"value"` + Code string `json:"code"` + Rules []string `json:"rules"` + Id uint32 `json:"id"` + Value int64 `json:"value"` } func (v *Voucher) AppliesTo(cart *CartGrain) ([]*CartItem, bool) { @@ -127,8 +127,8 @@ func (v *Voucher) AppliesTo(cart *CartGrain) ([]*CartItem, bool) { } // All voucher rules must pass (logical AND) - for _, rule := range v.Rules { - expr := rule.GetCondition() + for _, expr := range v.Rules { + if expr == "" { // Empty condition treated as pass (acts like a comment / placeholder) continue diff --git a/pkg/messages/messages.pb.go b/pkg/messages/messages.pb.go index 7303467..9f4f8a5 100644 --- a/pkg/messages/messages.pb.go +++ b/pkg/messages/messages.pb.go @@ -926,86 +926,18 @@ func (x *InitializeCheckout) GetPaymentInProgress() bool { return false } -type VoucherRule struct { - state protoimpl.MessageState `protogen:"open.v1"` - Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` - Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` - Condition string `protobuf:"bytes,4,opt,name=condition,proto3" json:"condition,omitempty"` - Action string `protobuf:"bytes,5,opt,name=action,proto3" json:"action,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *VoucherRule) Reset() { - *x = VoucherRule{} - mi := &file_messages_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *VoucherRule) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*VoucherRule) ProtoMessage() {} - -func (x *VoucherRule) 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 VoucherRule.ProtoReflect.Descriptor instead. -func (*VoucherRule) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{12} -} - -func (x *VoucherRule) GetType() string { - if x != nil { - return x.Type - } - return "" -} - -func (x *VoucherRule) GetDescription() string { - if x != nil { - return x.Description - } - return "" -} - -func (x *VoucherRule) GetCondition() string { - if x != nil { - return x.Condition - } - return "" -} - -func (x *VoucherRule) GetAction() string { - if x != nil { - return x.Action - } - return "" -} - type AddVoucher struct { state protoimpl.MessageState `protogen:"open.v1"` Code string `protobuf:"bytes,1,opt,name=code,proto3" json:"code,omitempty"` Value int64 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"` - VoucherRules []*VoucherRule `protobuf:"bytes,3,rep,name=voucherRules,proto3" json:"voucherRules,omitempty"` + VoucherRules []string `protobuf:"bytes,3,rep,name=voucherRules,proto3" json:"voucherRules,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *AddVoucher) Reset() { *x = AddVoucher{} - mi := &file_messages_proto_msgTypes[13] + mi := &file_messages_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1017,7 +949,7 @@ func (x *AddVoucher) String() string { func (*AddVoucher) ProtoMessage() {} func (x *AddVoucher) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[13] + mi := &file_messages_proto_msgTypes[12] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1030,7 +962,7 @@ func (x *AddVoucher) ProtoReflect() protoreflect.Message { // Deprecated: Use AddVoucher.ProtoReflect.Descriptor instead. func (*AddVoucher) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{13} + return file_messages_proto_rawDescGZIP(), []int{12} } func (x *AddVoucher) GetCode() string { @@ -1047,7 +979,7 @@ func (x *AddVoucher) GetValue() int64 { return 0 } -func (x *AddVoucher) GetVoucherRules() []*VoucherRule { +func (x *AddVoucher) GetVoucherRules() []string { if x != nil { return x.VoucherRules } @@ -1063,7 +995,7 @@ type RemoveVoucher struct { func (x *RemoveVoucher) Reset() { *x = RemoveVoucher{} - mi := &file_messages_proto_msgTypes[14] + mi := &file_messages_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1075,7 +1007,7 @@ func (x *RemoveVoucher) String() string { func (*RemoveVoucher) ProtoMessage() {} func (x *RemoveVoucher) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[14] + mi := &file_messages_proto_msgTypes[13] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1088,7 +1020,7 @@ func (x *RemoveVoucher) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveVoucher.ProtoReflect.Descriptor instead. func (*RemoveVoucher) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{14} + return file_messages_proto_rawDescGZIP(), []int{13} } func (x *RemoveVoucher) GetId() uint32 { @@ -1110,7 +1042,7 @@ type UpsertSubscriptionDetails struct { func (x *UpsertSubscriptionDetails) Reset() { *x = UpsertSubscriptionDetails{} - mi := &file_messages_proto_msgTypes[15] + mi := &file_messages_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1122,7 +1054,7 @@ func (x *UpsertSubscriptionDetails) String() string { func (*UpsertSubscriptionDetails) ProtoMessage() {} func (x *UpsertSubscriptionDetails) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[15] + mi := &file_messages_proto_msgTypes[14] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1135,7 +1067,7 @@ func (x *UpsertSubscriptionDetails) ProtoReflect() protoreflect.Message { // Deprecated: Use UpsertSubscriptionDetails.ProtoReflect.Descriptor instead. func (*UpsertSubscriptionDetails) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{15} + return file_messages_proto_rawDescGZIP(), []int{14} } func (x *UpsertSubscriptionDetails) GetId() string { @@ -1177,7 +1109,7 @@ type PreConditionFailed struct { func (x *PreConditionFailed) Reset() { *x = PreConditionFailed{} - mi := &file_messages_proto_msgTypes[16] + mi := &file_messages_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1189,7 +1121,7 @@ func (x *PreConditionFailed) String() string { func (*PreConditionFailed) ProtoMessage() {} func (x *PreConditionFailed) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[16] + mi := &file_messages_proto_msgTypes[15] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1202,7 +1134,7 @@ func (x *PreConditionFailed) ProtoReflect() protoreflect.Message { // Deprecated: Use PreConditionFailed.ProtoReflect.Descriptor instead. func (*PreConditionFailed) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{16} + return file_messages_proto_rawDescGZIP(), []int{15} } func (x *PreConditionFailed) GetOperation() string { @@ -1335,17 +1267,12 @@ const file_messages_proto_rawDesc = "" + "\x12InitializeCheckout\x12\x18\n" + "\aorderId\x18\x01 \x01(\tR\aorderId\x12\x16\n" + "\x06status\x18\x02 \x01(\tR\x06status\x12,\n" + - "\x11paymentInProgress\x18\x03 \x01(\bR\x11paymentInProgress\"y\n" + - "\vVoucherRule\x12\x12\n" + - "\x04type\x18\x02 \x01(\tR\x04type\x12 \n" + - "\vdescription\x18\x03 \x01(\tR\vdescription\x12\x1c\n" + - "\tcondition\x18\x04 \x01(\tR\tcondition\x12\x16\n" + - "\x06action\x18\x05 \x01(\tR\x06action\"q\n" + + "\x11paymentInProgress\x18\x03 \x01(\bR\x11paymentInProgress\"Z\n" + "\n" + "AddVoucher\x12\x12\n" + "\x04code\x18\x01 \x01(\tR\x04code\x12\x14\n" + - "\x05value\x18\x02 \x01(\x03R\x05value\x129\n" + - "\fvoucherRules\x18\x03 \x03(\v2\x15.messages.VoucherRuleR\fvoucherRules\"\x1f\n" + + "\x05value\x18\x02 \x01(\x03R\x05value\x12\"\n" + + "\fvoucherRules\x18\x03 \x03(\tR\fvoucherRules\"\x1f\n" + "\rRemoveVoucher\x12\x0e\n" + "\x02id\x18\x01 \x01(\rR\x02id\"\xa7\x01\n" + "\x19UpsertSubscriptionDetails\x12\x13\n" + @@ -1371,7 +1298,7 @@ func file_messages_proto_rawDescGZIP() []byte { return file_messages_proto_rawDescData } -var file_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 17) +var file_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 16) var file_messages_proto_goTypes = []any{ (*ClearCartRequest)(nil), // 0: messages.ClearCartRequest (*AddItem)(nil), // 1: messages.AddItem @@ -1385,23 +1312,21 @@ var file_messages_proto_goTypes = []any{ (*OrderCreated)(nil), // 9: messages.OrderCreated (*Noop)(nil), // 10: messages.Noop (*InitializeCheckout)(nil), // 11: messages.InitializeCheckout - (*VoucherRule)(nil), // 12: messages.VoucherRule - (*AddVoucher)(nil), // 13: messages.AddVoucher - (*RemoveVoucher)(nil), // 14: messages.RemoveVoucher - (*UpsertSubscriptionDetails)(nil), // 15: messages.UpsertSubscriptionDetails - (*PreConditionFailed)(nil), // 16: messages.PreConditionFailed - (*anypb.Any)(nil), // 17: google.protobuf.Any + (*AddVoucher)(nil), // 12: messages.AddVoucher + (*RemoveVoucher)(nil), // 13: messages.RemoveVoucher + (*UpsertSubscriptionDetails)(nil), // 14: messages.UpsertSubscriptionDetails + (*PreConditionFailed)(nil), // 15: messages.PreConditionFailed + (*anypb.Any)(nil), // 16: google.protobuf.Any } var file_messages_proto_depIdxs = []int32{ 6, // 0: messages.SetDelivery.pickupPoint:type_name -> messages.PickupPoint - 12, // 1: messages.AddVoucher.voucherRules:type_name -> messages.VoucherRule - 17, // 2: messages.UpsertSubscriptionDetails.data:type_name -> google.protobuf.Any - 17, // 3: messages.PreConditionFailed.input:type_name -> google.protobuf.Any - 4, // [4:4] is the sub-list for method output_type - 4, // [4:4] is the sub-list for method input_type - 4, // [4:4] is the sub-list for extension type_name - 4, // [4:4] is the sub-list for extension extendee - 0, // [0:4] is the sub-list for field type_name + 16, // 1: messages.UpsertSubscriptionDetails.data:type_name -> google.protobuf.Any + 16, // 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 input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name } func init() { file_messages_proto_init() } @@ -1413,14 +1338,14 @@ func file_messages_proto_init() { file_messages_proto_msgTypes[4].OneofWrappers = []any{} file_messages_proto_msgTypes[5].OneofWrappers = []any{} file_messages_proto_msgTypes[6].OneofWrappers = []any{} - file_messages_proto_msgTypes[15].OneofWrappers = []any{} + file_messages_proto_msgTypes[14].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_messages_proto_rawDesc), len(file_messages_proto_rawDesc)), NumEnums: 0, - NumMessages: 17, + NumMessages: 16, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/voucher/service.go b/pkg/voucher/service.go index e5913c3..01a9677 100644 --- a/pkg/voucher/service.go +++ b/pkg/voucher/service.go @@ -17,7 +17,7 @@ type Rule struct { type Voucher struct { Code string `json:"code"` Value int64 `json:"value"` - rules string `json:"rules"` + Rules string `json:"rules"` } type Service struct { @@ -42,13 +42,8 @@ func (s *Service) GetVoucher(code string) (*messages.AddVoucher, error) { return &messages.AddVoucher{ Code: code, Value: v.Value, - VoucherRules: []*messages.VoucherRule{ - { - Condition: v.rules, - Type: "", - Description: "", - Action: "", - }, + VoucherRules: []string{ + v.Rules, }, }, nil } @@ -59,7 +54,7 @@ type State struct { type StateFile struct { State State `json:"state"` - Vercion int `json:"version"` + Version int `json:"version"` } func (sf *StateFile) GetVoucher(code string) (*Voucher, bool) { diff --git a/proto/messages.proto b/proto/messages.proto index 0b9f827..4ec43f5 100644 --- a/proto/messages.proto +++ b/proto/messages.proto @@ -4,129 +4,114 @@ option go_package = "git.tornberg.me/go-cart-actor/proto;messages"; import "google/protobuf/any.proto"; -message ClearCartRequest { - -} +message ClearCartRequest {} message AddItem { - uint32 item_id = 1; - int32 quantity = 2; - int64 price = 3; - int64 orgPrice = 9; - string sku = 4; - string name = 5; - string image = 6; - int32 stock = 7; - int32 tax = 8; - string brand = 13; - string category = 14; - string category2 = 15; - string category3 = 16; - string category4 = 17; - string category5 = 18; - string disclaimer = 10; - string articleType = 11; - string sellerId = 19; - string sellerName = 20; - string country = 21; - string saleStatus = 24; - optional string outlet = 12; - optional string storeId = 22; - optional uint32 parentId = 23; + uint32 item_id = 1; + int32 quantity = 2; + int64 price = 3; + int64 orgPrice = 9; + string sku = 4; + string name = 5; + string image = 6; + int32 stock = 7; + int32 tax = 8; + string brand = 13; + string category = 14; + string category2 = 15; + string category3 = 16; + string category4 = 17; + string category5 = 18; + string disclaimer = 10; + string articleType = 11; + string sellerId = 19; + string sellerName = 20; + string country = 21; + string saleStatus = 24; + optional string outlet = 12; + optional string storeId = 22; + optional uint32 parentId = 23; } -message RemoveItem { - uint32 Id = 1; -} +message RemoveItem { uint32 Id = 1; } message ChangeQuantity { - uint32 Id = 1; - int32 quantity = 2; + uint32 Id = 1; + int32 quantity = 2; } message SetDelivery { - string provider = 1; - repeated uint32 items = 2; - optional PickupPoint pickupPoint = 3; - string country = 4; - string zip = 5; - optional string address = 6; - optional string city = 7; + string provider = 1; + repeated uint32 items = 2; + optional PickupPoint pickupPoint = 3; + string country = 4; + string zip = 5; + optional string address = 6; + optional string city = 7; } message SetPickupPoint { - uint32 deliveryId = 1; - string id = 2; - optional string name = 3; - optional string address = 4; - optional string city = 5; - optional string zip = 6; - optional string country = 7; + uint32 deliveryId = 1; + string id = 2; + optional string name = 3; + optional string address = 4; + optional string city = 5; + optional string zip = 6; + optional string country = 7; } message PickupPoint { - string id = 1; - optional string name = 2; - optional string address = 3; - optional string city = 4; - optional string zip = 5; - optional string country = 6; + string id = 1; + optional string name = 2; + optional string address = 3; + optional string city = 4; + optional string zip = 5; + optional string country = 6; } -message RemoveDelivery { - uint32 id = 1; -} +message RemoveDelivery { uint32 id = 1; } message CreateCheckoutOrder { - string terms = 1; - string checkout = 2; - string confirmation = 3; - string push = 4; - string validation = 5; - string country = 6; + string terms = 1; + string checkout = 2; + string confirmation = 3; + string push = 4; + string validation = 5; + string country = 6; } message OrderCreated { - string orderId = 1; - string status = 2; + string orderId = 1; + string status = 2; } message Noop { - // Intentionally empty - used for ownership acquisition or health pings + // Intentionally empty - used for ownership acquisition or health pings } message InitializeCheckout { - string orderId = 1; - string status = 2; - bool paymentInProgress = 3; -} - -message VoucherRule { - string type = 2; - string description = 3; - string condition = 4; - string action = 5; + string orderId = 1; + string status = 2; + bool paymentInProgress = 3; } message AddVoucher { - string code = 1; - int64 value = 2; - repeated VoucherRule voucherRules = 3; + string code = 1; + int64 value = 2; + repeated string voucherRules = 3; } -message RemoveVoucher { - uint32 id = 1; -} +message RemoveVoucher { uint32 id = 1; } message UpsertSubscriptionDetails { - optional string id = 1; - string offeringCode = 2; - string signingType = 3; - google.protobuf.Any data = 4; + optional string id = 1; + string offeringCode = 2; + string signingType = 3; + google.protobuf.Any data = 4; } message PreConditionFailed { - string operation = 1; - string error = 2; - google.protobuf.Any input = 3; + string operation = 1; + string error = 2; + google.protobuf.Any input = 3; } From e127251a60c8b6d52808b0ab7aa116a3479af3ae Mon Sep 17 00:00:00 2001 From: matst80 Date: Sat, 18 Oct 2025 15:25:44 +0200 Subject: [PATCH 06/10] add state file parser --- pkg/cart/mutation_test.go | 2 +- pkg/promotions/types.go | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/pkg/cart/mutation_test.go b/pkg/cart/mutation_test.go index 68c37a2..50fff32 100644 --- a/pkg/cart/mutation_test.go +++ b/pkg/cart/mutation_test.go @@ -66,7 +66,7 @@ func msgClearCart() *messages.ClearCartRequest { return &messages.ClearCartRequest{} } -func msgAddVoucher(code string, value int64, rules ...*messages.VoucherRule) *messages.AddVoucher { +func msgAddVoucher(code string, value int64, rules ...string) *messages.AddVoucher { return &messages.AddVoucher{Code: code, Value: value, VoucherRules: rules} } diff --git a/pkg/promotions/types.go b/pkg/promotions/types.go index 3646c60..bf5b370 100644 --- a/pkg/promotions/types.go +++ b/pkg/promotions/types.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" "fmt" + "os" "strconv" ) @@ -369,3 +370,36 @@ func WalkConditions(conds []Condition, fn func(c Condition) bool) { } } } + +type PromotionState struct { + Vouchers []PromotionRule `json:"promotions"` +} + +type StateFile struct { + State PromotionState `json:"state"` + Version int `json:"version"` +} + +func (sf *StateFile) GetPromotion(id string) (*PromotionRule, bool) { + for _, v := range sf.State.Vouchers { + if v.ID == id { + return &v, true + } + } + return nil, false +} + +func LoadStateFile(fileName string) (*PromotionState, error) { + f, err := os.Open(fileName) + if err != nil { + return nil, err + } + defer f.Close() + dec := json.NewDecoder(f) + sf := &PromotionState{} + err = dec.Decode(sf) + if err != nil { + return nil, err + } + return sf, nil +} From 662b381a3429884ed5220e7c727b40a9b34e7439 Mon Sep 17 00:00:00 2001 From: matst80 Date: Sat, 18 Oct 2025 15:42:30 +0200 Subject: [PATCH 07/10] probably fix discounts --- pkg/cart/cart-grain.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/pkg/cart/cart-grain.go b/pkg/cart/cart-grain.go index 8682d4d..a4fb4b3 100644 --- a/pkg/cart/cart-grain.go +++ b/pkg/cart/cart-grain.go @@ -249,19 +249,22 @@ func (c *CartGrain) UpdateTotals() { for _, item := range c.Items { rowTotal := MultiplyPrice(item.Price, int64(item.Quantity)) - item.TotalPrice = *rowTotal - - c.TotalPrice.Add(*rowTotal) - if item.OrgPrice != nil { diff := NewPrice() diff.Add(*item.OrgPrice) diff.Subtract(item.Price) + diff.Multiply(int64(item.Quantity)) + rowTotal.Subtract(*diff) + item.Discount = diff if diff.IncVat > 0 { c.TotalDiscount.Add(*diff) } } + item.TotalPrice = *rowTotal + + c.TotalPrice.Add(*rowTotal) + } for _, delivery := range c.Deliveries { c.TotalPrice.Add(delivery.Price) From 0c127e9d38685268194c957334a5828409d209f0 Mon Sep 17 00:00:00 2001 From: matst80 Date: Sat, 18 Oct 2025 15:50:38 +0200 Subject: [PATCH 08/10] add description all the way --- pkg/cart/cart-grain.go | 16 ++++++++++------ pkg/messages/messages.pb.go | 13 +++++++++++-- pkg/voucher/service.go | 12 +++++++----- proto/messages.proto | 1 + 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/pkg/cart/cart-grain.go b/pkg/cart/cart-grain.go index a4fb4b3..5c5816b 100644 --- a/pkg/cart/cart-grain.go +++ b/pkg/cart/cart-grain.go @@ -92,10 +92,12 @@ type CartGrain struct { } type Voucher struct { - Code string `json:"code"` - Rules []string `json:"rules"` - Id uint32 `json:"id"` - Value int64 `json:"value"` + Code string `json:"code"` + Applied bool `json:"applied"` + Rules []string `json:"rules"` + Description string `json:"description,omitempty"` + Id uint32 `json:"id"` + Value int64 `json:"value"` } func (v *Voucher) AppliesTo(cart *CartGrain) ([]*CartItem, bool) { @@ -270,13 +272,15 @@ func (c *CartGrain) UpdateTotals() { c.TotalPrice.Add(delivery.Price) } for _, voucher := range c.Vouchers { - if _, ok := voucher.AppliesTo(c); ok { + _, ok := voucher.AppliesTo(c) + voucher.Applied = false + if ok { value := NewPriceFromIncVat(voucher.Value, 25) if c.TotalPrice.IncVat <= value.IncVat { // don't apply discounts to more than the total price continue } - + voucher.Applied = true c.TotalDiscount.Add(*value) c.TotalPrice.Subtract(*value) } diff --git a/pkg/messages/messages.pb.go b/pkg/messages/messages.pb.go index 9f4f8a5..86ccfed 100644 --- a/pkg/messages/messages.pb.go +++ b/pkg/messages/messages.pb.go @@ -931,6 +931,7 @@ type AddVoucher struct { Code string `protobuf:"bytes,1,opt,name=code,proto3" json:"code,omitempty"` Value int64 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"` VoucherRules []string `protobuf:"bytes,3,rep,name=voucherRules,proto3" json:"voucherRules,omitempty"` + Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -986,6 +987,13 @@ func (x *AddVoucher) GetVoucherRules() []string { return nil } +func (x *AddVoucher) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + type RemoveVoucher struct { state protoimpl.MessageState `protogen:"open.v1"` Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` @@ -1267,12 +1275,13 @@ const file_messages_proto_rawDesc = "" + "\x12InitializeCheckout\x12\x18\n" + "\aorderId\x18\x01 \x01(\tR\aorderId\x12\x16\n" + "\x06status\x18\x02 \x01(\tR\x06status\x12,\n" + - "\x11paymentInProgress\x18\x03 \x01(\bR\x11paymentInProgress\"Z\n" + + "\x11paymentInProgress\x18\x03 \x01(\bR\x11paymentInProgress\"|\n" + "\n" + "AddVoucher\x12\x12\n" + "\x04code\x18\x01 \x01(\tR\x04code\x12\x14\n" + "\x05value\x18\x02 \x01(\x03R\x05value\x12\"\n" + - "\fvoucherRules\x18\x03 \x03(\tR\fvoucherRules\"\x1f\n" + + "\fvoucherRules\x18\x03 \x03(\tR\fvoucherRules\x12 \n" + + "\vdescription\x18\x04 \x01(\tR\vdescription\"\x1f\n" + "\rRemoveVoucher\x12\x0e\n" + "\x02id\x18\x01 \x01(\rR\x02id\"\xa7\x01\n" + "\x19UpsertSubscriptionDetails\x12\x13\n" + diff --git a/pkg/voucher/service.go b/pkg/voucher/service.go index 01a9677..f65cd7c 100644 --- a/pkg/voucher/service.go +++ b/pkg/voucher/service.go @@ -15,9 +15,10 @@ type Rule struct { } type Voucher struct { - Code string `json:"code"` - Value int64 `json:"value"` - Rules string `json:"rules"` + Code string `json:"code"` + Value int64 `json:"value"` + Rules string `json:"rules"` + Description string `json:"description,omitempty"` } type Service struct { @@ -40,8 +41,9 @@ func (s *Service) GetVoucher(code string) (*messages.AddVoucher, error) { } return &messages.AddVoucher{ - Code: code, - Value: v.Value, + Code: code, + Value: v.Value, + Description: v.Description, VoucherRules: []string{ v.Rules, }, diff --git a/proto/messages.proto b/proto/messages.proto index 4ec43f5..772bfdd 100644 --- a/proto/messages.proto +++ b/proto/messages.proto @@ -99,6 +99,7 @@ message AddVoucher { string code = 1; int64 value = 2; repeated string voucherRules = 3; + string description = 4; } message RemoveVoucher { uint32 id = 1; } From a0c82dc35177e6c61528627f73d53dc93ed0ee7f Mon Sep 17 00:00:00 2001 From: matst80 Date: Sat, 18 Oct 2025 15:51:04 +0200 Subject: [PATCH 09/10] missing file --- pkg/cart/mutation_add_voucher.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pkg/cart/mutation_add_voucher.go b/pkg/cart/mutation_add_voucher.go index 85bffe0..88743cc 100644 --- a/pkg/cart/mutation_add_voucher.go +++ b/pkg/cart/mutation_add_voucher.go @@ -54,10 +54,12 @@ func AddVoucher(g *CartGrain, m *messages.AddVoucher) error { g.lastVoucherId++ g.Vouchers = append(g.Vouchers, &Voucher{ - Id: g.lastVoucherId, - Code: m.Code, - Rules: m.VoucherRules, - Value: m.Value, + Id: g.lastVoucherId, + Applied: false, + Description: m.Description, + Code: m.Code, + Rules: m.VoucherRules, + Value: m.Value, }) g.UpdateTotals() return nil From af3eb0d7bf1313a756fd773ea5caa990ff1366d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mats=20T=C3=B6rnberg?= Date: Sun, 19 Oct 2025 16:46:14 +0200 Subject: [PATCH 10/10] fix close if no queue is used --- pkg/actor/disk_storage.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/actor/disk_storage.go b/pkg/actor/disk_storage.go index deff401..5dba330 100644 --- a/pkg/actor/disk_storage.go +++ b/pkg/actor/disk_storage.go @@ -104,7 +104,9 @@ func (s *DiskStorage[V]) LoadEvents(id uint64, grain Grain[V]) error { } func (s *DiskStorage[V]) Close() { - s.save() + if s.queue != nil { + s.save() + } close(s.done) }