discovery

package
v0.83.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 13, 2026 License: MIT Imports: 38 Imported by: 0

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

View Source
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.

View Source
const (
	TargetContents = "contents"
	TargetGroups   = "groups"
)

Interaction targets: content items or groups.

View Source
const (
	Unseen     = "unseen"
	InProgress = "in_progress"
	Completed  = "completed"
)

View statuses.

View Source
const (
	SortNewest        = "newest"
	SortOldest        = "oldest"
	SortTitle         = "title"
	SortPopular       = "popular"
	SortTopRated      = "top_rated"
	SortMostFavorited = "most_favorited"
	SortMostViewed    = "most_viewed"
	SortPosition      = "position"
	SortRandom        = "random"
)

Sorts.

View Source
const PopularityDepth = 100_000

PopularityDepth bounds the contents per kind and period that carry a popularity score; the rest sort as unviewed.

View Source
const SearchRetention = 180 * 24 * time.Hour

SearchRetention is how long a recent search is kept after its last use.

View Source
const SortRelevance = "relevance"

SortRelevance orders search results by match, personalized for a signed-in reader.

Variables

View Source
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 (f Fallback) ForSubject(ctx context.Context, subject signal.Subject, q Query) ([]Candidate, error)

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

type FilterSetting struct {
	GroupID string `json:"group_id"`
	Visible bool   `json:"visible"`
}

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 Placement added in v0.83.0

type Placement struct {
	ContentID string `json:"content_id"`
	Position  uint32 `json:"position"`
}

Placement is one shown content item at its 1-based position.

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

type Sales interface {
	Sales(ctx context.Context, keys []string) (map[string]offers.Sale, error)
}

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 New added in v0.83.0

func New(o Options) (*Service, error)

New validates o.

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

func (s *Service) EraseSearches(ctx context.Context, subjects []signal.Subject) error

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

func (s *Service) Handler(a auth.Authenticator) (http.Handler, error)

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

func (s *Service) PruneSearches(ctx context.Context) (int, error)

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

func (s *Service) RecordExposures(ctx context.Context, actor access.Actor, in Exposures) error

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

func (s *Service) RecordSignals(ctx context.Context, actor access.Actor, in Signals) error

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

func (s *Service) RefreshPopularity(ctx context.Context) error

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

func (s *Service) SignalPlane() bool

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.

func (*Service) Typeahead added in v0.83.0

func (s *Service) Typeahead(ctx context.Context, o TypeaheadOptions) (Typeahead, error)

Typeahead suggests contents the reader's listing shows and active groups, tolerating typos and partial words.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL