Skip to main content
Glama

Storyden

by Southclaws
Mozilla Public License 2.0
227
service.go5.08 kB
package category import ( "context" "github.com/Southclaws/fault" "github.com/Southclaws/fault/fctx" "github.com/Southclaws/fault/fmsg" "github.com/Southclaws/fault/ftag" "github.com/Southclaws/opt" "github.com/rs/xid" "go.uber.org/fx" "github.com/Southclaws/storyden/app/resources/account/account_querier" "github.com/Southclaws/storyden/app/resources/post/category" "github.com/Southclaws/storyden/internal/deletable" ) var errInvalidCategoryCreate = fault.New("invalid create args", ftag.With(ftag.InvalidArgument)) type Service interface { Create(ctx context.Context, partial Partial) (*category.Category, error) Update(ctx context.Context, slug string, partial Partial) (*category.Category, error) Move(ctx context.Context, slug string, move Move) ([]*category.Category, error) Delete(ctx context.Context, slug string, moveToID category.CategoryID) (*category.Category, error) } type Partial struct { Name opt.Optional[string] Slug opt.Optional[string] Description opt.Optional[string] Colour opt.Optional[string] Parent opt.Optional[category.CategoryID] CoverImageAssetID deletable.Value[*xid.ID] Meta opt.Optional[map[string]any] } type Move struct { Parent deletable.Value[category.CategoryID] Before opt.Optional[category.CategoryID] After opt.Optional[category.CategoryID] } func Build() fx.Option { return fx.Provide(New) } type service struct { accountQuery *account_querier.Querier category_repo *category.Repository } func New( accountQuery *account_querier.Querier, category_repo *category.Repository, ) Service { return &service{ accountQuery: accountQuery, category_repo: category_repo, } } func (s *service) Create(ctx context.Context, partial Partial) (*category.Category, error) { opts := []category.Option{} if v, ok := partial.Parent.Get(); ok { pid := v opts = append(opts, category.WithParent(&pid)) } if v, ok := partial.Slug.Get(); ok { opts = append(opts, category.WithSlug(v)) } coverImage, _ := partial.CoverImageAssetID.Get() if v, ok := coverImage.Get(); ok { opts = append(opts, category.WithCoverImageAssetID(v)) } if v, ok := partial.Meta.Get(); ok { opts = append(opts, category.WithMeta(v)) } name, ok := partial.Name.Get() if !ok { return nil, fault.Wrap(errInvalidCategoryCreate, fctx.With(ctx), fmsg.WithDesc("missing name", "Category name is required.")) } description, ok := partial.Description.Get() if !ok { return nil, fault.Wrap(errInvalidCategoryCreate, fctx.With(ctx), fmsg.WithDesc("missing description", "Category description is required.")) } colour, ok := partial.Colour.Get() if !ok { return nil, fault.Wrap(errInvalidCategoryCreate, fctx.With(ctx), fmsg.WithDesc("missing colour", "Category colour is required.")) } cat, err := s.category_repo.CreateCategory(ctx, name, description, colour, 0, false, opts...) if err != nil { return nil, fault.Wrap(err, fctx.With(ctx)) } return cat, nil } func (s *service) Update(ctx context.Context, slug string, partial Partial) (*category.Category, error) { opts := []category.Option{} if v, ok := partial.Name.Get(); ok { opts = append(opts, category.WithName(v)) } if v, ok := partial.Slug.Get(); ok { opts = append(opts, category.WithSlug(v)) } if v, ok := partial.Description.Get(); ok { opts = append(opts, category.WithDescription(v)) } if v, ok := partial.Colour.Get(); ok { opts = append(opts, category.WithColour(v)) } coverImageOpt, shouldDelete := partial.CoverImageAssetID.Get() if shouldDelete { opts = append(opts, category.WithCoverImageAssetID(nil)) } else if v, ok := coverImageOpt.Get(); ok { opts = append(opts, category.WithCoverImageAssetID(v)) } if v, ok := partial.Meta.Get(); ok { opts = append(opts, category.WithMeta(v)) } cat, err := s.category_repo.UpdateCategory(ctx, slug, opts...) if err != nil { return nil, fault.Wrap(err, fctx.With(ctx)) } return cat, nil } func (s *service) Move(ctx context.Context, slug string, move Move) ([]*category.Category, error) { parentOpt, deleteParent := move.Parent.Get() parentProvided := deleteParent var parentID *category.CategoryID if !deleteParent { if v, ok := parentOpt.Get(); ok { parentProvided = true pv := v parentID = &pv } } var beforeID *category.CategoryID if v, ok := move.Before.Get(); ok { pv := v beforeID = &pv } var afterID *category.CategoryID if v, ok := move.After.Get(); ok { pv := v afterID = &pv } cats, err := s.category_repo.MoveCategory(ctx, slug, category.MoveOptions{ ParentProvided: parentProvided, ParentID: parentID, Before: beforeID, After: afterID, }) if err != nil { return nil, fault.Wrap(err, fctx.With(ctx)) } return cats, nil } func (s *service) Delete(ctx context.Context, slug string, moveToID category.CategoryID) (*category.Category, error) { cat, err := s.category_repo.DeleteCategory(ctx, slug, moveToID) if err != nil { return nil, fault.Wrap(err, fctx.With(ctx)) } return cat, nil }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Southclaws/storyden'

If you have feedback or need assistance with the MCP directory API, please join our Discord server