157 lines
4.4 KiB
Go
157 lines
4.4 KiB
Go
package entity
|
|
|
|
import (
|
|
"errors"
|
|
"time"
|
|
|
|
"backend/pkg/post/domain/post"
|
|
|
|
"github.com/gocql/gocql"
|
|
)
|
|
|
|
// Post represents a post entity in the system.
|
|
// It contains the main content and metadata for user posts.
|
|
type Post struct {
|
|
ID gocql.UUID `db:"id" partition_key:"true"` // Post unique identifier
|
|
AuthorUID string `db:"author_uid"` // Author user UID
|
|
Title string `db:"title"` // Post title
|
|
Content string `db:"content"` // Post content
|
|
Type post.Type `db:"type"` // Post type (text, image, video, etc.)
|
|
Status post.Status `db:"status"` // Post status (draft, published, etc.)
|
|
CategoryID *gocql.UUID `db:"category_id,omitempty"` // Category ID (optional)
|
|
Tags []string `db:"tags,omitempty"` // Post tags
|
|
Images []string `db:"images,omitempty"` // Image URLs (optional)
|
|
VideoURL *string `db:"video_url,omitempty"` // Video URL (optional)
|
|
LinkURL *string `db:"link_url,omitempty"` // Link URL (optional)
|
|
LikeCount int64 `db:"like_count"` // Number of likes
|
|
CommentCount int64 `db:"comment_count"` // Number of comments
|
|
ViewCount int64 `db:"view_count"` // Number of views
|
|
IsPinned bool `db:"is_pinned"` // Whether the post is pinned
|
|
PinnedAt *int64 `db:"pinned_at,omitempty"` // Pinned timestamp (optional)
|
|
PublishedAt *int64 `db:"published_at,omitempty"` // Published timestamp (optional)
|
|
CreatedAt int64 `db:"created_at"` // Creation timestamp
|
|
UpdatedAt int64 `db:"updated_at"` // Last update timestamp
|
|
}
|
|
|
|
// TableName returns the Cassandra table name for Post entities.
|
|
func (p *Post) TableName() string {
|
|
return "posts"
|
|
}
|
|
|
|
// Validate validates the Post entity
|
|
func (p *Post) Validate() error {
|
|
if p.AuthorUID == "" {
|
|
return errors.New("author_uid is required")
|
|
}
|
|
if len(p.Title) < 1 || len(p.Title) > 200 {
|
|
return errors.New("title length must be between 1 and 200 characters")
|
|
}
|
|
if len(p.Content) < 1 || len(p.Content) > 10000 {
|
|
return errors.New("content length must be between 1 and 10000 characters")
|
|
}
|
|
if !p.Type.IsValid() {
|
|
return errors.New("invalid post type")
|
|
}
|
|
if !p.Status.IsValid() {
|
|
return errors.New("invalid post status")
|
|
}
|
|
if len(p.Tags) > 10 {
|
|
return errors.New("maximum 10 tags allowed per post")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// SetTimestamps sets the create and update timestamps
|
|
func (p *Post) SetTimestamps() {
|
|
now := time.Now().UTC().UnixNano() / 1e6 // milliseconds
|
|
if p.CreatedAt == 0 {
|
|
p.CreatedAt = now
|
|
}
|
|
p.UpdatedAt = now
|
|
}
|
|
|
|
// IsNew returns true if this is a new post (no ID set)
|
|
func (p *Post) IsNew() bool {
|
|
var zeroUUID gocql.UUID
|
|
return p.ID == zeroUUID
|
|
}
|
|
|
|
// Publish marks the post as published
|
|
func (p *Post) Publish() {
|
|
p.Status = post.PostStatusPublished
|
|
now := time.Now().UTC().UnixNano() / 1e6
|
|
p.PublishedAt = &now
|
|
p.SetTimestamps()
|
|
}
|
|
|
|
// Archive marks the post as archived
|
|
func (p *Post) Archive() {
|
|
p.Status = post.PostStatusArchived
|
|
p.SetTimestamps()
|
|
}
|
|
|
|
// Delete marks the post as deleted (soft delete)
|
|
func (p *Post) Delete() {
|
|
p.Status = post.PostStatusDeleted
|
|
p.SetTimestamps()
|
|
}
|
|
|
|
// IsVisible returns true if the post is visible to public
|
|
func (p *Post) IsVisible() bool {
|
|
return p.Status.IsVisible()
|
|
}
|
|
|
|
// IsEditable returns true if the post can be edited
|
|
func (p *Post) IsEditable() bool {
|
|
return p.Status.IsEditable()
|
|
}
|
|
|
|
// IncrementLikeCount increments the like count
|
|
func (p *Post) IncrementLikeCount() {
|
|
p.LikeCount++
|
|
p.SetTimestamps()
|
|
}
|
|
|
|
// DecrementLikeCount decrements the like count
|
|
func (p *Post) DecrementLikeCount() {
|
|
if p.LikeCount > 0 {
|
|
p.LikeCount--
|
|
p.SetTimestamps()
|
|
}
|
|
}
|
|
|
|
// IncrementCommentCount increments the comment count
|
|
func (p *Post) IncrementCommentCount() {
|
|
p.CommentCount++
|
|
p.SetTimestamps()
|
|
}
|
|
|
|
// DecrementCommentCount decrements the comment count
|
|
func (p *Post) DecrementCommentCount() {
|
|
if p.CommentCount > 0 {
|
|
p.CommentCount--
|
|
p.SetTimestamps()
|
|
}
|
|
}
|
|
|
|
// IncrementViewCount increments the view count
|
|
func (p *Post) IncrementViewCount() {
|
|
p.ViewCount++
|
|
p.SetTimestamps()
|
|
}
|
|
|
|
// Pin pins the post
|
|
func (p *Post) Pin() {
|
|
p.IsPinned = true
|
|
now := time.Now().UTC().UnixNano() / 1e6
|
|
p.PinnedAt = &now
|
|
p.SetTimestamps()
|
|
}
|
|
|
|
// Unpin unpins the post
|
|
func (p *Post) Unpin() {
|
|
p.IsPinned = false
|
|
p.PinnedAt = nil
|
|
p.SetTimestamps()
|
|
}
|