Documentation
¶
Overview ¶
Package planstep resolves a purchase plan's current step into the recommendations it would buy. It reads only; nothing here attaches or executes, and no production caller exists yet (platform#631).
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrNoMatch = errors.New("no current recommendation matches the plan")
ErrNoMatch means no stored recommendation matches the plan right now. It is not a failure of the plan: the cache may be cold or mid-collect, so callers retry on a later tick and fail only after the grace window.
var ErrTargetMet = errors.New("the plan's cumulative target is already met")
ErrTargetMet means every matched recommendation already has this plan's cumulative target committed, so the step has nothing left to buy. It is distinct from ErrNoMatch (nothing matched, retry later).
var ErrUnsupportedPlan = errors.New("plan settings are not supported by recommendation resolution")
ErrUnsupportedPlan marks a plan whose settings Resolve cannot honor. Every such plan is refused before any recommendation is read, rather than resolved with the setting silently ignored.
Functions ¶
func Precheck ¶
func Precheck(plan *config.PurchasePlan) error
Precheck refuses, with a plan-specific error, the plan settings Resolve does not apply: any Include*/Exclude*/MinCount filter on a service config (the plan-step request never sets them, so honoring them would buy something other than what the plan says), an armed multi-step plan with a Savings Plans service (platform#631 Q7), and an immediate ramp whose PercentPerStep is not 100 (an immediate ramp ignores that field when validated but Resolve sizes with it).
Types ¶
type Result ¶
type Result struct {
// Recs are the recommendations the step would buy.
Recs []config.RecommendationRecord
// Baseline is set only when step is 1: every matched count-based identity
// mapped to its base (the existing baseline entry, else step-1 shown),
// including recs that sized to 0. The caller freezes it; nil at step > 1.
Baseline config.PlanRampBaseline
// Skipped lists identities with no baseline at step > 1 (new recs, newly
// added accounts). They are never frozen at first sight: under-buy.
Skipped []string
// Target and Committed total the judged identities' cumulative target and
// what the plan already holds. Set only with ErrTargetMet, for the no-op
// row's note.
Target, Committed int
}
Result is what Resolve decided for one step.
func Resolve ¶
func Resolve(ctx context.Context, src Source, store Store, plan *config.PurchasePlan, accountIDs []string, step int, baseline config.PlanRampBaseline, committed map[string]config.PlanRampQuantity) (Result, error)
Resolve returns the recommendations the plan's step would buy: for each enabled plan service, the recs Opportunities shows (strict read, enabled providers) restricted to the plan's term, payment and target accounts, sized to the CUMULATIVE target and priced from the unsuppressed stored row. For a count rec: target = floor(base * Coverage * CumulativePercent(step) / 10000) and buy = clamp(target - committed, 0, shown). base is the frozen baseline entry, or at step 1 the shown count (post-suppression, never above demand); at step > 1 an identity without a baseline is skipped. baseline and committed are caller-supplied (this function does no extra store reads). accountIDs are the plan's target accounts; recs without an account are excluded. Every failure is returned; there is no unsized or over-show fallback. An empty result is ErrTargetMet only when a non-empty baseline exists and every baselined identity has its target committed (decided without `shown`); anything else, including a hidden identity with a gap or an empty step-1 read (no baseline returned), is ErrNoMatch. Savings Plans keep their per-step sizing (platform#631 Q7).
type Source ¶
type Source interface {
ListRecommendationsStrict(ctx context.Context, filter config.RecommendationFilter) ([]config.RecommendationRecord, error)
}
Source is the strict recommendation read (suppressions and account overrides applied; their read errors returned). *scheduler.Scheduler.
type Store ¶
type Store interface {
ListStoredRecommendations(ctx context.Context, filter config.RecommendationFilter) ([]config.RecommendationRecord, error)
GetGlobalConfig(ctx context.Context) (*config.GlobalConfig, error)
}
Store supplies the unsuppressed stored rows used for pricing and the enabled-providers setting. config.StoreInterface satisfies it.