package chat import ( "context" "github.com/google/uuid" "go.uber.org/zap" "gorm.io/gorm" ) type PermissionService struct { db *gorm.DB logger *zap.Logger } func NewPermissionService(db *gorm.DB, logger *zap.Logger) *PermissionService { if logger == nil { logger = zap.NewNop() } return &PermissionService{ db: db, logger: logger, } } type roomMemberCheck struct { Role string `gorm:"column:role"` IsMuted bool `gorm:"column:is_muted"` } func (p *PermissionService) getMembership(ctx context.Context, userID, roomID uuid.UUID) (*roomMemberCheck, bool) { var member roomMemberCheck err := p.db.WithContext(ctx). Table("room_members"). Select("role, is_muted"). Where("user_id = ? AND room_id = ?", userID, roomID). First(&member).Error if err != nil { return nil, false } return &member, true } func (p *PermissionService) CanRead(ctx context.Context, userID, roomID uuid.UUID) bool { // GL3-01: Live stream chat — allow read when roomID is a live_streams.id (public) var count int64 if err := p.db.WithContext(ctx). Table("live_streams"). Where("id = ?", roomID). Count(&count).Error; err == nil && count > 0 { return true } _, isMember := p.getMembership(ctx, userID, roomID) return isMember } func (p *PermissionService) CanSend(ctx context.Context, userID, roomID uuid.UUID) bool { // GL3-01: Live stream chat — allow send when roomID is a live_streams.id (public) var count int64 if err := p.db.WithContext(ctx). Table("live_streams"). Where("id = ?", roomID). Count(&count).Error; err == nil && count > 0 { return true } member, isMember := p.getMembership(ctx, userID, roomID) if !isMember { return false } return !member.IsMuted } func (p *PermissionService) CanJoin(ctx context.Context, userID, roomID uuid.UUID) bool { // GL3-01: Live stream chat — allow join when roomID is a live_streams.id (public) var count int64 if err := p.db.WithContext(ctx). Table("live_streams"). Where("id = ?", roomID). Count(&count).Error; err == nil && count > 0 { return true } _, isMember := p.getMembership(ctx, userID, roomID) return isMember } // IsLiveRoom returns true if roomID is a live_streams.id (F474). func (p *PermissionService) IsLiveRoom(ctx context.Context, roomID uuid.UUID) bool { var count int64 if err := p.db.WithContext(ctx). Table("live_streams"). Where("id = ?", roomID). Count(&count).Error; err != nil { return false } return count > 0 } func (p *PermissionService) CanModerate(ctx context.Context, userID, roomID uuid.UUID) bool { member, isMember := p.getMembership(ctx, userID, roomID) if !isMember { return false } return member.Role == "admin" || member.Role == "moderator" || member.Role == "owner" }