package entity import ( "errors" "time" "backend/pkg/post/domain/post" "github.com/gocql/gocql" ) // Comment represents a comment entity on a post. // Comments can be nested (replies to comments). type Comment struct { ID gocql.UUID `db:"id" partition_key:"true"` // Comment unique identifier PostID gocql.UUID `db:"post_id" clustering_key:"true"` // Post ID (clustering key for sorting) AuthorUID string `db:"author_uid"` // Author user UID ParentID *gocql.UUID `db:"parent_id,omitempty" clustering_key:"true"` // Parent comment ID (for nested comments) Content string `db:"content"` // Comment content Status post.CommentStatus `db:"status"` // Comment status LikeCount int64 `db:"like_count"` // Number of likes ReplyCount int64 `db:"reply_count"` // Number of replies CreatedAt int64 `db:"created_at" clustering_key:"true"` // Creation timestamp (for sorting) UpdatedAt int64 `db:"updated_at"` // Last update timestamp } // TableName returns the Cassandra table name for Comment entities. func (c *Comment) TableName() string { return "comments" } // Validate validates the Comment entity func (c *Comment) Validate() error { var zeroUUID gocql.UUID if c.PostID == zeroUUID { return errors.New("post_id is required") } if c.AuthorUID == "" { return errors.New("author_uid is required") } if len(c.Content) < 1 || len(c.Content) > 2000 { return errors.New("content length must be between 1 and 2000 characters") } if !c.Status.IsValid() { return errors.New("invalid comment status") } return nil } // SetTimestamps sets the create and update timestamps func (c *Comment) SetTimestamps() { now := time.Now().UTC().UnixNano() / 1e6 // milliseconds if c.CreatedAt == 0 { c.CreatedAt = now } c.UpdatedAt = now } // IsNew returns true if this is a new comment (no ID set) func (c *Comment) IsNew() bool { var zeroUUID gocql.UUID return c.ID == zeroUUID } // IsReply returns true if this comment is a reply to another comment func (c *Comment) IsReply() bool { var zeroUUID gocql.UUID return c.ParentID != nil && *c.ParentID != zeroUUID } // Delete marks the comment as deleted (soft delete) func (c *Comment) Delete() { c.Status = post.CommentStatusDeleted c.SetTimestamps() } // Hide hides the comment func (c *Comment) Hide() { c.Status = post.CommentStatusHidden c.SetTimestamps() } // IsVisible returns true if the comment is visible to public func (c *Comment) IsVisible() bool { return c.Status.IsVisible() } // IncrementLikeCount increments the like count func (c *Comment) IncrementLikeCount() { c.LikeCount++ c.SetTimestamps() } // DecrementLikeCount decrements the like count func (c *Comment) DecrementLikeCount() { if c.LikeCount > 0 { c.LikeCount-- c.SetTimestamps() } } // IncrementReplyCount increments the reply count func (c *Comment) IncrementReplyCount() { c.ReplyCount++ c.SetTimestamps() } // DecrementReplyCount decrements the reply count func (c *Comment) DecrementReplyCount() { if c.ReplyCount > 0 { c.ReplyCount-- c.SetTimestamps() } }