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

83 lines
3.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}