package papitemplate import ( "context" api "github.com/tech/sendico/pkg/api/http" notifications "github.com/tech/sendico/pkg/messaging/envelope" "github.com/tech/sendico/pkg/mlogger" model "github.com/tech/sendico/pkg/model/notification" "github.com/tech/sendico/pkg/mservice" eapi "github.com/tech/sendico/server/interface/api" "github.com/tech/sendico/server/interface/api/sresponse" mutil "github.com/tech/sendico/server/internal/mutil/param" "go.mongodb.org/mongo-driver/v2/bson" "go.uber.org/zap" ) type ProtectedAPI[T any] struct { Logger mlogger.Logger DB ProtectedDB[T] Oph mutil.ParamHelper // org param handler Pph mutil.ParamHelper // parent object param handler Cph mutil.ParamHelper // child object param handler resource mservice.Type a eapi.API config *PAPIConfig nconfig *NotificationConfig[*T] } func (a *ProtectedAPI[_]) Name() mservice.Type { return a.resource } func (_ *ProtectedAPI[_]) Finish(_ context.Context) error { return nil } func (a *ProtectedAPI[T]) Build() *ProtectedAPI[T] { createHandler := a.config.CreateResolver(a.create) if createHandler != nil { a.a.Register().AccountHandler(a.Name(), a.Oph.AddRef("/"), api.Post, createHandler) } listHandler := a.config.ListResolver(a.list) if listHandler != nil { a.a.Register().AccountHandler(a.Name(), a.Pph.AddRef(a.Oph.AddRef("/list")), api.Get, listHandler) } getHandler := a.config.GetResolver(a.get) if getHandler != nil { a.a.Register().AccountHandler(a.Name(), a.Cph.AddRef("/"), api.Get, getHandler) } updateHandler := a.config.UpdateResolver(a.update) if updateHandler != nil { a.a.Register().AccountHandler(a.Name(), "/", api.Put, updateHandler) } deleteHandler := a.config.DeleteResolver(a.delete) if deleteHandler != nil { a.a.Register().AccountHandler(a.Name(), a.Cph.AddRef("/"), api.Delete, deleteHandler) } archiveHandler := a.config.ArchiveResolver(a.archive) if archiveHandler != nil { a.a.Register().AccountHandler(a.Name(), a.Cph.AddRef(a.Oph.AddRef("/archive")), api.Get, archiveHandler) } if a.config.Reorder != nil { a.a.Register().AccountHandler(a.Name(), "/reorder", api.Post, a.reorder) } if a.config.Taggable != nil { a.a.Register().AccountHandler(a.Name(), "/tags/add", api.Put, a.addTag) a.a.Register().AccountHandler(a.Name(), "/tags/add", api.Post, a.addTags) a.a.Register().AccountHandler(a.Name(), "/tags", api.Delete, a.removeTag) a.a.Register().AccountHandler(a.Name(), "/tags/all", api.Delete, a.removeAllTags) a.a.Register().AccountHandler(a.Name(), "/tags/set", api.Post, a.setTags) a.a.Register().AccountHandler(a.Name(), "/tags", api.Get, a.getTags) } return a } func (a *ProtectedAPI[T]) WithNotifications(factory func(template *T, actorAccountRef bson.ObjectID, t model.NotificationAction) notifications.Envelope) *ProtectedAPI[T] { a.nconfig.WithNotifications(factory) a.Logger.Info("Notificatons handler installed") return a } // WithNoCreateNotification disables the create notification. func (a *ProtectedAPI[T]) WithNoCreateNotification() *ProtectedAPI[T] { a.nconfig.WithNoCreateNotification() a.Logger.Info("Object creation notificaton disabled") return a } // WithNoUpdateNotification disables the update notification. func (a *ProtectedAPI[T]) WithNoUpdateNotification() *ProtectedAPI[T] { a.nconfig.WithNoUpdateNotification() a.Logger.Info("Object update notificaton disabled") return a } // WithNoDeleteNotification disables the delete notification. func (a *ProtectedAPI[T]) WithNoDeleteNotification() *ProtectedAPI[T] { a.nconfig.WithNoDeleteNotification() a.Logger.Info("Object deletion notificaton disabled") return a } func (a *ProtectedAPI[T]) WithNoCreate() *ProtectedAPI[T] { a.config.WithNoCreate() a.Logger.Info("Create handler disabled") return a } func (a *ProtectedAPI[T]) WithCreateHandler(handler sresponse.AccountHandlerFunc) *ProtectedAPI[T] { a.config.WithCreateHandler(handler) a.Logger.Info("Create handler overridden") return a } func (a *ProtectedAPI[T]) WithNoList() *ProtectedAPI[T] { a.config.WithNoList() a.Logger.Info("List handler disabled") return a } func (a *ProtectedAPI[T]) WithListHandler(handler sresponse.AccountHandlerFunc) *ProtectedAPI[T] { a.config.WithListHandler(handler) a.Logger.Info("List handler overridden") return a } func (a *ProtectedAPI[T]) WithNoGet() *ProtectedAPI[T] { a.config.WithNoGet() a.Logger.Info("Get handler disabled") return a } func (a *ProtectedAPI[T]) WithGetHandler(handler sresponse.AccountHandlerFunc) *ProtectedAPI[T] { a.config.WithGetHandler(handler) a.Logger.Info("Get handler overridden") return a } func (a *ProtectedAPI[T]) WithReorderHandler(reorder ReorderConfig) *ProtectedAPI[T] { a.config.WithReorderHandler(reorder) a.Logger.Info("Reorder handler installed") return a } func (a *ProtectedAPI[T]) WithTaggableHandler(taggable TaggableConfig) *ProtectedAPI[T] { a.config.WithTaggableHandler(taggable) a.Logger.Info("Taggable handlers installed") return a } func (a *ProtectedAPI[T]) WithNoUpdate() *ProtectedAPI[T] { a.config.WithNoUpdate() a.Logger.Info("Update handler disabled") return a } func (a *ProtectedAPI[T]) WithUpdateHandler(handler sresponse.AccountHandlerFunc) *ProtectedAPI[T] { a.config.WithUpdateHandler(handler) a.Logger.Info("Update handler overridden") return a } func (a *ProtectedAPI[T]) WithNoDelete() *ProtectedAPI[T] { a.config.WithNoDelete() a.Logger.Info("Delete handler disabled") return a } func (a *ProtectedAPI[T]) WithDeleteHandler(handler sresponse.AccountHandlerFunc) *ProtectedAPI[T] { a.config.WithDeleteHandler(handler) a.Logger.Info("Delete handler overriden") return a } func CreateAPI[T any](a eapi.API, dbFactory func() (ProtectedDB[T], error), parent, resource mservice.Type) (*ProtectedAPI[T], error) { p := &ProtectedAPI[T]{ Logger: a.Logger().Named(resource), Oph: mutil.CreatePH("org"), // to avoid collision with organizaitons_ref when Pph: mutil.CreatePH(parent), resource: resource, Cph: mutil.CreatePH(resource), a: a, config: NewConfig(), nconfig: NewNotificationConfig[*T](a.Register().Messaging().Producer()), } var err error if p.DB, err = dbFactory(); err != nil { p.Logger.Error("Failed to create protected database", zap.Error(err)) return nil, err } return p, nil }