turash/bugulma/backend/internal/repository/content_repository.go

151 lines
4.9 KiB
Go

package repository
import (
"context"
"strings"
"time"
"bugulma/backend/internal/domain"
"gorm.io/gorm"
)
// StaticPageRepository implements domain.StaticPageRepository with GORM
type StaticPageRepository struct {
*BaseRepository[domain.StaticPage]
db *gorm.DB
}
// NewStaticPageRepository creates a new GORM-based static page repository
func NewStaticPageRepository(db *gorm.DB) domain.StaticPageRepository {
return &StaticPageRepository{
BaseRepository: NewBaseRepository[domain.StaticPage](db),
db: db,
}
}
// GetBySlug retrieves a page by slug
func (r *StaticPageRepository) GetBySlug(ctx context.Context, slug string) (*domain.StaticPage, error) {
return r.FindOneWhereWithContext(ctx, "slug = ?", slug)
}
// Search searches pages by title and content
func (r *StaticPageRepository) Search(ctx context.Context, query string) ([]*domain.StaticPage, error) {
searchTerm := "%" + strings.ToLower(query) + "%"
return r.FindWhereWithContext(ctx, "LOWER(title) LIKE ? OR LOWER(content) LIKE ?", searchTerm, searchTerm)
}
// AnnouncementRepository implements domain.AnnouncementRepository with GORM
type AnnouncementRepository struct {
*BaseRepository[domain.Announcement]
db *gorm.DB
}
// NewAnnouncementRepository creates a new GORM-based announcement repository
func NewAnnouncementRepository(db *gorm.DB) domain.AnnouncementRepository {
return &AnnouncementRepository{
BaseRepository: NewBaseRepository[domain.Announcement](db),
db: db,
}
}
// GetAll retrieves announcements with filters
func (r *AnnouncementRepository) GetAll(ctx context.Context, filters domain.AnnouncementFilters) ([]*domain.Announcement, error) {
query := r.db.WithContext(ctx).Model(&domain.Announcement{})
if filters.IsActive != nil {
query = query.Where("is_active = ?", *filters.IsActive)
}
if filters.Priority != nil {
query = query.Where("priority = ?", *filters.Priority)
}
if filters.StartDate != nil {
query = query.Where("start_date >= ?", *filters.StartDate)
}
if filters.EndDate != nil {
query = query.Where("end_date <= ?", *filters.EndDate)
}
var announcements []*domain.Announcement
result := query.Order("created_at DESC").Find(&announcements)
if result.Error != nil {
return nil, result.Error
}
return announcements, nil
}
// GetActive retrieves active announcements
func (r *AnnouncementRepository) GetActive(ctx context.Context) ([]*domain.Announcement, error) {
now := time.Now()
return r.FindWhereWithContext(ctx, "is_active = ? AND (start_date IS NULL OR start_date <= ?) AND (end_date IS NULL OR end_date >= ?)", true, now, now)
}
// RecordView records a view for an announcement
func (r *AnnouncementRepository) RecordView(ctx context.Context, id string) error {
result := r.db.WithContext(ctx).
Model(&domain.Announcement{}).
Where("id = ?", id).
UpdateColumn("views", gorm.Expr("views + 1"))
return result.Error
}
// RecordClick records a click for an announcement
func (r *AnnouncementRepository) RecordClick(ctx context.Context, id string) error {
result := r.db.WithContext(ctx).
Model(&domain.Announcement{}).
Where("id = ?", id).
UpdateColumn("clicks", gorm.Expr("clicks + 1"))
return result.Error
}
// RecordDismissal records a dismissal for an announcement
func (r *AnnouncementRepository) RecordDismissal(ctx context.Context, id string) error {
result := r.db.WithContext(ctx).
Model(&domain.Announcement{}).
Where("id = ?", id).
UpdateColumn("dismissals", gorm.Expr("dismissals + 1"))
return result.Error
}
// MediaAssetRepository implements domain.MediaAssetRepository with GORM
type MediaAssetRepository struct {
*BaseRepository[domain.MediaAsset]
db *gorm.DB
}
// NewMediaAssetRepository creates a new GORM-based media asset repository
func NewMediaAssetRepository(db *gorm.DB) domain.MediaAssetRepository {
return &MediaAssetRepository{
BaseRepository: NewBaseRepository[domain.MediaAsset](db),
db: db,
}
}
// GetAll retrieves media assets with filters
func (r *MediaAssetRepository) GetAll(ctx context.Context, filters domain.MediaAssetFilters) ([]*domain.MediaAsset, error) {
query := r.db.WithContext(ctx).Model(&domain.MediaAsset{})
if filters.Type != nil {
query = query.Where("type = ?", *filters.Type)
}
if len(filters.Tags) > 0 {
// Search for assets containing any of the tags
for _, tag := range filters.Tags {
query = query.Where("tags::text LIKE ?", "%"+tag+"%")
}
}
var assets []*domain.MediaAsset
result := query.Order("created_at DESC").Find(&assets)
if result.Error != nil {
return nil, result.Error
}
return assets, nil
}
// Search searches media assets by filename and tags
func (r *MediaAssetRepository) Search(ctx context.Context, query string) ([]*domain.MediaAsset, error) {
searchTerm := "%" + strings.ToLower(query) + "%"
return r.FindWhereWithContext(ctx, "LOWER(filename) LIKE ? OR LOWER(original_name) LIKE ? OR tags::text LIKE ?", searchTerm, searchTerm, searchTerm)
}