cached gateway routing

This commit is contained in:
Stephan D
2026-02-20 15:38:22 +01:00
parent bc2bc3770d
commit 671ccc55a0
23 changed files with 777 additions and 23 deletions

View File

@@ -0,0 +1,111 @@
package chainwalletroutesdb
import (
"context"
"errors"
"github.com/tech/sendico/pkg/db/repository"
ri "github.com/tech/sendico/pkg/db/repository/index"
"github.com/tech/sendico/pkg/db/template"
"github.com/tech/sendico/pkg/merrors"
"github.com/tech/sendico/pkg/mlogger"
"github.com/tech/sendico/pkg/model"
"github.com/tech/sendico/pkg/mservice"
"go.mongodb.org/mongo-driver/v2/mongo"
"go.uber.org/zap"
)
type ChainWalletRoutesDB struct {
template.DBImp[*model.ChainWalletRoute]
}
func Create(logger mlogger.Logger, db *mongo.Database) (*ChainWalletRoutesDB, error) {
p := &ChainWalletRoutesDB{
DBImp: *template.Create[*model.ChainWalletRoute](logger, mservice.WalletRoutes, db),
}
if err := p.Repository.CreateIndex(&ri.Definition{
Name: "idx_org_wallet_unique",
Unique: true,
Keys: []ri.Key{
{Field: "organizationRef", Sort: ri.Asc},
{Field: "walletRef", Sort: ri.Asc},
},
}); err != nil {
p.Logger.Error("Failed to create unique organization/wallet route index", zap.Error(err))
return nil, err
}
if err := p.Repository.CreateIndex(&ri.Definition{
Name: "idx_wallet_ref",
Keys: []ri.Key{
{Field: "walletRef", Sort: ri.Asc},
},
}); err != nil {
p.Logger.Error("Failed to create wallet route lookup index", zap.Error(err))
return nil, err
}
return p, nil
}
func (db *ChainWalletRoutesDB) Get(ctx context.Context, organizationRef string, walletRef string) (*model.ChainWalletRoute, error) {
org := model.ChainWalletRoute{OrganizationRef: organizationRef, WalletRef: walletRef}
org.Normalize()
if org.OrganizationRef == "" || org.WalletRef == "" {
return nil, merrors.InvalidArgument("wallet route requires organizationRef and walletRef")
}
var route model.ChainWalletRoute
query := repository.Query().
Filter(repository.Field("organizationRef"), org.OrganizationRef).
Filter(repository.Field("walletRef"), org.WalletRef)
return &route, db.FindOne(ctx, query, &route)
}
func (db *ChainWalletRoutesDB) Upsert(ctx context.Context, route *model.ChainWalletRoute) error {
if route == nil {
return merrors.InvalidArgument("wallet route is nil")
}
route.Normalize()
if route.OrganizationRef == "" || route.WalletRef == "" {
return merrors.InvalidArgument("wallet route requires organizationRef and walletRef")
}
if route.Network == "" && route.GatewayID == "" {
return merrors.InvalidArgument("wallet route requires network or gatewayId")
}
existing, err := db.Get(ctx, route.OrganizationRef, route.WalletRef)
if err != nil {
if !errors.Is(err, merrors.ErrNoData) {
return err
}
if createErr := db.Create(ctx, route); createErr != nil {
if errors.Is(createErr, merrors.ErrDataConflict) {
existing, err = db.Get(ctx, route.OrganizationRef, route.WalletRef)
if err != nil {
return err
}
} else {
return createErr
}
} else {
return nil
}
}
changed := false
if route.Network != "" && existing.Network != route.Network {
existing.Network = route.Network
changed = true
}
if route.GatewayID != "" && existing.GatewayID != route.GatewayID {
existing.GatewayID = route.GatewayID
changed = true
}
if !changed {
return nil
}
return db.Update(ctx, existing)
}