all the refactor
This commit is contained in:
+39
-10
@@ -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"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user