all the refactor
Build and Publish / BuildAndDeployAmd64 (push) Failing after 5s
Build and Publish / BuildAndDeployArm64 (push) Failing after 6s

This commit is contained in:
2026-06-28 17:51:52 +02:00
parent 7db0d236c7
commit aa8b2bdedc
84 changed files with 4328 additions and 2344 deletions
+39 -10
View File
@@ -28,6 +28,8 @@ import (
"git.k6n.net/mats/go-cart-actor/pkg/outbox"
messages "git.k6n.net/mats/go-cart-actor/proto/order"
"git.k6n.net/mats/platform/config"
"git.k6n.net/mats/platform/rabbit"
"git.k6n.net/mats/platform/tax"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/proto"
@@ -42,7 +44,7 @@ type server struct {
freg *flow.Registry
flows *flowStore
provider order.PaymentProvider
taxProvider order.TaxProvider
taxProvider tax.Provider
defaultFlow string
dataDir string
idem *idempotency.Store
@@ -112,11 +114,37 @@ func main() {
}
go box.Run(context.Background(), newRabbitPublisher(amqpURL), 5*time.Second, logger)
emitPub = box
// Stream applied order mutations to the shared mutations exchange (routing
// key mutation.order) for the backoffice live feed. Best-effort, separate
// from the durable outbox above.
if conn, derr := rabbit.Dial(amqpURL, "order"); derr != nil {
logger.Warn("order: mutation feed disabled", "err", derr)
} else {
feed := actor.NewAmqpListener(conn.Connection(), "order", actor.MutationSummary)
feed.DefineTopics()
pool.AddListener(feed)
// Declare the "order" topic exchange the outbox relay publishes
// order.created to, so a publish can't hit a missing exchange before
// a consumer declares it. Durable + idempotent.
if ch, cerr := conn.Channel(); cerr != nil {
logger.Warn("order: declare order exchange: channel", "err", cerr)
} else {
if eerr := ch.ExchangeDeclare("order", "topic", true, false, false, false, nil); eerr != nil {
logger.Warn("order: declare order exchange", "err", eerr)
}
_ = ch.Close()
}
}
}
freg := flow.NewRegistry()
flow.RegisterBuiltinHooks(freg)
order.RegisterFlowActions(freg, applier, provider)
order.RegisterEmitHook(freg, emitPub)
// order.created domain event → durable outbox → "order" topic exchange.
// Reactors: inventory commit, fulfillment allocation.
order.RegisterOrderCreatedEmit(freg, applier, emitPub, "order", "order")
engine := flow.NewEngine(freg, logger)
def, err := order.EmbeddedFlow("place-and-pay")
@@ -248,8 +276,9 @@ type lineReq struct {
Sku string `json:"sku"`
Name string `json:"name"`
Quantity int32 `json:"quantity"`
UnitPrice int64 `json:"unitPrice"` // inc-vat, minor units
TaxRate int32 `json:"taxRate"` // percent
UnitPrice int64 `json:"unitPrice"` // inc-vat, minor units
TaxRate int32 `json:"taxRate"` // basis points (2500 = 25%)
Location string `json:"location,omitempty"` // inventory commit location / store id
}
type checkoutReq struct {
@@ -343,7 +372,7 @@ func (s *server) buildPlaceOrder(id order.OrderId, req *checkoutReq) *messages.P
var total, totalTax int64
for _, l := range req.Lines {
lineTotal := l.UnitPrice * int64(l.Quantity)
lineTax := s.taxProvider.ComputeTax(lineTotal, int(l.TaxRate))
lineTax := s.taxProvider.Compute(lineTotal, int(l.TaxRate))
total += lineTotal
totalTax += lineTax
po.Lines = append(po.Lines, &messages.OrderLine{
@@ -442,8 +471,8 @@ func (s *server) handleList(w http.ResponseWriter, r *http.Request) {
OrderId: order.OrderId(raw).String(),
Reference: g.OrderReference,
Status: g.Status,
TotalAmount: g.TotalAmount,
CapturedAmount: g.CapturedAmount,
TotalAmount: g.TotalAmount.Int64(),
CapturedAmount: g.CapturedAmount.Int64(),
Currency: g.Currency,
PlacedAt: g.PlacedAt,
})
@@ -457,15 +486,15 @@ func (s *server) handleList(w http.ResponseWriter, r *http.Request) {
// NordicTaxProvider with SE as the default country (matching the current
// Nordic-only footprint). Set TAX_PROVIDER=static for dev and tests
// (no country awareness).
func selectTaxProvider() order.TaxProvider {
func selectTaxProvider() tax.Provider {
provider := os.Getenv("TAX_PROVIDER")
switch provider {
case "static":
return order.NewStaticTaxProvider()
return tax.NewStatic()
case "nordic":
return order.NewNordicTaxProvider(config.EnvString("TAX_DEFAULT_COUNTRY", "SE"))
return tax.NewNordic(config.EnvString("TAX_DEFAULT_COUNTRY", "SE"))
default:
return order.NewNordicTaxProvider(config.EnvString("TAX_DEFAULT_COUNTRY", "SE"))
return tax.NewNordic(config.EnvString("TAX_DEFAULT_COUNTRY", "SE"))
}
}