bff for callbacks

This commit is contained in:
Stephan D
2026-03-01 02:04:15 +01:00
parent 709df51512
commit 86eab3bb70
44 changed files with 1563 additions and 25 deletions

View File

@@ -0,0 +1,15 @@
package callbacks
import (
"context"
"github.com/tech/sendico/pkg/auth"
"github.com/tech/sendico/pkg/model"
"go.mongodb.org/mongo-driver/v2/bson"
)
type DB interface {
auth.ProtectedDB[*model.Callback]
SetArchived(ctx context.Context, accountRef, organizationRef, callbackRef bson.ObjectID, archived, cascade bool) error
List(ctx context.Context, accountRef, organizationRef, _ bson.ObjectID, cursor *model.ViewCursor) ([]model.Callback, error)
}

View File

@@ -3,6 +3,7 @@ package db
import (
"github.com/tech/sendico/pkg/auth"
"github.com/tech/sendico/pkg/db/account"
"github.com/tech/sendico/pkg/db/callbacks"
"github.com/tech/sendico/pkg/db/chainassets"
"github.com/tech/sendico/pkg/db/chainwalletroutes"
mongoimpl "github.com/tech/sendico/pkg/db/internal/mongo"
@@ -29,6 +30,7 @@ type Factory interface {
NewOrganizationDB() (organization.DB, error)
NewInvitationsDB() (invitation.DB, error)
NewRecipientsDB() (recipient.DB, error)
NewCallbacksDB() (callbacks.DB, error)
NewVerificationsDB() (verification.DB, error)
NewRolesDB() (role.DB, error)

View File

@@ -0,0 +1,30 @@
package callbacksdb
import (
"context"
"github.com/tech/sendico/pkg/mutil/mzap"
"go.mongodb.org/mongo-driver/v2/bson"
"go.uber.org/zap"
)
func (db *CallbacksDB) SetArchived(
ctx context.Context,
accountRef,
organizationRef,
callbackRef bson.ObjectID,
isArchived,
cascade bool,
) error {
if err := db.ArchivableDB.SetArchived(ctx, accountRef, callbackRef, isArchived); err != nil {
db.DBImp.Logger.Warn("Failed to change callback archive status", zap.Error(err),
mzap.AccRef(accountRef),
mzap.ObjRef("organization_ref", organizationRef),
mzap.ObjRef("callback_ref", callbackRef),
zap.Bool("archived", isArchived),
zap.Bool("cascade", cascade),
)
return err
}
return nil
}

View File

@@ -0,0 +1,112 @@
package callbacksdb
import (
"context"
"errors"
"github.com/tech/sendico/pkg/auth"
"github.com/tech/sendico/pkg/db/callbacks"
"github.com/tech/sendico/pkg/db/policy"
ri "github.com/tech/sendico/pkg/db/repository/index"
"github.com/tech/sendico/pkg/db/storable"
"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 CallbacksDB struct {
auth.ProtectedDBImp[*model.Callback]
auth.ArchivableDB[*model.Callback]
}
func Create(
ctx context.Context,
logger mlogger.Logger,
enforcer auth.Enforcer,
pdb policy.DB,
db *mongo.Database,
) (*CallbacksDB, error) {
if err := ensureBuiltInPolicy(ctx, logger, pdb); err != nil {
return nil, err
}
p, err := auth.CreateDBImp[*model.Callback](ctx, logger, pdb, enforcer, mservice.Callbacks, db)
if err != nil {
return nil, err
}
for _, definition := range []*ri.Definition{
{
Name: "uq_callbacks_client_url",
Keys: []ri.Key{
{Field: storable.OrganizationRefField, Sort: ri.Asc},
{Field: "client_id", Sort: ri.Asc},
{Field: "url", Sort: ri.Asc},
},
Unique: true,
},
{
Name: "idx_callbacks_lookup",
Keys: []ri.Key{
{Field: storable.OrganizationRefField, Sort: ri.Asc},
{Field: "status", Sort: ri.Asc},
{Field: "event_types", Sort: ri.Asc},
},
},
} {
if err := p.DBImp.Repository.CreateIndex(definition); err != nil {
p.DBImp.Logger.Warn("Failed to create callbacks index", zap.String("index", definition.Name), zap.Error(err))
return nil, err
}
}
createEmpty := func() *model.Callback {
return &model.Callback{}
}
getArchivable := func(callback *model.Callback) model.Archivable {
return &callback.ArchivableBase
}
return &CallbacksDB{
ProtectedDBImp: *p,
ArchivableDB: auth.NewArchivableDB(
p.DBImp,
p.DBImp.Logger,
enforcer,
createEmpty,
getArchivable,
),
}, nil
}
func ensureBuiltInPolicy(ctx context.Context, logger mlogger.Logger, pdb policy.DB) error {
var existing model.PolicyDescription
if err := pdb.GetBuiltInPolicy(ctx, mservice.Callbacks, &existing); err == nil {
return nil
} else if !errors.Is(err, merrors.ErrNoData) {
return err
}
description := "Callbacks subscription management"
resourceTypes := []mservice.Type{mservice.Callbacks}
policyDescription := &model.PolicyDescription{
Describable: model.Describable{
Name: "Callbacks",
Description: &description,
},
ResourceTypes: &resourceTypes,
}
if err := pdb.Create(ctx, policyDescription); err != nil && !errors.Is(err, merrors.ErrDataConflict) {
if logger != nil {
logger.Warn("Failed to create built-in callbacks policy", zap.Error(err))
}
return err
}
return pdb.GetBuiltInPolicy(ctx, mservice.Callbacks, &existing)
}
var _ callbacks.DB = (*CallbacksDB)(nil)

View File

@@ -0,0 +1,36 @@
package callbacksdb
import (
"context"
"errors"
"github.com/tech/sendico/pkg/db/repository"
"github.com/tech/sendico/pkg/merrors"
"github.com/tech/sendico/pkg/model"
mauth "github.com/tech/sendico/pkg/mutil/db/auth"
"go.mongodb.org/mongo-driver/v2/bson"
)
func (db *CallbacksDB) List(
ctx context.Context,
accountRef,
organizationRef,
_ bson.ObjectID,
cursor *model.ViewCursor,
) ([]model.Callback, error) {
res, err := mauth.GetProtectedObjects[model.Callback](
ctx,
db.DBImp.Logger,
accountRef,
organizationRef,
model.ActionRead,
repository.OrgFilter(organizationRef),
cursor,
db.Enforcer,
db.DBImp.Repository,
)
if errors.Is(err, merrors.ErrNoData) {
return []model.Callback{}, nil
}
return res, err
}

View File

@@ -10,9 +10,11 @@ import (
"github.com/mitchellh/mapstructure"
"github.com/tech/sendico/pkg/auth"
"github.com/tech/sendico/pkg/db/account"
"github.com/tech/sendico/pkg/db/callbacks"
"github.com/tech/sendico/pkg/db/chainassets"
"github.com/tech/sendico/pkg/db/chainwalletroutes"
"github.com/tech/sendico/pkg/db/internal/mongo/accountdb"
"github.com/tech/sendico/pkg/db/internal/mongo/callbacksdb"
"github.com/tech/sendico/pkg/db/internal/mongo/chainassetsdb"
"github.com/tech/sendico/pkg/db/internal/mongo/chainwalletroutesdb"
"github.com/tech/sendico/pkg/db/internal/mongo/invitationdb"
@@ -218,6 +220,10 @@ func (db *DB) NewRecipientsDB() (recipient.DB, error) {
return newProtectedDB(db, create)
}
func (db *DB) NewCallbacksDB() (callbacks.DB, error) {
return newProtectedDB(db, callbacksdb.Create)
}
func (db *DB) NewRefreshTokensDB() (refreshtokens.DB, error) {
return refreshtokensdb.Create(db.logger, db.db())
}