package domain import "context" /* Repository 是 radar module 的持久化介面。實作有兩份:mongo(正式)與 memory(測試), 兩份行為必須一致,尤其是「找不到」一律回 ErrNotFound 而非 nil。 */ type Repository interface { // ServiceProfile:每會員一份 GetServiceProfile(ctx context.Context, ownerUID int64) (*ServiceProfile, error) SaveServiceProfile(ctx context.Context, p *ServiceProfile) error // RadarWatch SaveWatch(ctx context.Context, w *RadarWatch) error GetWatch(ctx context.Context, id string) (*RadarWatch, error) ListWatches(ctx context.Context, ownerUID int64, f WatchListFilter) ([]*RadarWatch, int64, error) // ListActiveWatches 是每日排程的來源,只回 active。 ListActiveWatches(ctx context.Context, ownerUID int64) ([]*RadarWatch, error) // ListAllActiveWatches 跨會員列出全部 active watch,供 worker 每日排程 tick 使用。 ListAllActiveWatches(ctx context.Context) ([]*RadarWatch, error) CountActiveWatches(ctx context.Context, ownerUID int64) (int64, error) TouchWatchSweptAt(ctx context.Context, id string, at int64) error // Opportunity // UpsertByExternalID:同 owner+external_id 只留一筆;命中則併 matched_terms,不重跑判定。 UpsertByExternalID(ctx context.Context, o *Opportunity) (*Opportunity, error) GetOpportunity(ctx context.Context, id string) (*Opportunity, error) GetByExternalID(ctx context.Context, ownerUID int64, externalID string) (*Opportunity, error) ListOpportunities(ctx context.Context, ownerUID int64, f OpportunityListFilter) ([]*Opportunity, int64, error) // CountToday 回傳 UTC 當日建立的商機數(每日配額池)。 CountToday(ctx context.Context, ownerUID int64, at int64) (int64, error) UpdateOpportunityStatus(ctx context.Context, id string, status string) error SetOpportunityOverride(ctx context.Context, id string, ov *OpportunityOverride, newBand, newStatus string) error // RadarSweep CreateSweep(ctx context.Context, s *RadarSweep) error // UpdateSweep 累加計數與 judged_external_ids(去重),供 Job 中途進度與續跑。 UpdateSweep(ctx context.Context, id string, delta SweepDelta) (*RadarSweep, error) GetSweep(ctx context.Context, id string) (*RadarSweep, error) GetSweepByJobID(ctx context.Context, jobID string) (*RadarSweep, error) ListSweeps(ctx context.Context, ownerUID int64, f SweepListFilter) ([]*RadarSweep, int64, error) // ReplyVariant SaveReply(ctx context.Context, r *ReplyVariant) error ListReplies(ctx context.Context, ownerUID int64, opportunityID string) ([]*ReplyVariant, error) GetReply(ctx context.Context, id string) (*ReplyVariant, error) }