Ctrl K
ComunidadGuías…

internal/store/account_rating.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package store

import (
	"context"

	"telesrv/internal/domain"
)

// AccountRatingStore owns the composite rating read model and its contribution
// ledger.
//
// The read model is derived: SaveAccountRating writes a recomputed projection,
// AccountRatingSignals gathers the raw inputs from the contributing tables, and
// the ledger keeps manual adjustments that must survive a recompute.
type AccountRatingStore interface {
	// AccountRating returns the stored projection. Missing rows return
	// domain.ErrAccountRatingNotFound so callers can distinguish "never computed"
	// from "computed as zero".
	AccountRating(ctx context.Context, userID int64) (domain.AccountRating, error)
	// AccountRatingBatch resolves several users in one round trip. Users without
	// a row are absent from the map.
	AccountRatingBatch(ctx context.Context, userIDs []int64) (map[int64]domain.AccountRating, error)
	// SaveAccountRating upserts the projection using optimistic concurrency on
	// the stored version; a stale version reports changed=false.
	SaveAccountRating(ctx context.Context, rating domain.AccountRating) (stored domain.AccountRating, changed bool, err error)
	// AccountRatingSignals gathers the raw contribution snapshot for one user,
	// including the manual total carried from the ledger.
	AccountRatingSignals(ctx context.Context, userID int64) (domain.AccountRatingSignals, error)
	// AdjustAccountRating appends a manual adjustment. Replaying the same
	// CommandKey returns the recorded event and applied=false.
	AdjustAccountRating(ctx context.Context, req domain.AdjustAccountRatingRequest) (event domain.AccountRatingEvent, applied bool, err error)
	// ListAccountRatings is the admin leaderboard query with keyset paging.
	ListAccountRatings(ctx context.Context, filter domain.AccountRatingFilter) ([]domain.AccountRating, error)
	// AccountRatingEvents returns the ledger for one user, newest first.
	AccountRatingEvents(ctx context.Context, userID int64, limit int) ([]domain.AccountRatingEvent, error)
	// StaleAccountRatings returns user ids whose projection is older than the
	// given horizon, for the background recompute worker.
	StaleAccountRatings(ctx context.Context, olderThanUnix int64, limit int) ([]int64, error)
	// UnratedAccounts returns user ids that have no projection at all, oldest
	// account first, for the same worker.
	//
	// Without this the read model can never populate itself: StaleAccountRatings
	// walks account_rating, so it can only refresh rows that already exist, and the
	// very first row for a user would have to come from an operator recomputing
	// that user by hand. Seeding is what makes the local admin leaderboard useful.
	//
	// Deleted accounts and bots are excluded: neither has a rating to show.
	UnratedAccounts(ctx context.Context, limit int) ([]int64, error)
}