Documentation
¶
Overview ¶
Package discovery is ContentKit's public read surface over its own content: lists, keyword search, typeahead, similar and "for you" lists, the release date index, viewers' content filters and history, and the signals and exposures clients send. Every read runs over content_facets under the catalog's one visibility rule (Visibility): access, site scope, content filters, listing and language apply inside ContentKit, and each content item shows as one card carrying the version that fits the viewer best.
Similar and "for you" lists come from a Candidates source (Engagement, the co-engagement default, or a provider's) through the Recommender's shared policy; popular sorts read the policy scores an engine job copies from the signal plane into content_facets.popularity.
Index ¶
- Constants
- Variables
- type Admit
- type Candidate
- type Candidates
- type Card
- type CardAccess
- type CardVersion
- type Chip
- type ContentFilterState
- type ContentFilters
- type ContentFiltersUpdate
- type ContentPage
- type Counts
- type Covers
- type DateCount
- type Engagement
- type ExposureInput
- type Exposures
- type Fallback
- type Filter
- type FilterSetting
- type HistoryOptions
- type Hit
- type ImportSignal
- type Interaction
- type InteractionPage
- type ListOptions
- type MineOptions
- type Options
- type Placement
- type Query
- type Reader
- type RecentSearch
- type RecentSearches
- type RecommendOptions
- type RecommendationOptions
- type Recommender
- type ReleaseDates
- type ReleaseDatesOptions
- type Sales
- type SearchOptions
- type Service
- func (s *Service) ClearSearches(ctx context.Context, actor access.Actor, session, query string) error
- func (s *Service) ContentFilters(ctx context.Context, actor access.Actor, language string) (ContentFilters, error)
- func (s *Service) EraseSearches(ctx context.Context, subjects []signal.Subject) error
- func (s *Service) Favorites(ctx context.Context, o MineOptions) (InteractionPage, error)
- func (s *Service) ForgetHistory(ctx context.Context, actor access.Actor, kind, contentID string) error
- func (s *Service) Handler(a auth.Authenticator) (http.Handler, error)
- func (s *Service) History(ctx context.Context, o HistoryOptions) (ContentPage, error)
- func (s *Service) ImportSignals(ctx context.Context, in []ImportSignal) error
- func (s *Service) List(ctx context.Context, o ListOptions) (ContentPage, error)
- func (s *Service) PruneSearches(ctx context.Context) (int, error)
- func (s *Service) Reactions(ctx context.Context, o MineOptions) (InteractionPage, error)
- func (s *Service) RecentSearches(ctx context.Context, actor access.Actor, session string, limit int) (RecentSearches, error)
- func (s *Service) Recommendations(ctx context.Context, o RecommendationOptions) (ContentPage, error)
- func (s *Service) RecordExposures(ctx context.Context, actor access.Actor, in Exposures) error
- func (s *Service) RecordSearch(ctx context.Context, actor access.Actor, session, query string, results int) error
- func (s *Service) RecordSignals(ctx context.Context, actor access.Actor, in Signals) error
- func (s *Service) RefreshPopularity(ctx context.Context) error
- func (s *Service) ReleaseDates(ctx context.Context, o ReleaseDatesOptions) (ReleaseDates, error)
- func (s *Service) Search(ctx context.Context, o SearchOptions) (ContentPage, error)
- func (s *Service) SetContentFilters(ctx context.Context, actor access.Actor, u ContentFiltersUpdate) error
- func (s *Service) SignalPlane() bool
- func (s *Service) Similar(ctx context.Context, anchorID string, o RecommendationOptions) (ContentPage, error)
- func (s *Service) Typeahead(ctx context.Context, o TypeaheadOptions) (Typeahead, error)
- type SignalInput
- type Signals
- type SimilarOptions
- type Typeahead
- type TypeaheadOptions
- type ViewerState
- type Visibility
Constants ¶
const ( // TypeView is a consumption session: its progress is cumulative per // revision. TypeView = signal.TypeView // TypeClick is a click on a listed card, attributed to its render. TypeClick = "click" )
Signal types a client sends.
const ( TargetContents = "contents" TargetGroups = "groups" )
Interaction targets: content items or groups.
const ( Unseen = "unseen" InProgress = "in_progress" Completed = "completed" )
View statuses.
const ( SortNewest = "newest" SortOldest = "oldest" SortTitle = "title" SortPopular = "popular" SortTopRated = "top_rated" SortMostFavorited = "most_favorited" SortMostViewed = "most_viewed" SortPosition = "position" SortRandom = "random" )
Sorts.
const PopularityDepth = 100_000
PopularityDepth bounds the contents per kind and period that carry a popularity score; the rest sort as unviewed.
const SearchRetention = 180 * 24 * time.Hour
SearchRetention is how long a recent search is kept after its last use.
const SortRelevance = "relevance"
SortRelevance orders search results by match, personalized for a signed-in reader.
Variables ¶
var ( ErrInvalid = errors.New("discovery: invalid request") ErrNotFound = errors.New("discovery: not found") // ErrNoSignals is a read or write that needs the signal plane, which the // engine runs without. ErrNoSignals = errors.New("discovery: no signal plane") )
Errors; match with errors.Is.
Functions ¶
This section is empty.
Types ¶
type Admit ¶ added in v0.83.0
type Admit func(ctx context.Context, refs []contentref.ContentRef) (map[contentref.ContentKey]bool, error)
Admit decides which candidate works a list may show, in one batch: the reader's visibility. Recommender oversamples its sources so admission still fills the list.
type Candidate ¶
type Candidate struct {
Ref contentref.ContentRef
Score float64
}
Candidate is one ranked work.
type Candidates ¶
type Candidates interface {
Similar(ctx context.Context, anchor contentref.ContentRef, q Query) ([]Candidate, error)
ForSubject(ctx context.Context, subject signal.Subject, q Query) ([]Candidate, error)
}
Candidates generates ranked candidate works for similar and "for you" lists; Recommender applies the shared policy (tenant, kinds, anchor, seen and disliked exclusions, admission, dedupe, limit, popularity fill) so every source gets it. Engagement is the default co-engagement source; Fallback composes a new source over it. Order is rank. Implementations should oversample past Limit: Recommender filters afterward and truncates.
type Card ¶ added in v0.83.0
type Card struct {
ID string `json:"id"`
Kind string `json:"kind"`
// Code and Path are its page: [/{lang}]/{route}/{code}/{slug}.
Code string `json:"code"`
Path string `json:"path"`
// Title is in Language: the display language, else a fallback.
Title string `json:"title"`
Language string `json:"language"`
Cover []media.PublicRendition `json:"cover"`
Version CardVersion `json:"version"`
// Groups are the version's effective groups with a page, by group kind.
Groups map[string][]Chip `json:"groups"`
// Owner is the owner group's card (a channel's name, path, avatar and
// cover).
Owner *groups.GroupCard `json:"owner,omitempty"`
Counts Counts `json:"counts"`
Access CardAccess `json:"access"`
Viewer *ViewerState `json:"viewer,omitempty"`
PublishedAt *time.Time `json:"published_at,omitempty"`
Attributes map[string]any `json:"attributes"`
}
Card is one content item as a grid shows it, with the version that fits the reader best.
type CardAccess ¶ added in v0.83.0
type CardAccess struct {
Allowed bool `json:"allowed"`
// Unknown: entitlements could not be read; denied, nothing offered.
Unknown bool `json:"unknown,omitempty"`
// Sell are the keys whose purchase opens it; Requires is the key a buyer
// holds first.
Sell []string `json:"sell,omitempty"`
Requires string `json:"requires,omitempty"`
Preview *access.Preview `json:"preview,omitempty"`
FreeAfter *time.Time `json:"free_after,omitempty"`
// Offers are the purchasable offers of Sell's keys; tiers are the host's
// to label.
Offers []offers.Sale `json:"offers,omitempty"`
}
CardAccess is the reader's access decision on the card's version.
type CardVersion ¶ added in v0.83.0
type CardVersion struct {
ID string `json:"id"`
Languages []string `json:"languages"`
Traits []string `json:"traits"`
Label string `json:"label,omitempty"`
Pages *int `json:"pages,omitempty"`
DurationMS *int64 `json:"duration_ms,omitempty"`
}
CardVersion is the version a card shows.
type Chip ¶ added in v0.83.0
type Chip struct {
ID string `json:"id"`
Slug string `json:"slug"`
Name string `json:"name"`
Path string `json:"path,omitempty"`
}
Chip names one group on a card.
type ContentFilterState ¶ added in v0.83.0
type ContentFilterState struct {
Group groups.GroupCard `json:"group"`
// Label is the configured label in the requested language, else the
// group's name.
Label string `json:"label"`
DefaultVisible bool `json:"default_visible"`
// Visible is the reader's setting, Overridden whether it is their own.
Visible bool `json:"visible"`
Overridden bool `json:"overridden"`
}
ContentFilterState is one configured content filter as the reader has it.
type ContentFilters ¶ added in v0.83.0
type ContentFilters struct {
Filters []ContentFilterState `json:"filters"`
// IncludeDeleted lists deleted content the reader holds.
IncludeDeleted bool `json:"include_deleted"`
}
ContentFilters are the reader's content filters, applied in every read.
type ContentFiltersUpdate ¶ added in v0.83.0
type ContentFiltersUpdate struct {
Filters []FilterSetting `json:"filters"`
IncludeDeleted bool `json:"include_deleted"`
}
ContentFiltersUpdate replaces the reader's settings.
type ContentPage ¶ added in v0.83.0
type ContentPage struct {
Contents []Card `json:"contents"`
// NextCursor pages on; empty on the last page.
NextCursor string `json:"next_cursor,omitempty"`
}
ContentPage is one page of cards.
type Counts ¶ added in v0.83.0
type Counts struct {
Likes int `json:"likes"`
Dislikes int `json:"dislikes"`
Favorites int `json:"favorites"`
Views int64 `json:"views"`
}
Counts are a content item's interaction counts; Views counts its distinct viewers of all time plus its imported legacy view count.
type Covers ¶ added in v0.83.0
type Covers interface {
Covers(ctx context.Context, covers []versions.CoverOf) ([][]media.PublicRendition, error)
}
Covers resolves covers to public renditions, per cover in order: versions.Service.
type DateCount ¶ added in v0.83.0
type DateCount struct {
// Date is YYYY-MM-DD or YYYY-MM in the filter's time zone.
Date string `json:"date"`
// Count is the contents released then; Free those open to anyone.
Count int `json:"count"`
Free int `json:"free"`
}
DateCount is one day or month of the index.
type Engagement ¶
type Engagement struct {
Store *signal.Store
Tenant string
// RRFK is the seed fusion constant (default 60).
RRFK int
}
Engagement is the co-engagement Candidates source: Similar reads works co-engaged with the anchor; ForSubject seeds from the subject's highest-signal non-negative works and RRF-fuses each seed's co-engaged list.
func NewEngagement ¶
func NewEngagement(conn signal.Conn, database, tenant string) (Engagement, error)
NewEngagement builds the default source over a hub's ClickHouse database.
func (Engagement) ForSubject ¶
func (e Engagement) ForSubject(ctx context.Context, subject signal.Subject, q Query) ([]Candidate, error)
ForSubject never returns its seeds.
func (Engagement) Similar ¶
func (e Engagement) Similar(ctx context.Context, anchor contentref.ContentRef, q Query) ([]Candidate, error)
type ExposureInput ¶ added in v0.83.0
type ExposureInput struct {
// RenderID is stable per render and shared with its clicks.
RenderID string `json:"render_id"`
// Stage is served, rendered or visible.
Stage string `json:"stage"`
Revision uint64 `json:"revision,omitempty"`
QueryID string `json:"query_id,omitempty"`
Surface string `json:"surface,omitempty"`
Ranker string `json:"ranker,omitempty"`
Language string `json:"language,omitempty"`
// OccurredAt is the render's time; now by default.
OccurredAt *time.Time `json:"occurred_at,omitempty"`
Shown []Placement `json:"shown"`
}
ExposureInput is one result list at one stage.
type Exposures ¶ added in v0.83.0
type Exposures struct {
Session string `json:"session,omitempty"`
Exposures []ExposureInput `json:"exposures"`
}
Exposures are result lists a client rendered or showed.
type Fallback ¶
type Fallback struct {
Primary, Secondary Candidates
OnError func(error)
}
Fallback serves Primary and uses Secondary when Primary fails (after OnError) or returns fewer than Limit candidates. Recommender decides whether to fill after its policy filters, so excluded candidates do not count.
func (Fallback) ForSubject ¶
func (Fallback) Similar ¶
func (f Fallback) Similar(ctx context.Context, anchor contentref.ContentRef, q Query) ([]Candidate, error)
type Filter ¶ added in v0.83.0
type Filter struct {
Kind string
// Groups are all required (effective on the card's version); a position
// sort orders by the first.
Groups []string
ExcludeGroups []string
// Traits are all required on the card's version.
Traits []string
// Attributes are "name:value" equalities on Kind's declared filterable
// attributes, all required.
Attributes []string
// ReleasedOn is a day (YYYY-MM-DD) or month (YYYY-MM) of publication in
// TimeZone.
ReleasedOn string
// TimeZone is an IANA zone; UTC by default.
TimeZone string
// ViewStatus is unseen, in_progress or completed: the signed-in
// reader's own.
ViewStatus string
// OwnerGroups keeps content one of these groups owns (a channel's feed);
// owning is not membership and opens nothing.
OwnerGroups []string
}
Filter selects contents: what lists, search and release dates share.
type FilterSetting ¶ added in v0.83.0
FilterSetting shows or hides one configured filter's group.
type HistoryOptions ¶ added in v0.83.0
type HistoryOptions struct {
Reader
Kind string
// Status is seen, in_progress or completed; anything they touched by
// default.
Status string
CardGroups []string
Cursor string
// Limit defaults to 24 and is capped at 100.
Limit int
}
HistoryOptions select one page of the signed-in reader's history.
type Hit ¶
type Hit struct {
contentref.ContentRef
Score float32
}
Hit is one ranked work of a discovery list.
type ImportSignal ¶ added in v0.83.0
type ImportSignal struct {
ContentID string
VersionID string
Subject signal.Subject
Type string
EventID string
Revision uint64
OccurredAt time.Time
DurationS uint32
Progress uint32
Resume string
}
ImportSignal is a recorded event as the bulk import replays it: its subject given, scored as RecordSignals scores a client's.
type Interaction ¶ added in v0.83.0
type Interaction struct {
Content *Card `json:"content,omitempty"`
Group *groups.GroupCard `json:"group,omitempty"`
// Value is the reaction: 1 like, -1 dislike; 1 for a favorite.
Value int16 `json:"value"`
// At is when the reader favorited or last reacted.
At time.Time `json:"at"`
}
Interaction is one content item or group the reader favorited or reacted to, as its card shows it now.
type InteractionPage ¶ added in v0.83.0
type InteractionPage struct {
Items []Interaction `json:"items"`
// NextCursor pages on; empty on the last page.
NextCursor string `json:"next_cursor,omitempty"`
}
InteractionPage is one page of the reader's favorites or reactions, most recent first.
type ListOptions ¶ added in v0.83.0
type ListOptions struct {
Reader
Filter
// Sort is newest, oldest, title, popular[:period], top_rated[:period],
// most_favorited, most_viewed, position or random; the kind's configured
// sort, else newest, by default. Periods are popularity.Periods.
Sort string
// CardGroups are the group kinds cards name; every kind with a page by
// default.
CardGroups []string
Cursor string
// Limit defaults to 24 and is capped at 100.
Limit int
}
ListOptions select one page of a list.
type MineOptions ¶ added in v0.83.0
type MineOptions struct {
Reader
// Target is contents (the default) or groups.
Target string
// Kind is one content kind or group kind; every kind by default.
Kind string
// Value narrows reactions: like or dislike; both by default.
Value string
CardGroups []string
Cursor string
// Limit defaults to 24 and is capped at 100.
Limit int
}
MineOptions select one page of the signed-in reader's favorites or reactions.
type Options ¶ added in v0.83.0
type Options struct {
Pool *pgxpool.Pool
Schema string
Tenant string
Kinds kinds.Config
// Visibility is the catalog's visibility rule; every read applies it.
Visibility Visibility
// Resolver decides direct reads: the anchor of a similar list and the
// content a signal names.
Resolver resolve.Resolver
// Gate decides each card's access.
Gate *access.Gate
// Groups names the groups on cards and in typeahead.
Groups *groups.Store
// Covers resolves cards' covers; nil leaves them out.
Covers Covers
// Sales fills cards' paywall offers; nil leaves them out.
Sales Sales
// Hub is the keyword search client and the signal plane. Without a
// signal plane, history, signals, exposures, view_status, similar,
// recommendations and popularity are unavailable.
Hub *hub.Hub
// Candidates sources similar and recommendations; nil is co-engagement
// over the signal plane.
Candidates Candidates
// Policy ranks popular sorts; zero is popularity.PolicyV1.
Policy popularity.Policy
Logger *slog.Logger
Now func() time.Time
}
Options configure a Service.
type Query ¶
type Query struct {
// ContentKinds limits candidate kinds (empty = any).
ContentKinds []string
// Limit is the number of results the caller returns after filtering.
Limit int
// Window bounds the evidence (zero = all time).
Window signal.Window
// SeedLimit and SeedContentKinds bound which of the subject's history
// informs ForSubject (0 / empty = implementation default).
SeedLimit int
SeedContentKinds []string
}
Query bounds one candidate request.
type Reader ¶ added in v0.83.0
type Reader struct {
Actor access.Actor
// Host is the request's host: it picks the site scope.
Host string
// Language lists only content with a live version serving it.
Language string
// DisplayLanguage is the language of titles and group names and the
// preferred language of each card's version; Language, else the site's
// first.
DisplayLanguage string
// Mode is lock (the default) or hide.
Mode access.Mode
}
Reader is who reads, on which site, in which language.
type RecentSearch ¶ added in v0.83.0
type RecentSearch struct {
Query string `json:"query"`
// Results is how many cards its first page showed.
Results int `json:"results"`
SearchedAt time.Time `json:"searched_at"`
}
RecentSearch is one query the reader searched.
type RecentSearches ¶ added in v0.83.0
type RecentSearches struct {
Searches []RecentSearch `json:"searches"`
}
RecentSearches is the reader's recent searches, newest first.
type RecommendOptions ¶
type RecommendOptions struct {
// ContentKinds are the candidate kinds to recommend. Required.
ContentKinds []string
// Limit caps results (default: Recommender.DefaultLimit).
Limit int
// SeedLimit is how many of the subject's highest-signal works inform
// candidates (source default; Engagement: 5).
SeedLimit int
// SeedContentKinds limits which kinds may seed (default: any).
SeedContentKinds []string
// IncludeSeen keeps already-seen works in results (default: excluded).
IncludeSeen bool
// PopularWindow is the popularity window used to fill out results on
// cold start or thin candidate sets (zero = all time, like every Window).
PopularWindow signal.Window
// Admit keeps the works the reader may be shown; nil admits all.
Admit Admit
}
RecommendOptions controls Recommend ("for you": subject → works).
type RecommendationOptions ¶ added in v0.83.0
type RecommendationOptions struct {
Reader
Filter
CardGroups []string
// Limit defaults to 12 and is capped at 50.
Limit int
}
RecommendationOptions select a similar or "for you" list.
type Recommender ¶
type Recommender struct {
Candidates Candidates
Store *signal.Store
Tenant string
// DefaultLimit applies when options leave Limit zero (default 20).
DefaultLimit int
// RRFK scales popularity-fill tail scores (default 60).
RRFK int
}
Recommender turns a Candidates source into tenant-scoped discovery lists.
func (Recommender) Recommend ¶
func (r Recommender) Recommend(ctx context.Context, subject signal.Subject, opts RecommendOptions) ([]Hit, error)
Recommend returns "for you" works for a subject: excluding already-seen (unless IncludeSeen) and always disliked works, filled from popularity on cold start or thin candidates.
func (Recommender) Similar ¶
func (r Recommender) Similar(ctx context.Context, anchor contentref.ContentRef, opts SimilarOptions) ([]Hit, error)
Similar returns works like the anchor, never the anchor itself.
type ReleaseDates ¶ added in v0.83.0
type ReleaseDates struct {
Dates []DateCount `json:"dates"`
NextCursor string `json:"next_cursor,omitempty"`
}
ReleaseDates is one page of the index, newest first.
type ReleaseDatesOptions ¶ added in v0.83.0
type ReleaseDatesOptions struct {
Reader
Filter
// By is month (the default) or day.
By string
// Cursor is the previous page's next_cursor: dates before it follow.
Cursor string
// Limit defaults to 60 and is capped at 1000.
Limit int
}
ReleaseDatesOptions select the release date index.
type Sales ¶ added in v0.83.0
Sales answers the purchasable offers selling paywalls' keys, by key: *offers.Service.
type SearchOptions ¶ added in v0.83.0
type SearchOptions struct {
Reader
Filter
Query string
// Sort is relevance (the default) or a list sort of the best matches.
Sort string
CardGroups []string
Cursor string
// Limit defaults to 24 and is capped at 100.
Limit int
// Unpersonalized ranks a signed-in reader's results as anyone's.
Unpersonalized bool
}
SearchOptions select one page of keyword search.
type Service ¶ added in v0.83.0
type Service struct {
// contains filtered or unexported fields
}
Service serves discovery for one tenant.
func (*Service) ClearSearches ¶ added in v0.83.0
func (s *Service) ClearSearches(ctx context.Context, actor access.Actor, session, query string) error
ClearSearches hides the reader's recent searches: one query, or all of them until now.
func (*Service) ContentFilters ¶ added in v0.83.0
func (s *Service) ContentFilters(ctx context.Context, actor access.Actor, language string) (ContentFilters, error)
ContentFilters is the signed-in reader's content filters: every configured filter whose group exists, labeled in language.
func (*Service) EraseSearches ¶ added in v0.83.0
EraseSearches deletes subjects' recent searches and markers.
func (*Service) Favorites ¶ added in v0.83.0
func (s *Service) Favorites(ctx context.Context, o MineOptions) (InteractionPage, error)
Favorites pages what the signed-in reader favorited, most recent first: the content items their listing shows (one card per item, whichever version they favorited) or the active groups.
func (*Service) ForgetHistory ¶ added in v0.83.0
func (s *Service) ForgetHistory(ctx context.Context, actor access.Actor, kind, contentID string) error
ForgetHistory erases the signed-in reader's signals for one content item, one kind, or every kind.
func (*Service) Handler ¶ added in v0.83.0
Handler serves the discovery routes: lists, search, typeahead, similar and "for you" lists, the release date index, the reader's content filters and history, and the signals and exposures clients send. a says who each request is; each request runs in access.WithMemo, so a page costs one billing read.
func (*Service) History ¶ added in v0.83.0
func (s *Service) History(ctx context.Context, o HistoryOptions) (ContentPage, error)
History pages the contents the signed-in reader engaged with, most recent first, as their listing shows them now.
func (*Service) ImportSignals ¶ added in v0.83.0
func (s *Service) ImportSignals(ctx context.Context, in []ImportSignal) error
ImportSignals records imported events in the signal plane, without a visibility check: a view on a version also counts for its content. ErrNoSignals without a signal plane.
func (*Service) List ¶ added in v0.83.0
func (s *Service) List(ctx context.Context, o ListOptions) (ContentPage, error)
List pages cards: one per content item the reader's listing shows that matches the filter, in the sort's order.
func (*Service) PruneSearches ¶ added in v0.83.0
PruneSearches deletes recent searches hidden by a clear, of erased people, or unused for SearchRetention, then the markers they no longer need. It returns how many searches it deleted.
func (*Service) Reactions ¶ added in v0.83.0
func (s *Service) Reactions(ctx context.Context, o MineOptions) (InteractionPage, error)
Reactions pages what the signed-in reader liked or disliked, most recently changed first, as Favorites does: tag affinities and preferences read it.
func (*Service) RecentSearches ¶ added in v0.83.0
func (s *Service) RecentSearches(ctx context.Context, actor access.Actor, session string, limit int) (RecentSearches, error)
RecentSearches lists the reader's recent searches since their last clear.
func (*Service) Recommendations ¶ added in v0.83.0
func (s *Service) Recommendations(ctx context.Context, o RecommendationOptions) (ContentPage, error)
Recommendations lists contents for the signed-in reader from their history, filled from what is popular, that their listing shows; seen and disliked content left out.
func (*Service) RecordExposures ¶ added in v0.83.0
RecordExposures records result lists for click attribution.
func (*Service) RecordSearch ¶ added in v0.83.0
func (s *Service) RecordSearch(ctx context.Context, actor access.Actor, session, query string, results int) error
RecordSearch keeps a query the reader searched; a signed-out reader without a session, or an erased person, keeps none.
func (*Service) RecordSignals ¶ added in v0.83.0
RecordSignals records a client's events: a view on a version also counts for its content. A view is scored against its version's own size (popularity.SessionScore), so it completes at 90% of its pages, duration or scroll.
func (*Service) RefreshPopularity ¶ added in v0.83.0
RefreshPopularity copies the signal plane's popularity into content_facets.popularity, so popular and windowed top_rated sorts are one Postgres query under any filter: each period's policy score, each window's rating (the Wilson lower bound of the subjects whose feedback in it is positive) and all-time viewers. Run it periodically (the engine's contentkit_popularity job).
func (*Service) ReleaseDates ¶ added in v0.83.0
func (s *Service) ReleaseDates(ctx context.Context, o ReleaseDatesOptions) (ReleaseDates, error)
ReleaseDates counts the contents the reader's listing shows by the day or month they were published, newest first.
func (*Service) Search ¶ added in v0.83.0
func (s *Service) Search(ctx context.Context, o SearchOptions) (ContentPage, error)
Search pages the contents matching a keyword query, grouped per content item, under the reader's visibility and the filter.
func (*Service) SetContentFilters ¶ added in v0.83.0
func (s *Service) SetContentFilters(ctx context.Context, actor access.Actor, u ContentFiltersUpdate) error
SetContentFilters replaces the signed-in reader's settings; each names a configured filter's group.
func (*Service) SignalPlane ¶ added in v0.83.0
SignalPlane reports whether signals are recorded.
func (*Service) Similar ¶ added in v0.83.0
func (s *Service) Similar(ctx context.Context, anchorID string, o RecommendationOptions) (ContentPage, error)
Similar lists contents like the anchor content that the reader's listing shows; of the anchor's kind unless the filter names one.
type SignalInput ¶ added in v0.83.0
type SignalInput struct {
ContentID string `json:"content_id"`
VersionID string `json:"version_id,omitempty"`
// Type is view or click.
Type string `json:"type"`
// EventID is the client's stable identity of the event; retries reuse it.
EventID string `json:"event_id"`
// Revision orders cumulative snapshots of one view.
Revision uint64 `json:"revision,omitempty"`
OccurredAt time.Time `json:"occurred_at"`
DurationS uint32 `json:"duration_s,omitempty"`
// Progress is pages read (reader kinds), seconds watched (player kinds)
// or percent scrolled (post kinds).
Progress uint32 `json:"progress,omitempty"`
Resume string `json:"resume,omitempty"`
// RenderID, Surface and Position attribute it to an exposure.
RenderID string `json:"render_id,omitempty"`
Surface string `json:"surface,omitempty"`
Position uint32 `json:"position,omitempty"`
}
SignalInput is one event on a content item or one of its versions.
type Signals ¶ added in v0.83.0
type Signals struct {
Session string `json:"session,omitempty"`
Signals []SignalInput `json:"signals"`
}
Signals is what a client reports, for the signed-in reader or, signed out, for the browser session Session names.
type SimilarOptions ¶
type SimilarOptions struct {
Limit int
// ContentKinds limits result kinds (default: any).
ContentKinds []string
// Window bounds the candidate evidence (default all time).
Window signal.Window
// ExcludeSeenFor drops works this subject has already seen (and always
// drops works they negatively reacted to).
ExcludeSeenFor *signal.Subject
// Admit keeps the works the reader may be shown; nil admits all.
Admit Admit
}
SimilarOptions controls Similar ("more like this").
type Typeahead ¶ added in v0.83.0
type Typeahead struct {
Contents []Card `json:"contents"`
Groups []groups.GroupCard `json:"groups"`
}
Typeahead is the suggestions: content cards and groups, best first.
type TypeaheadOptions ¶ added in v0.83.0
type TypeaheadOptions struct {
Reader
Query string
// Kind limits content suggestions to one kind.
Kind string
// GroupKinds are the group kinds suggested; every kind with a page by
// default.
GroupKinds []string
// Limit is per section: 8 by default, at most 20.
Limit int
}
TypeaheadOptions select suggestions while a reader types.
type ViewerState ¶ added in v0.83.0
type ViewerState struct {
Favorited bool `json:"favorited"`
// Seen, Completed and Progress come from the signal plane.
Seen bool `json:"seen"`
Completed bool `json:"completed"`
Progress uint32 `json:"progress"`
ProgressMax uint32 `json:"progress_max"`
Resume string `json:"resume,omitempty"`
LastViewAt *time.Time `json:"last_view_at,omitempty"`
}
ViewerState is the signed-in reader's own standing with a content item.
type Visibility ¶ added in v0.83.0
type Visibility interface {
Viewer(ctx context.Context, o catalog.ViewerOptions) (*catalog.Viewer, error)
}
Visibility is the catalog's one visibility rule (engine spec §4): *catalog.Store. A request's Viewer renders it as SQL over content_facets.