backend/pkg/notification/domain/repository/notification.go

83 lines
3.2 KiB
Go
Raw Normal View History

2025-11-17 09:31:58 +00:00
package repository
import (
"backend/pkg/notification/domain/entity"
"context"
"github.com/gocql/gocql"
)
type NotificationRepository interface {
NotificationEventRepository
UserNotificationRepository
NotificationCursorRepository
}
// ---- 1. Event ----
// 專心管「事件本體」fan-out 前先寫這張。
// 通常由上游 domain event consumer 呼叫 Create。
type QueryNotificationEventParam struct {
ObjectID *string
ObjectType *string
Limit *int
}
type NotificationEventRepository interface {
// Create 建立一筆新的 NotificationEvent。
Create(ctx context.Context, e *entity.NotificationEvent) error
// GetByID 依 EventID 取得事件。
GetByID(ctx context.Context, id string) (*entity.NotificationEvent, error)
// ListByObject 依 object_type + object_id 查詢相關事件選用debug / 後台用)。
ListByObject(ctx context.Context, param QueryNotificationEventParam) ([]*entity.NotificationEvent, error)
}
// ---- 2. 使用者通知user_notification ----
// 管使用者的小鈴鐺 rowfan-out 之後用這個寫入。
// ListLatestOptions 查列表用的參數
type ListLatestOptions struct {
UserID string
Buckets []string // e.g. []string{"202511", "202510"}
Limit int // 建議在 service 層限制最大值,例如 <= 100
}
type UserNotificationRepository interface {
// CreateUserNotification 建立單一通知(針對某一個 user
// 由呼叫端決定 bucket 與 TTL 秒數。
CreateUserNotification(ctx context.Context, n *entity.UserNotification, ttlSeconds int) error
// BulkCreate 批次建立多筆通知fan-out worker 使用)。
// 一般期望要嘛全部成功要嘛全部失敗。
BulkCreate(ctx context.Context, list []*entity.UserNotification, ttlSeconds int) error
// ListLatest 取得某 user 最新的通知列表(小鈴鐺拉下來用)。
ListLatest(ctx context.Context, opt ListLatestOptions) ([]*entity.UserNotification, error)
// MarkRead 將單一通知設為已讀。
// 用 (user_id, bucket, ts) 精準定位那一筆資料。
MarkRead(ctx context.Context, userID, bucket string, ts gocql.UUID) error
// MarkAllRead 將指定 buckets 範圍內的通知設為已讀。
// 常見用法:最近幾個 bucket例如最近 30 天)全部標為已讀。
// Cassandra 不適合全表掃描,實作時可分批 select 再 update。
MarkAllRead(ctx context.Context, userID string, buckets []string) error
// CountUnreadApprox 回傳未讀數(允許是近似值)。
// 實作方式可以是:
// - 掃少量 buckets 中 status='UNREAD' 的 row然後在應用端計算
// - 或讀取外部 counterRedis / 另一張 counter table
CountUnreadApprox(ctx context.Context, userID string, buckets []string) (int64, error)
}
// ---- 3. NotificationCursorRepository ----
// 管 last_seen 光標,用來減少大量「每一筆更新已讀」的成本。
type NotificationCursorRepository interface {
// GetCursor 取得某 user 的光標,如果不存在可以回傳 (nil, nil)。
GetCursor(ctx context.Context, userID string) (*entity.NotificationCursor, error)
// UpsertCursor 新增或更新光標。
// 一般在使用者打開通知列表、或捲到最上面時更新。
UpsertCursor(ctx context.Context, cursor *entity.NotificationCursor) error
}