Files
spsays-bff/internal/model/broadcast.go
T
2026-08-29 18:34:07 +05:30

41 lines
1.3 KiB
Go

package model
import (
"encoding/json"
"time"
)
// Broadcast is an announcement shown to every user exactly once.
//
// Deliberately not a notification: it creates no tray rows and no per-user
// records until someone actually dismisses it. The modal is the delivery
// surface; push and the realtime nudge only tell clients to go look.
type Broadcast struct {
ID string `json:"id"`
Title string `json:"title"`
Body string `json:"body"`
// Entities are offset/length formatting spans, the same shape chat uses,
// so no HTML is ever stored or rendered.
Entities json.RawMessage `json:"entities"`
// BannerURL is resolved from the stored R2 key for the client.
BannerURL *string `json:"banner_url,omitempty"`
CTALabel *string `json:"cta_label,omitempty"`
CTAURL *string `json:"cta_url,omitempty"`
PublishedAt *time.Time `json:"published_at,omitempty"`
ExpiresAt *time.Time `json:"expires_at,omitempty"`
CreatedAt time.Time `json:"created_at"`
// SeenCount is filled for the admin list only — how many people have
// dismissed it so far.
SeenCount int64 `json:"seen_count,omitempty"`
}
// Live reports whether the broadcast is currently deliverable.
func (b *Broadcast) Live(now time.Time) bool {
if b.PublishedAt == nil || b.PublishedAt.After(now) {
return false
}
return b.ExpiresAt == nil || b.ExpiresAt.After(now)
}