package cms import ( "context" "errors" "time" "tm/pkg/logger" orm "tm/pkg/mongo" "go.mongodb.org/mongo-driver/v2/bson" ) // Repository defines methods for CMS data access type Repository interface { Create(ctx context.Context, cms *CMS) error Update(ctx context.Context, cms *CMS) error Delete(ctx context.Context, id string) error GetByID(ctx context.Context, id string) (*CMS, error) GetByKey(ctx context.Context, key string) (*CMS, error) Search(ctx context.Context, search *SearchCMSForm, pagination orm.Pagination) (*orm.PaginatedResult[CMS], error) } // cmsRepository implements the Repository interface using the MongoDB ORM type cmsRepository struct { ormRepo orm.Repository[CMS] logger logger.Logger } // NewRepository creates a new CMS repository func NewRepository(mongoManager *orm.ConnectionManager, logger logger.Logger) Repository { // Create indexes using the ORM's index management indexes := []orm.Index{ *orm.CreateTextIndex("cms_search_idx", "key"), *orm.NewIndex("key_idx", bson.D{{Key: "key", Value: 1}}), *orm.NewIndex("created_at_idx", bson.D{{Key: "created_at", Value: -1}}), } // Create indexes err := mongoManager.CreateIndexes("cms", indexes) if err != nil { logger.Warn("Failed to create CMS indexes", map[string]interface{}{ "error": err.Error(), }) } // Create ORM repository ormRepo := orm.NewRepository[CMS](mongoManager.GetCollection("cms"), logger) return &cmsRepository{ ormRepo: ormRepo, logger: logger, } } // Create creates a new CMS entry func (r *cmsRepository) Create(ctx context.Context, cms *CMS) error { // Set created timestamp using Unix timestamp now := time.Now().Unix() cms.SetCreatedAt(now) // Use ORM to create CMS err := r.ormRepo.Create(ctx, cms) if err != nil { r.logger.Error("Failed to create CMS", map[string]interface{}{ "error": err.Error(), "key": cms.Key, }) return err } r.logger.Info("CMS created successfully", map[string]interface{}{ "id": cms.GetID(), "key": cms.Key, }) return nil } // Update updates a CMS entry func (r *cmsRepository) Update(ctx context.Context, cms *CMS) error { // Set updated timestamp using Unix timestamp cms.SetUpdatedAt(time.Now().Unix()) // Use ORM to update CMS err := r.ormRepo.Update(ctx, cms) if err != nil { r.logger.Error("Failed to update CMS", map[string]interface{}{ "error": err.Error(), "id": cms.GetID(), "key": cms.Key, }) return err } r.logger.Info("CMS updated successfully", map[string]interface{}{ "id": cms.GetID(), "key": cms.Key, }) return nil } // GetByID retrieves a CMS entry by ID func (r *cmsRepository) GetByID(ctx context.Context, id string) (*CMS, error) { cms, err := r.ormRepo.FindByID(ctx, id) if err != nil { if errors.Is(err, orm.ErrDocumentNotFound) { return nil, ErrCMSNotFound } r.logger.Error("Failed to get CMS by ID", map[string]interface{}{ "error": err.Error(), "id": id, }) return nil, err } return cms, nil } // GetByKey retrieves a CMS entry by key func (r *cmsRepository) GetByKey(ctx context.Context, key string) (*CMS, error) { cms, err := r.ormRepo.FindOne(ctx, bson.M{"key": key}) if err != nil { if errors.Is(err, orm.ErrDocumentNotFound) { return nil, ErrCMSNotFound } r.logger.Error("Failed to get CMS by key", map[string]interface{}{ "error": err.Error(), "key": key, }) return nil, err } return cms, nil } // Delete deletes a CMS entry func (r *cmsRepository) Delete(ctx context.Context, id string) error { // Get CMS first to log the key cms, err := r.GetByID(ctx, id) if err != nil { r.logger.Error("Failed to delete CMS", map[string]interface{}{ "error": err.Error(), "id": id, }) if errors.Is(err, ErrCMSNotFound) { return ErrCMSNotFound } return err } // Delete from database err = r.ormRepo.Delete(ctx, id) if err != nil { r.logger.Error("Failed to delete CMS", map[string]interface{}{ "error": err.Error(), "id": id, "key": cms.Key, }) return err } r.logger.Info("CMS deleted successfully", map[string]interface{}{ "id": id, "key": cms.Key, }) return nil } // Search searches CMS entries with filters and pagination func (r *cmsRepository) Search(ctx context.Context, search *SearchCMSForm, pagination orm.Pagination) (*orm.PaginatedResult[CMS], error) { filter := bson.M{} if search.Search != nil && *search.Search != "" { filter["$or"] = bson.A{ bson.M{"key": bson.M{"$regex": search.Search, "$options": "i"}}, } } if search.Key != nil && *search.Key != "" { filter["key"] = bson.M{"$regex": search.Key, "$options": "i"} } // Use ORM to find CMS entries result, err := r.ormRepo.FindAll(ctx, filter, pagination) if err != nil { r.logger.Error("Failed to search CMS entries", map[string]interface{}{ "error": err.Error(), }) return nil, err } return result, nil }