Treasury bot + ledger fix
This commit is contained in:
@@ -3,11 +3,11 @@ package store
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/tech/sendico/ledger/storage"
|
||||
"github.com/tech/sendico/pkg/db/repository"
|
||||
"github.com/tech/sendico/pkg/db/repository/builder"
|
||||
ri "github.com/tech/sendico/pkg/db/repository/index"
|
||||
"github.com/tech/sendico/pkg/merrors"
|
||||
"github.com/tech/sendico/pkg/mlogger"
|
||||
@@ -26,10 +26,27 @@ type accountsStore struct {
|
||||
}
|
||||
|
||||
const (
|
||||
orgCurrencyRoleNonOperatingIndex = "org_currency_role_non_operating_unique"
|
||||
orgCurrencyRoleNonOperatingPrefix = "org_currency_role_non_operating_unique"
|
||||
orgCurrencyRoleSystemOperatingName = "org_currency_role_system_operating_unique"
|
||||
)
|
||||
|
||||
var nonOperatingUniqueRoles = []account_role.AccountRole{
|
||||
account_role.AccountRoleHold,
|
||||
account_role.AccountRoleTransit,
|
||||
account_role.AccountRoleSettlement,
|
||||
account_role.AccountRoleClearing,
|
||||
account_role.AccountRolePending,
|
||||
account_role.AccountRoleReserve,
|
||||
account_role.AccountRoleLiquidity,
|
||||
account_role.AccountRoleFee,
|
||||
account_role.AccountRoleChargeback,
|
||||
account_role.AccountRoleAdjustment,
|
||||
}
|
||||
|
||||
func nonOperatingRoleIndexName(role account_role.AccountRole) string {
|
||||
return fmt.Sprintf("%s_%s", orgCurrencyRoleNonOperatingPrefix, role)
|
||||
}
|
||||
|
||||
func NewAccounts(logger mlogger.Logger, db *mongo.Database) (storage.AccountsStore, error) {
|
||||
repo := repository.CreateMongoRepository(db, mservice.LedgerAccounts)
|
||||
|
||||
@@ -48,21 +65,25 @@ func NewAccounts(logger mlogger.Logger, db *mongo.Database) (storage.AccountsSto
|
||||
}
|
||||
|
||||
// Keep role uniqueness for non-operating organization accounts.
|
||||
roleIndex := &ri.Definition{
|
||||
Keys: []ri.Key{
|
||||
{Field: "organizationRef", Sort: ri.Asc},
|
||||
{Field: "currency", Sort: ri.Asc},
|
||||
{Field: "role", Sort: ri.Asc},
|
||||
},
|
||||
Unique: true,
|
||||
Name: orgCurrencyRoleNonOperatingIndex,
|
||||
PartialFilter: repository.Query().
|
||||
Filter(repository.Field("scope"), pkm.LedgerAccountScopeOrganization).
|
||||
Comparison(repository.Field("role"), builder.Ne, account_role.AccountRoleOperating),
|
||||
}
|
||||
if err := repo.CreateIndex(roleIndex); err != nil {
|
||||
logger.Error("Failed to ensure accounts role index", zap.Error(err))
|
||||
return nil, err
|
||||
// Some Mongo-compatible backends reject partial filters that use negation ($ne/$not).
|
||||
// Build one equality-based partial index per non-operating role for compatibility.
|
||||
for _, role := range nonOperatingUniqueRoles {
|
||||
roleIndex := &ri.Definition{
|
||||
Keys: []ri.Key{
|
||||
{Field: "organizationRef", Sort: ri.Asc},
|
||||
{Field: "currency", Sort: ri.Asc},
|
||||
{Field: "role", Sort: ri.Asc},
|
||||
},
|
||||
Unique: true,
|
||||
Name: nonOperatingRoleIndexName(role),
|
||||
PartialFilter: repository.Query().
|
||||
Filter(repository.Field("scope"), pkm.LedgerAccountScopeOrganization).
|
||||
Filter(repository.Field("role"), role),
|
||||
}
|
||||
if err := repo.CreateIndex(roleIndex); err != nil {
|
||||
logger.Error("Failed to ensure accounts role index", zap.String("role", string(role)), zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure only one system-tagged operating role per organization/currency.
|
||||
|
||||
Reference in New Issue
Block a user