fixed po <-> tgsettle contract

This commit is contained in:
Stephan D
2026-03-06 15:12:14 +01:00
parent 031b8931ca
commit 3295b9d9f0
15 changed files with 540 additions and 76 deletions

View File

@@ -45,6 +45,9 @@ const (
type StepShell struct {
StepRef string `bson:"stepRef" json:"stepRef"`
StepCode string `bson:"stepCode" json:"stepCode"`
Rail model.Rail `bson:"rail,omitempty" json:"rail,omitempty"`
Gateway string `bson:"gateway,omitempty" json:"gateway,omitempty"`
InstanceID string `bson:"instanceId,omitempty" json:"instanceId,omitempty"`
ReportVisibility model.ReportVisibility `bson:"reportVisibility,omitempty" json:"reportVisibility,omitempty"`
UserLabel string `bson:"userLabel,omitempty" json:"userLabel,omitempty"`
}
@@ -53,6 +56,9 @@ type StepShell struct {
type StepExecution struct {
StepRef string `bson:"stepRef" json:"stepRef"`
StepCode string `bson:"stepCode" json:"stepCode"`
Rail model.Rail `bson:"rail,omitempty" json:"rail,omitempty"`
Gateway string `bson:"gateway,omitempty" json:"gateway,omitempty"`
InstanceID string `bson:"instanceId,omitempty" json:"instanceId,omitempty"`
ReportVisibility model.ReportVisibility `bson:"reportVisibility,omitempty" json:"reportVisibility,omitempty"`
UserLabel string `bson:"userLabel,omitempty" json:"userLabel,omitempty"`
State StepState `bson:"state" json:"state"`

View File

@@ -143,10 +143,16 @@ func buildInitialStepTelemetry(shell []StepShell) ([]StepExecution, error) {
return nil, merrors.InvalidArgument("steps[" + itoa(i) + "].report_visibility is invalid")
}
userLabel := strings.TrimSpace(shell[i].UserLabel)
railValue := model.ParseRail(string(shell[i].Rail))
gatewayID := strings.TrimSpace(shell[i].Gateway)
instanceID := strings.TrimSpace(shell[i].InstanceID)
out = append(out, StepExecution{
StepRef: stepRef,
StepCode: stepCode,
Rail: railValue,
Gateway: gatewayID,
InstanceID: instanceID,
ReportVisibility: visibility,
UserLabel: userLabel,
State: StepStatePending,

View File

@@ -6,6 +6,7 @@ import (
"time"
"github.com/tech/sendico/payments/storage/model"
"github.com/tech/sendico/pkg/discovery"
"github.com/tech/sendico/pkg/merrors"
paymenttypes "github.com/tech/sendico/pkg/payments/types"
"go.mongodb.org/mongo-driver/v2/bson"
@@ -42,7 +43,15 @@ func TestCreate_OK(t *testing.T) {
QuoteSnapshot: quote,
Steps: []StepShell{
{StepRef: " s1 ", StepCode: " reserve_funds ", ReportVisibility: model.ReportVisibilityHidden},
{StepRef: "s2", StepCode: "submit_gateway", ReportVisibility: model.ReportVisibilityUser, UserLabel: " Card payout "},
{
StepRef: "s2",
StepCode: "submit_gateway",
Rail: discovery.RailProviderSettlement,
Gateway: "payment_gateway_settlement",
InstanceID: "04a54fec-20f4-4250-a715-eb9886e13e12",
ReportVisibility: model.ReportVisibilityUser,
UserLabel: " Card payout ",
},
},
})
if err != nil {
@@ -111,6 +120,15 @@ func TestCreate_OK(t *testing.T) {
if got, want := payment.StepExecutions[1].UserLabel, "Card payout"; got != want {
t.Fatalf("unexpected second step user label: got=%q want=%q", got, want)
}
if got, want := payment.StepExecutions[1].Rail, model.Rail(discovery.RailProviderSettlement); got != want {
t.Fatalf("unexpected second step rail: got=%q want=%q", got, want)
}
if got, want := payment.StepExecutions[1].Gateway, "payment_gateway_settlement"; got != want {
t.Fatalf("unexpected second step gateway: got=%q want=%q", got, want)
}
if got, want := payment.StepExecutions[1].InstanceID, "04a54fec-20f4-4250-a715-eb9886e13e12"; got != want {
t.Fatalf("unexpected second step instance_id: got=%q want=%q", got, want)
}
// Verify immutable snapshot semantics by ensuring clones were created.
payment.IntentSnapshot.Ref = "changed"

View File

@@ -221,6 +221,9 @@ func toStepShells(graph *xplan.Graph) []agg.StepShell {
out = append(out, agg.StepShell{
StepRef: graph.Steps[i].StepRef,
StepCode: graph.Steps[i].StepCode,
Rail: graph.Steps[i].Rail,
Gateway: graph.Steps[i].Gateway,
InstanceID: graph.Steps[i].InstanceID,
ReportVisibility: graph.Steps[i].Visibility,
UserLabel: graph.Steps[i].UserLabel,
})

View File

@@ -408,6 +408,15 @@ func stepExecutionEqual(left, right agg.StepExecution) bool {
if left.StepRef != right.StepRef || left.StepCode != right.StepCode {
return false
}
if left.Rail != right.Rail {
return false
}
if strings.TrimSpace(left.Gateway) != strings.TrimSpace(right.Gateway) {
return false
}
if strings.TrimSpace(left.InstanceID) != strings.TrimSpace(right.InstanceID) {
return false
}
if left.State != right.State || left.Attempt != right.Attempt {
return false
}

View File

@@ -6,6 +6,7 @@ import (
"github.com/tech/sendico/payments/orchestrator/internal/service/orchestrationv2/agg"
"github.com/tech/sendico/payments/orchestrator/internal/service/orchestrationv2/xplan"
"github.com/tech/sendico/payments/storage/model"
"github.com/tech/sendico/pkg/discovery"
"github.com/tech/sendico/pkg/merrors"
)
@@ -144,6 +145,16 @@ func (s *svc) normalizeStepExecutions(
stepCode = stepsByRef[stepRef].StepCode
}
exec.StepCode = stepCode
step := stepsByRef[stepRef]
if exec.Rail == discovery.RailUnspecified {
exec.Rail = step.Rail
}
if strings.TrimSpace(exec.Gateway) == "" {
exec.Gateway = strings.TrimSpace(step.Gateway)
}
if strings.TrimSpace(exec.InstanceID) == "" {
exec.InstanceID = strings.TrimSpace(step.InstanceID)
}
exec.ReportVisibility = effectiveStepVisibility(exec.ReportVisibility, stepsByRef[stepRef].Visibility)
exec.UserLabel = firstNonEmpty(exec.UserLabel, stepsByRef[stepRef].UserLabel)
cloned := cloneStepExecution(exec)
@@ -158,6 +169,9 @@ func (s *svc) normalizeStepExecution(exec agg.StepExecution, index int) (agg.Ste
exec.FailureCode = strings.TrimSpace(exec.FailureCode)
exec.FailureMsg = strings.TrimSpace(exec.FailureMsg)
exec.UserLabel = strings.TrimSpace(exec.UserLabel)
exec.Gateway = strings.TrimSpace(exec.Gateway)
exec.InstanceID = strings.TrimSpace(exec.InstanceID)
exec.Rail = model.ParseRail(string(exec.Rail))
exec.ReportVisibility = model.NormalizeReportVisibility(exec.ReportVisibility)
exec.ExternalRefs = cloneExternalRefs(exec.ExternalRefs)
if exec.StepRef == "" {
@@ -197,6 +211,9 @@ func seedMissingExecutions(
executionsByRef[stepRef] = &agg.StepExecution{
StepRef: step.StepRef,
StepCode: step.StepCode,
Rail: step.Rail,
Gateway: strings.TrimSpace(step.Gateway),
InstanceID: strings.TrimSpace(step.InstanceID),
ReportVisibility: effectiveStepVisibility(model.ReportVisibilityUnspecified, step.Visibility),
UserLabel: strings.TrimSpace(step.UserLabel),
State: agg.StepStatePending,