fixed doc env vars + mongo v2 migration

This commit is contained in:
Stephan D
2026-01-31 00:26:42 +01:00
parent cbb7bd8ba6
commit 1aa7e287fb
356 changed files with 1705 additions and 1729 deletions

View File

@@ -10,12 +10,12 @@ import (
"github.com/tech/sendico/billing/fees/storage/model"
"github.com/tech/sendico/pkg/merrors"
"github.com/tech/sendico/pkg/mutil/mzap"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/v2/bson"
"go.uber.org/zap"
)
type planFinder interface {
FindActiveOrgPlan(ctx context.Context, orgRef primitive.ObjectID, at time.Time) (*model.FeePlan, error)
FindActiveOrgPlan(ctx context.Context, orgRef bson.ObjectID, at time.Time) (*model.FeePlan, error)
FindActiveGlobalPlan(ctx context.Context, at time.Time) (*model.FeePlan, error)
}
@@ -40,7 +40,7 @@ func New(plans storage.PlansStore, logger *zap.Logger) *feeResolver {
}
}
func (r *feeResolver) ResolveFeeRule(ctx context.Context, orgRef *primitive.ObjectID, trigger model.Trigger, at time.Time, attrs map[string]string) (*model.FeePlan, *model.FeeRule, error) {
func (r *feeResolver) ResolveFeeRule(ctx context.Context, orgRef *bson.ObjectID, trigger model.Trigger, at time.Time, attrs map[string]string) (*model.FeePlan, *model.FeeRule, error) {
if r.plans == nil {
return nil, nil, merrors.InvalidArgument("fees: plans store is required")
}
@@ -117,7 +117,7 @@ func (r *feeResolver) ResolveFeeRule(ctx context.Context, orgRef *primitive.Obje
return plan, rule, nil
}
func (r *feeResolver) getOrgPlan(ctx context.Context, orgRef primitive.ObjectID, at time.Time) (*model.FeePlan, error) {
func (r *feeResolver) getOrgPlan(ctx context.Context, orgRef bson.ObjectID, at time.Time) (*model.FeePlan, error) {
if r.finder != nil {
return r.finder.FindActiveOrgPlan(ctx, orgRef, at)
}
@@ -129,7 +129,7 @@ func (r *feeResolver) getGlobalPlan(ctx context.Context, at time.Time) (*model.F
return r.finder.FindActiveGlobalPlan(ctx, at)
}
// Treat zero ObjectID as global in legacy path.
return r.plans.GetActivePlan(ctx, primitive.NilObjectID, at)
return r.plans.GetActivePlan(ctx, bson.NilObjectID, at)
}
func selectRule(plan *model.FeePlan, trigger model.Trigger, at time.Time, attrs map[string]string) (*model.FeeRule, error) {

View File

@@ -8,7 +8,7 @@ import (
"github.com/tech/sendico/billing/fees/storage"
"github.com/tech/sendico/billing/fees/storage/model"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/v2/bson"
"go.uber.org/zap"
)
@@ -27,7 +27,7 @@ func TestResolver_GlobalFallbackWhenOrgMissing(t *testing.T) {
store := &memoryPlansStore{plans: []*model.FeePlan{globalPlan}}
resolver := New(store, zap.NewNop())
orgA := primitive.NewObjectID()
orgA := bson.NewObjectID()
plan, rule, err := resolver.ResolveFeeRule(context.Background(), &orgA, model.TriggerCapture, now, nil)
if err != nil {
t.Fatalf("expected fallback to global, got error: %v", err)
@@ -44,7 +44,7 @@ func TestResolver_OrgOverridesGlobal(t *testing.T) {
t.Helper()
now := time.Now()
org := primitive.NewObjectID()
org := bson.NewObjectID()
globalPlan := &model.FeePlan{
Active: true,
EffectiveFrom: now.Add(-time.Hour),
@@ -71,7 +71,7 @@ func TestResolver_OrgOverridesGlobal(t *testing.T) {
t.Fatalf("expected org rule, got %s", rule.RuleID)
}
otherOrg := primitive.NewObjectID()
otherOrg := bson.NewObjectID()
_, rule, err = resolver.ResolveFeeRule(context.Background(), &otherOrg, model.TriggerCapture, now, nil)
if err != nil {
t.Fatalf("expected global fallback for other org, got error: %v", err)
@@ -85,7 +85,7 @@ func TestResolver_SelectsHighestPriority(t *testing.T) {
t.Helper()
now := time.Now()
org := primitive.NewObjectID()
org := bson.NewObjectID()
plan := &model.FeePlan{
Active: true,
EffectiveFrom: now.Add(-time.Hour),
@@ -124,7 +124,7 @@ func TestResolver_EffectiveDateFiltering(t *testing.T) {
t.Helper()
now := time.Now()
org := primitive.NewObjectID()
org := bson.NewObjectID()
past := now.Add(-24 * time.Hour)
future := now.Add(24 * time.Hour)
@@ -253,7 +253,7 @@ func TestResolver_MultipleActivePlansConflict(t *testing.T) {
t.Helper()
now := time.Now()
org := primitive.NewObjectID()
org := bson.NewObjectID()
p1 := &model.FeePlan{
Active: true,
EffectiveFrom: now.Add(-time.Hour),
@@ -285,11 +285,11 @@ type memoryPlansStore struct {
func (m *memoryPlansStore) Create(context.Context, *model.FeePlan) error { return nil }
func (m *memoryPlansStore) Update(context.Context, *model.FeePlan) error { return nil }
func (m *memoryPlansStore) Get(context.Context, primitive.ObjectID) (*model.FeePlan, error) {
func (m *memoryPlansStore) Get(context.Context, bson.ObjectID) (*model.FeePlan, error) {
return nil, storage.ErrFeePlanNotFound
}
func (m *memoryPlansStore) GetActivePlan(ctx context.Context, orgRef primitive.ObjectID, at time.Time) (*model.FeePlan, error) {
func (m *memoryPlansStore) GetActivePlan(ctx context.Context, orgRef bson.ObjectID, at time.Time) (*model.FeePlan, error) {
if !orgRef.IsZero() {
if plan, err := m.FindActiveOrgPlan(ctx, orgRef, at); err == nil {
return plan, nil
@@ -300,7 +300,7 @@ func (m *memoryPlansStore) GetActivePlan(ctx context.Context, orgRef primitive.O
return m.FindActiveGlobalPlan(ctx, at)
}
func (m *memoryPlansStore) FindActiveOrgPlan(_ context.Context, orgRef primitive.ObjectID, at time.Time) (*model.FeePlan, error) {
func (m *memoryPlansStore) FindActiveOrgPlan(_ context.Context, orgRef bson.ObjectID, at time.Time) (*model.FeePlan, error) {
var matches []*model.FeePlan
for _, plan := range m.plans {
if plan == nil || plan.OrganizationRef == nil || plan.OrganizationRef.IsZero() || (*plan.OrganizationRef != orgRef) {

View File

@@ -5,11 +5,11 @@ import (
"time"
"github.com/tech/sendico/billing/fees/storage/model"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/v2/bson"
)
// FeeResolver centralises plan/rule resolution with org override and global fallback.
// Implementations live under the internal/resolver package.
type FeeResolver interface {
ResolveFeeRule(ctx context.Context, orgID *primitive.ObjectID, trigger model.Trigger, at time.Time, attrs map[string]string) (*model.FeePlan, *model.FeeRule, error)
ResolveFeeRule(ctx context.Context, orgID *bson.ObjectID, trigger model.Trigger, at time.Time, attrs map[string]string) (*model.FeePlan, *model.FeeRule, error)
}

View File

@@ -24,7 +24,7 @@ import (
"github.com/tech/sendico/pkg/mservice"
feesv1 "github.com/tech/sendico/pkg/proto/billing/fees/v1"
tracev1 "github.com/tech/sendico/pkg/proto/common/trace/v1"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/v2/bson"
"go.uber.org/zap"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
@@ -151,7 +151,7 @@ func (s *Service) QuoteFees(ctx context.Context, req *feesv1.QuoteFeesRequest) (
return nil, err
}
orgRef, parseErr := primitive.ObjectIDFromHex(req.GetMeta().GetOrganizationRef())
orgRef, parseErr := bson.ObjectIDFromHex(req.GetMeta().GetOrganizationRef())
if parseErr != nil {
logger.Warn("QuoteFees invalid organization_ref", zap.Error(parseErr))
err = status.Error(codes.InvalidArgument, "invalid organization_ref")
@@ -233,7 +233,7 @@ func (s *Service) PrecomputeFees(ctx context.Context, req *feesv1.PrecomputeFees
now := s.clock.Now()
orgRef, parseErr := primitive.ObjectIDFromHex(req.GetMeta().GetOrganizationRef())
orgRef, parseErr := bson.ObjectIDFromHex(req.GetMeta().GetOrganizationRef())
if parseErr != nil {
logger.Warn("PrecomputeFees invalid organization_ref", zap.Error(parseErr))
err = status.Error(codes.InvalidArgument, "invalid organization_ref")
@@ -351,7 +351,7 @@ func (s *Service) ValidateFeeToken(ctx context.Context, req *feesv1.ValidateFeeT
return resp, nil
}
orgRef, parseErr := primitive.ObjectIDFromHex(payload.OrganizationRef)
orgRef, parseErr := bson.ObjectIDFromHex(payload.OrganizationRef)
if parseErr != nil {
resultReason = "invalid_token"
logger.Warn("token contained invalid organization reference", zap.Error(parseErr))
@@ -408,11 +408,11 @@ func (s *Service) validatePrecomputeRequest(req *feesv1.PrecomputeFeesRequest) e
return s.validateQuoteRequest(&feesv1.QuoteFeesRequest{Meta: req.GetMeta(), Intent: req.GetIntent()})
}
func (s *Service) computeQuote(ctx context.Context, orgRef primitive.ObjectID, intent *feesv1.Intent, overrides *feesv1.PolicyOverrides, trace *tracev1.TraceContext) ([]*feesv1.DerivedPostingLine, []*feesv1.AppliedRule, *feesv1.FXUsed, error) {
func (s *Service) computeQuote(ctx context.Context, orgRef bson.ObjectID, intent *feesv1.Intent, overrides *feesv1.PolicyOverrides, trace *tracev1.TraceContext) ([]*feesv1.DerivedPostingLine, []*feesv1.AppliedRule, *feesv1.FXUsed, error) {
return s.computeQuoteWithTime(ctx, orgRef, intent, overrides, trace, s.clock.Now())
}
func (s *Service) computeQuoteWithTime(ctx context.Context, orgRef primitive.ObjectID, intent *feesv1.Intent, _ *feesv1.PolicyOverrides, trace *tracev1.TraceContext, now time.Time) ([]*feesv1.DerivedPostingLine, []*feesv1.AppliedRule, *feesv1.FXUsed, error) {
func (s *Service) computeQuoteWithTime(ctx context.Context, orgRef bson.ObjectID, intent *feesv1.Intent, _ *feesv1.PolicyOverrides, trace *tracev1.TraceContext, now time.Time) ([]*feesv1.DerivedPostingLine, []*feesv1.AppliedRule, *feesv1.FXUsed, error) {
bookedAt := now
if intent.GetBookedAt() != nil && intent.GetBookedAt().IsValid() {
bookedAt = intent.GetBookedAt().AsTime()
@@ -428,7 +428,7 @@ func (s *Service) computeQuoteWithTime(ctx context.Context, orgRef primitive.Obj
logFields = append(logFields, logFieldsFromTrace(trace)...)
logger := s.logger.With(logFields...)
var orgPtr *primitive.ObjectID
var orgPtr *bson.ObjectID
if !orgRef.IsZero() {
orgPtr = &orgRef
}

View File

@@ -14,7 +14,7 @@ import (
feesv1 "github.com/tech/sendico/pkg/proto/billing/fees/v1"
moneyv1 "github.com/tech/sendico/pkg/proto/common/money/v1"
tracev1 "github.com/tech/sendico/pkg/proto/common/trace/v1"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/v2/bson"
"go.uber.org/zap"
"google.golang.org/protobuf/types/known/timestamppb"
)
@@ -23,7 +23,7 @@ func TestQuoteFees_ComputesDerivedLines(t *testing.T) {
t.Helper()
now := time.Date(2024, 1, 10, 16, 0, 0, 0, time.UTC)
orgRef := primitive.NewObjectID()
orgRef := bson.NewObjectID()
plan := &model.FeePlan{
Active: true,
@@ -48,7 +48,7 @@ func TestQuoteFees_ComputesDerivedLines(t *testing.T) {
},
},
}
plan.SetID(primitive.NewObjectID())
plan.SetID(bson.NewObjectID())
plan.OrganizationRef = &orgRef
service := NewService(
@@ -123,7 +123,7 @@ func TestQuoteFees_FiltersByAttributesAndDates(t *testing.T) {
t.Helper()
now := time.Date(2024, 5, 20, 9, 30, 0, 0, time.UTC)
orgRef := primitive.NewObjectID()
orgRef := bson.NewObjectID()
plan := &model.FeePlan{
Active: true,
@@ -162,7 +162,7 @@ func TestQuoteFees_FiltersByAttributesAndDates(t *testing.T) {
},
},
}
plan.SetID(primitive.NewObjectID())
plan.SetID(bson.NewObjectID())
plan.OrganizationRef = &orgRef
service := NewService(
@@ -205,7 +205,7 @@ func TestQuoteFees_RoundingDown(t *testing.T) {
t.Helper()
now := time.Date(2024, 3, 15, 12, 0, 0, 0, time.UTC)
orgRef := primitive.NewObjectID()
orgRef := bson.NewObjectID()
plan := &model.FeePlan{
Active: true,
@@ -223,7 +223,7 @@ func TestQuoteFees_RoundingDown(t *testing.T) {
},
},
}
plan.SetID(primitive.NewObjectID())
plan.SetID(bson.NewObjectID())
plan.OrganizationRef = &orgRef
service := NewService(
@@ -261,7 +261,7 @@ func TestQuoteFees_UsesInjectedCalculator(t *testing.T) {
t.Helper()
now := time.Date(2024, 6, 1, 8, 0, 0, 0, time.UTC)
orgRef := primitive.NewObjectID()
orgRef := bson.NewObjectID()
plan := &model.FeePlan{
Active: true,
EffectiveFrom: now.Add(-time.Hour),
@@ -276,7 +276,7 @@ func TestQuoteFees_UsesInjectedCalculator(t *testing.T) {
},
},
}
plan.SetID(primitive.NewObjectID())
plan.SetID(bson.NewObjectID())
plan.OrganizationRef = &orgRef
result := &types.CalculationResult{
@@ -334,7 +334,7 @@ func TestQuoteFees_PopulatesFxUsed(t *testing.T) {
t.Helper()
now := time.Date(2024, 7, 1, 9, 30, 0, 0, time.UTC)
orgRef := primitive.NewObjectID()
orgRef := bson.NewObjectID()
plan := &model.FeePlan{
Active: true,
@@ -352,7 +352,7 @@ func TestQuoteFees_PopulatesFxUsed(t *testing.T) {
},
},
}
plan.SetID(primitive.NewObjectID())
plan.SetID(bson.NewObjectID())
plan.OrganizationRef = &orgRef
fakeOracle := &oracleclient.Fake{
@@ -433,11 +433,11 @@ func (s *stubPlansStore) Update(context.Context, *model.FeePlan) error {
return nil
}
func (s *stubPlansStore) Get(context.Context, primitive.ObjectID) (*model.FeePlan, error) {
func (s *stubPlansStore) Get(context.Context, bson.ObjectID) (*model.FeePlan, error) {
return nil, storage.ErrFeePlanNotFound
}
func (s *stubPlansStore) GetActivePlan(_ context.Context, orgRef primitive.ObjectID, at time.Time) (*model.FeePlan, error) {
func (s *stubPlansStore) GetActivePlan(_ context.Context, orgRef bson.ObjectID, at time.Time) (*model.FeePlan, error) {
if !orgRef.IsZero() {
if plan, err := s.FindActiveOrgPlan(context.Background(), orgRef, at); err == nil {
return plan, nil
@@ -448,7 +448,7 @@ func (s *stubPlansStore) GetActivePlan(_ context.Context, orgRef primitive.Objec
return s.FindActiveGlobalPlan(context.Background(), at)
}
func (s *stubPlansStore) FindActiveOrgPlan(_ context.Context, orgRef primitive.ObjectID, at time.Time) (*model.FeePlan, error) {
func (s *stubPlansStore) FindActiveOrgPlan(_ context.Context, orgRef bson.ObjectID, at time.Time) (*model.FeePlan, error) {
if s.plan == nil {
return nil, storage.ErrFeePlanNotFound
}