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)