feat(posts): add post reference/internal linking functionality
Add support for referencing other posts within messages through a new post_ref segment type. Includes new PostReference model to track relationships, PostRefService for processing references, and new endpoints for post suggestions, related posts, and reference click tracking.
This commit is contained in:
97
internal/repository/post_ref_repo.go
Normal file
97
internal/repository/post_ref_repo.go
Normal file
@@ -0,0 +1,97 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
|
||||
"with_you/internal/model"
|
||||
)
|
||||
|
||||
type PostRefRepository interface {
|
||||
BatchUpsert(ctx context.Context, sourcePostID string, targetPostIDs []string) error
|
||||
DeleteBySourcePostID(ctx context.Context, sourcePostID string) error
|
||||
GetSourcesByTargetPostID(ctx context.Context, targetPostID string, page, pageSize int) ([]model.PostReference, int64, error)
|
||||
GetTargetsBySourcePostID(ctx context.Context, sourcePostID string) ([]model.PostReference, error)
|
||||
MarkStatusByTargetPostID(ctx context.Context, targetPostID string, status model.PostReferenceStatus) error
|
||||
IncrementClickCount(ctx context.Context, sourcePostID, targetPostID string) error
|
||||
}
|
||||
|
||||
type postRefRepository struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewPostRefRepository(db *gorm.DB) PostRefRepository {
|
||||
return &postRefRepository{db: db}
|
||||
}
|
||||
|
||||
func (r *postRefRepository) BatchUpsert(ctx context.Context, sourcePostID string, targetPostIDs []string) error {
|
||||
if len(targetPostIDs) == 0 {
|
||||
return nil
|
||||
}
|
||||
refs := make([]model.PostReference, 0, len(targetPostIDs))
|
||||
for _, targetID := range targetPostIDs {
|
||||
refs = append(refs, model.PostReference{
|
||||
SourcePostID: sourcePostID,
|
||||
TargetPostID: targetID,
|
||||
Status: model.PostRefActive,
|
||||
})
|
||||
}
|
||||
return r.db.WithContext(ctx).Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "source_post_id"}, {Name: "target_post_id"}},
|
||||
DoUpdates: clause.AssignmentColumns([]string{"status", "updated_at"}),
|
||||
}).Create(&refs).Error
|
||||
}
|
||||
|
||||
func (r *postRefRepository) DeleteBySourcePostID(ctx context.Context, sourcePostID string) error {
|
||||
return r.db.WithContext(ctx).Where("source_post_id = ?", sourcePostID).Delete(&model.PostReference{}).Error
|
||||
}
|
||||
|
||||
func (r *postRefRepository) GetSourcesByTargetPostID(ctx context.Context, targetPostID string, page, pageSize int) ([]model.PostReference, int64, error) {
|
||||
var refs []model.PostReference
|
||||
var total int64
|
||||
|
||||
if err := r.db.WithContext(ctx).Model(&model.PostReference{}).
|
||||
Where("target_post_id = ? AND status = ?", targetPostID, model.PostRefActive).
|
||||
Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
offset := (page - 1) * pageSize
|
||||
if err := r.db.WithContext(ctx).
|
||||
Where("target_post_id = ? AND status = ?", targetPostID, model.PostRefActive).
|
||||
Preload("SourcePost").
|
||||
Preload("SourcePost.User").
|
||||
Order("created_at DESC").
|
||||
Offset(offset).Limit(pageSize).
|
||||
Find(&refs).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return refs, total, nil
|
||||
}
|
||||
|
||||
func (r *postRefRepository) GetTargetsBySourcePostID(ctx context.Context, sourcePostID string) ([]model.PostReference, error) {
|
||||
var refs []model.PostReference
|
||||
if err := r.db.WithContext(ctx).
|
||||
Where("source_post_id = ?", sourcePostID).
|
||||
Preload("TargetPost").
|
||||
Preload("TargetPost.User").
|
||||
Find(&refs).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return refs, nil
|
||||
}
|
||||
|
||||
func (r *postRefRepository) MarkStatusByTargetPostID(ctx context.Context, targetPostID string, status model.PostReferenceStatus) error {
|
||||
return r.db.WithContext(ctx).Model(&model.PostReference{}).
|
||||
Where("target_post_id = ?", targetPostID).
|
||||
Update("status", status).Error
|
||||
}
|
||||
|
||||
func (r *postRefRepository) IncrementClickCount(ctx context.Context, sourcePostID, targetPostID string) error {
|
||||
return r.db.WithContext(ctx).Model(&model.PostReference{}).
|
||||
Where("source_post_id = ? AND target_post_id = ?", sourcePostID, targetPostID).
|
||||
UpdateColumn("click_count", gorm.Expr("click_count + 1")).Error
|
||||
}
|
||||
Reference in New Issue
Block a user