Documentation
¶
Overview ¶
Package versions publishes content versions and binds their optional media. A kind's media items are its versions, {kind, content, version}; a content has none of its own. This package answers media's hooks from the content model (who uploads, who reads, the facts a version's media yields), records immutable ready-file snapshots for viewers (chapter metadata, signed previews and playback), and serves the reader plan, reader metadata and downloads. Each version receives its own explicit uploads.
Whether a viewer sees, opens or edits a content or a version is the catalog's decision over the access gate, ContentKit's own resolve.Resolver; this package adds segments' release and the rule's preview to it. The listing projection is refreshed through Facets.
Index ¶
- Constants
- Variables
- func ChapterPathHooks(pool *pgxpool.Pool, schema string, registry *media.Registry, ...) media.Hooks
- func EncodeReleaseBaseline(target Target, kind, state, parentState string, desired, released access.Rule) ([]byte, error)
- func EntityOwner(kind, id string) string
- func LockSource(ctx context.Context, pool *pgxpool.Pool, tenant, version string) (func(), error)
- func LockSources(ctx context.Context, pool *pgxpool.Pool, tenant string, versions []string) (func(), error)
- func MigrateReaderSnapshots(ctx context.Context, pool *pgxpool.Pool, schema, tenant, riverSchema string, ...) error
- func ParseEntityOwner(owner string) (kind, id string, ok bool)
- func PrepareDerivatives(pool *pgxpool.Pool, schema string, manifests *media.Manifests, ...) func(context.Context, contentref.ContentRef) error
- func ProcessingPublisher(pool *pgxpool.Pool, riverSchema, contentSchema string, ...) (func(context.Context, pgx.Tx, contentref.ContentRef) error, error)
- func QueueFor(catalog string) string
- func RetirementBarrier(pool *pgxpool.Pool, schema string, registry *media.Registry) func(context.Context, contentref.ContentRef, *media.Manifest) error
- type Anchor
- type Archive
- type ArchiveRequest
- type BackgroundCue
- type CoverOf
- type DownloadDecision
- type DownloadEntity
- type DownloadPolicy
- type DownloadRequest
- type Downloads
- type Facets
- type FileDownload
- type ForegroundCue
- type Media
- type MediaPending
- type NoticePage
- type Options
- type Others
- type PageNotice
- type PageNotices
- type PageSpan
- type Pending
- type PlanPage
- type PlanPlayback
- type PlanPreview
- type PlanSegment
- type PlanTrack
- type Quota
- type QuotaError
- type ReaderDefaults
- type ReaderMeta
- type ReaderPlan
- type ReleaseRequest
- type Service
- func (s *Service) Archive(ctx context.Context, request ArchiveRequest) (*Archive, error)
- func (s *Service) Bind(m Media) error
- func (s *Service) CheckRestorableTx(ctx context.Context, tx pgx.Tx, targets []Target) error
- func (s *Service) Covers(ctx context.Context, covers []CoverOf) ([][]media.PublicRendition, error)
- func (s *Service) Delete(ctx context.Context, targets []Target) error
- func (s *Service) DeleteTx(ctx context.Context, tx pgx.Tx, targets []Target) error
- func (s *Service) DismissPageNotice(ctx context.Context, actor access.Actor, t Target, id string) error
- func (s *Service) Download(ctx context.Context, actor access.Actor, t Target) (*FileDownload, error)
- func (s *Service) EntityCovers() entities.CoverResolver
- func (s *Service) EntityFolders() entities.Folders
- func (s *Service) Handler(a auth.Authenticator, log *slog.Logger) (http.Handler, error)
- func (s *Service) Hooks() media.Hooks
- func (s *Service) Ladder(kind string) string
- func (s *Service) PageNotices(ctx context.Context, actor access.Actor, t Target) (PageNotices, error)
- func (s *Service) PendingTx(ctx context.Context, q pgx.Tx, targets []Target) ([]MediaPending, error)
- func (s *Service) Plan(ctx context.Context, actor access.Actor, t Target) (*ReaderPlan, error)
- func (s *Service) RepublishTx(ctx context.Context, tx pgx.Tx, targets []Target) error
- func (s *Service) RestorePageNotice(ctx context.Context, actor access.Actor, t Target, id string) (PageNotices, error)
- func (s *Service) ResumeDeletes(ctx context.Context, limit int) (int, error)
- func (s *Service) RiverJobs() riverhelpers.Contribution
- func (s *Service) SchedulePublicationTx(ctx context.Context, tx pgx.Tx, targets []Target) error
- func (s *Service) SetReaderMeta(ctx context.Context, actor access.Actor, t Target, rm ReaderMeta) error
- func (s *Service) ValidateChapterStartsTx(ctx context.Context, tx pgx.Tx, target Target, starts []string) error
- func (s *Service) WithChapterLocks(ctx context.Context, targets []Target, fn func() error) error
- type Target
- type TierQuota
- type UnavailableError
Constants ¶
const ( // CodeNoDownload is a version without the file its kind's download serves. CodeNoDownload = "no_download" CodeDownloadUnavailable = "download_unavailable" )
Download refusals.
const DefaultDownloadTTL = 5 * time.Minute
DefaultDownloadTTL is how long a file download's URL opens its file: long enough to start the transfer, which then runs to its end.
const Queue = "contentkit_versions"
Queue is the River queue of version publication and optional media jobs.
Variables ¶
var ( // ErrNotFound is a content or version that does not exist, or that the // viewer may not see. ErrNotFound = errors.New("versions: not found") // ErrNotReady is a version whose media is still processing or not yet published. ErrNotReady = errors.New("versions: media not ready") // ErrNoDownload is a version without the file its kind's download // serves: nothing uploaded, or an upload that failed or was dropped. ErrNoDownload = errors.New("versions: no download") // ErrForbidden is what the viewer sees but may not do. ErrForbidden = errors.New("versions: forbidden") // ErrInvalid is a malformed request. ErrInvalid = errors.New("versions: invalid") )
Functions ¶
func ChapterPathHooks ¶ added in v0.128.0
func ChapterPathHooks(pool *pgxpool.Pool, schema string, registry *media.Registry, wake func(context.Context, pgx.Tx, contentref.ContentRef) error) media.Hooks
ChapterPathHooks installs the same marker contract in stock worker recovery. The journal must not settle a recovered rename without its catalog update.
func EncodeReleaseBaseline ¶ added in v0.131.0
func EncodeReleaseBaseline(target Target, kind, state, parentState string, desired, released access.Rule) ([]byte, error)
EncodeReleaseBaseline represents a previously completed edition without storage. It records the policy already served, never today's evaluation of desired access. Migration persists it without invoking completion or events.
func EntityOwner ¶ added in v0.117.0
EntityOwner is the quota owner of an entity's uploads: "{kind}:{id}".
func LockSource ¶ added in v0.99.0
LockSource serializes source selection with catalog segment writes. Acquire it before a SQL transaction/row lock; manifest commits may notify the catalog.
func LockSources ¶ added in v0.99.0
func LockSources(ctx context.Context, pool *pgxpool.Pool, tenant string, versions []string) (func(), error)
LockSources serializes source selection and catalog segment writes before either takes row locks. A batch uses one dedicated connection, leaving the caller's pool available for manifest commits and catalog notifications.
func MigrateReaderSnapshots ¶ added in v0.114.0
func MigrateReaderSnapshots(ctx context.Context, pool *pgxpool.Pool, schema, tenant, riverSchema string, reg *media.Registry) error
MigrateReaderSnapshots recovers ready versions without a metadata snapshot through the ordinary durable publisher. It performs no object-store work and adds no recurring repair job. Completed snapshots are untouched on rerun.
func ParseEntityOwner ¶ added in v0.117.0
ParseEntityOwner is EntityOwner's kind and id; ok is false for any other owner.
func PrepareDerivatives ¶ added in v0.131.0
func PrepareDerivatives(pool *pgxpool.Pool, schema string, manifests *media.Manifests, uploads *media.Uploads) func(context.Context, contentref.ContentRef) error
PrepareDerivatives prepares page order and automatic cover inputs inside the existing derivative attempt. Drafts get the same preparation without publishing.
func ProcessingPublisher ¶ added in v0.126.1
func ProcessingPublisher(pool *pgxpool.Pool, riverSchema, contentSchema string, registry *media.Registry) (func(context.Context, pgx.Tx, contentref.ContentRef) error, error)
ProcessingPublisher wakes the accepted release from a processor's completion transaction, including stock external workers. It preserves its requested date and a follow-up when an older snapshot job is already running.
func QueueFor ¶ added in v0.128.0
QueueFor is the edition-worker queue for one immutable catalog key. The media tenant/app path partition is not necessarily this catalog key.
func RetirementBarrier ¶ added in v0.115.0
func RetirementBarrier(pool *pgxpool.Pool, schema string, registry *media.Registry) func(context.Context, contentref.ContentRef, *media.Manifest) error
RetirementBarrier supplies the catalog-side media barrier to standalone workers. It shares the exact withdrawal logic used by embedded writers; workers need no authentication or application callbacks to retire a file.
Types ¶
type Anchor ¶
type Anchor struct {
ID string `json:"id"`
Page string `json:"page"`
OffsetPercent float64 `json:"offset_percent"`
DurationSeconds *float64 `json:"duration_seconds,omitempty"`
}
Anchor is a scroll position within a page of the vertical reader.
type Archive ¶
type Archive struct {
Name string // the attachment's file name
Type string // application/zip, or the configured single file's content type
Size int64 // single-file size; ZIPs stream without a known size
// contains filtered or unexported fields
}
Archive is an authorized ZIP or exact configured single-file transfer.
type ArchiveRequest ¶ added in v0.107.0
type ArchiveRequest struct {
Target
Viewer, Account string
AccountSet bool
Kind auth.SubjectKind
Editor bool
Claims []string
Mark, Name, Revision, Ticket string
Pages int // exact authorized ZIP prefix; bound into the ticket
File bool // the configured exact single-file download, never a caller-supplied path
}
ArchiveRequest is the signed download grant's selectors. Editor delegates only this exact transfer until ticket expiry, like a private media URL. It never creates a session or reusable permission checker. Claims retain only configured token-tier entitlements for this verified transfer.
type BackgroundCue ¶
type BackgroundCue struct {
File string `json:"file"`
FromPage *string `json:"from_page,omitempty"`
ToPage *string `json:"to_page,omitempty"`
FromAnchor *string `json:"from_anchor,omitempty"`
ToAnchor *string `json:"to_anchor,omitempty"`
Loop *bool `json:"loop,omitempty"`
Layer *string `json:"layer,omitempty"`
}
BackgroundCue plays a track over a range of pages or anchors.
type CoverOf ¶
type CoverOf struct {
Kind string
ID string
Image string
ContentID string
Version string
Language string
Preset string
}
CoverOf names a content's or an entity's cover: Kind and ID are its owner; Image an image uploaded to the owner's item ("i-{uuid}"), else ContentID a content whose cover it shows; with neither, a content owner's own. A content's cover is its Version's, else its default edition's in Language (internal/edition). With Preset media.AvatarPreset it names an entity's avatar: Image, else the item's first, else the kind's default.
type DownloadDecision ¶ added in v0.87.0
type DownloadDecision struct {
Allowed bool
// A refusal's stable code of the host's ("release_window") and, when it
// is a matter of time, when the viewer may download.
Reason string
AvailableAt *time.Time
// Mark are the pages (from 1) of a page download to mark; files ignore it.
Mark []int
// Name is the download's file name without its extension; "" keeps
// ContentKit's. ContentKit cleans and bounds it.
Name string
}
DownloadDecision is a policy's ruling.
type DownloadEntity ¶ added in v0.117.0
DownloadEntity is an entity of a download's version, named in its language, else the site's default, else another, else by its slug, with its attributes.
type DownloadPolicy ¶ added in v0.87.0
type DownloadPolicy interface {
// Decide rules on a download after the access check, before the quota.
Decide(ctx context.Context, r DownloadRequest) (DownloadDecision, error)
// Mark returns page's (from 1) marked bytes for actor and their
// extension (".png"): a page Decide named.
Mark(ctx context.Context, actor access.Actor, v Target, page int, b []byte) ([]byte, string, error)
}
DownloadPolicy is the host's download policy: whether a viewer may download a version now, and which pages of a page download it marks with its own watermark. ContentKit asks; the host decides.
type DownloadRequest ¶ added in v0.87.0
type DownloadRequest struct {
Actor access.Actor
Tiers []string // the tiers Actor holds
Editor bool // Actor edits the version
Target
Kind string
// Language is the version's language; Title is its title, in Language
// when it has one there (its content's id when it has none).
Language, Title string
// Entities are the version's entities, its own and its content's.
Entities []DownloadEntity
// Rule is the version's effective access rule.
Rule access.Rule
// Released is when the version went live; zero while it is not.
Released time.Time
// Pages are a page download's pages; 0 for a file.
Pages int
}
DownloadRequest is a download Decide rules on.
type Downloads ¶
type Downloads struct {
Anonymous []Quota `json:"anonymous,omitempty" yaml:"anonymous"`
User []Quota `json:"user,omitempty" yaml:"user"`
Tiers []TierQuota `json:"tiers,omitempty" yaml:"tiers"`
// TTL is how long a file download's URL opens its file; 0 is DefaultDownloadTTL.
TTL time.Duration `json:"ttl,omitempty" yaml:"ttl"`
// Redis shares the counts across replicas; nil keeps them per process.
Redis redis.UniversalClient `json:"-" yaml:"-"`
}
Downloads are the download quotas: an anonymous viewer's (by address), a signed-in one's, and the first of Tiers a viewer holds, which replaces User. A bucket without quotas is unlimited.
type Facets ¶
Facets refreshes the listing projection of versions whose derived media facts changed, in the writing transaction.
type FileDownload ¶ added in v0.87.0
type FileDownload struct {
URL string `json:"url"`
Name string `json:"name"`
Type string `json:"type"`
Size int64 `json:"size,omitempty"`
ExpiresAt time.Time `json:"expires_at"`
}
FileDownload is a granted download. URL serves it as an attachment named Name until ExpiresAt (a transfer begun runs to its end): the media host's URL of a file, or this module's archive route relative to the download route ("archive?..."). Size is 0 for archives: they stream on demand.
type ForegroundCue ¶
type ForegroundCue struct {
File string `json:"file"`
Page *string `json:"page,omitempty"`
Anchor *string `json:"anchor,omitempty"`
}
ForegroundCue plays a whole track at a page or anchor.
type Media ¶
type Media struct {
Manifests *media.Manifests
Uploads *media.Uploads
Jobs *media.Jobs
Reader *media.Reader // signs file downloads; nil serves none
}
Media is the media runtime built over Service.Hooks.
type MediaPending ¶ added in v0.104.0
MediaPending is what keeps a version's media from going live: files still processing in its manifest, or a publication not yet current for them.
type NoticePage ¶ added in v0.104.0
type NoticePage struct {
ID string `json:"id"`
SourceName string `json:"source_name"`
Reason string `json:"reason,omitempty"`
From int `json:"from,omitempty"`
To int `json:"to,omitempty"`
PreviewURL string `json:"preview_url,omitempty"`
}
NoticePage is one page a notice concerns. A removed page names why (blank, duplicate or spread); a reordered page gives its archive position and the position applied.
type Options ¶
type Options struct {
Tenant string // the content tables' tenant
Schema string // ContentKit's schema
Pool *pgxpool.Pool
Kinds kinds.Config // the site's content and entity kinds
Auth auth.Authenticator // the host's: staff and group scope checks
// MediaConfigured requires Bind before a release can run. A service without
// media still owns publication requests, completed access and deadlines.
MediaConfigured bool
// AccountExists verifies avatar targets in this tenant's account directory.
// Scoped engines install it; nil preserves the legacy host contract.
AccountExists func(context.Context, string) (bool, error)
// Resolver decides versions ({kind, content, version}) for a viewer:
// Visible (live, or edited by them), Accessible (opened by them) and
// Editor.
Resolver resolve.Resolver
// Gate answers the tiers a viewer holds for download quotas; optional.
Gate *access.Gate
Facets Facets
Others Others // nil refuses every other kind
Policy DownloadPolicy // the host's download policy; nil allows every download and marks none
Downloads Downloads
Logger *slog.Logger
Now func() time.Time
}
Options configure a Service.
type Others ¶
type Others interface {
resolve.Resolver
media.UploadAuthorizer
}
Others answer the media kinds of neither contents nor groups: posts' and polls' images.
type PageNotice ¶ added in v0.104.0
type PageNotice struct {
ID string `json:"id"`
Kind string `json:"kind"` // removed | reordered
Pages []NoticePage `json:"pages"`
}
PageNotice is a quiet note about an automatic page change: removed pages (blank, duplicate, or a single covered by a two-page spread) can be restored, and an archive reordered into natural name order can be dismissed. Neither ever blocks saving or publishing.
type PageNotices ¶ added in v0.104.0
type PageNotices struct {
Notices []PageNotice `json:"notices"`
Cookie *http.Cookie `json:"-"`
}
PageNotices are a version's undismissed notices, for its editors.
type PageSpan ¶ added in v0.99.0
PageSpan is a printed page range; a spread is still one reader image.
type Pending ¶
type Pending struct {
Status string `json:"status"` // "pending"
}
Pending answers a version whose media is still being prepared: retry.
type PlanPage ¶
type PlanPage struct {
ID string `json:"id"` // original image SHA-256; the canonical page identity
Name string `json:"name"`
Span *PageSpan `json:"span,omitempty"`
W int `json:"w"`
H int `json:"h"`
Files map[string]string `json:"files"`
}
PlanPage is one page of an open segment: its name, reading size and the path of each rendition in the segment's item.
type PlanPlayback ¶
type PlanPlayback struct {
Item media.RefBody `json:"item"`
Tracks []PlanTrack `json:"tracks"`
Inspection bool `json:"inspection,omitempty"`
}
PlanPlayback is the version's audio item and its tracks.
type PlanPreview ¶
type PlanPreview struct {
ID string `json:"id"` // original image SHA-256
Index int `json:"index"`
Name string `json:"name"`
URL string `json:"url"`
W int `json:"w"`
H int `json:"h"`
}
PlanPreview is a public preview of a leading page.
type PlanSegment ¶
type PlanSegment struct {
Position *int `json:"position,omitempty"`
Title string `json:"title,omitempty"`
Start int `json:"start"`
End int `json:"end"`
Released bool `json:"released"`
ReleaseAt *time.Time `json:"release_at,omitempty"`
Locked bool `json:"locked"`
Inspection bool `json:"inspection,omitempty"` // authorized prepared derivatives; fetch with explicit management read
Item *media.RefBody `json:"item,omitempty"` // read it at GET /media/{kind}/{id}
Pages []PlanPage `json:"pages,omitempty"`
}
PlanSegment is one span of pages: a segment's (Position set) or pages outside every segment.
type Quota ¶
type Quota struct {
Limit int `json:"limit" yaml:"limit"`
Per time.Duration `json:"per" yaml:"per"`
}
Quota admits at most Limit downloads in any Per.
type QuotaError ¶
QuotaError is a download refused by its viewer's quota.
func (*QuotaError) Error ¶
func (e *QuotaError) Error() string
type ReaderDefaults ¶
type ReaderDefaults struct {
AutoAdvanceSeconds float64 `json:"auto_advance_seconds,omitempty"`
}
type ReaderMeta ¶
type ReaderMeta struct {
SchemaVersion int `json:"schema_version"` // 1
Defaults *ReaderDefaults `json:"defaults,omitempty"`
Anchors []Anchor `json:"anchors,omitempty"`
Background []BackgroundCue `json:"background,omitempty"`
Foreground []ForegroundCue `json:"foreground,omitempty"`
}
ReaderMeta is a version's reader metadata, kept in its item's manifest: scroll anchors on its pages and audio cues on pages or anchors. Pages use original-image hashes; audio files retain their upload names.
type ReaderPlan ¶
type ReaderPlan struct {
NextReleaseAt *time.Time `json:"next_release_at,omitempty"`
Content string `json:"content_id"`
Version string `json:"version_id"`
Publication string `json:"publication_id"`
Pages *int `json:"pages,omitempty"`
Segments []PlanSegment `json:"segments"`
Previews []PlanPreview `json:"previews"`
Playback *PlanPlayback `json:"playback,omitempty"`
Reader *ReaderMeta `json:"reader,omitempty"`
Expires int64 `json:"expires,omitempty"` // signed preview URL expiry, Unix seconds
}
ReaderPlan is a ready version snapshot with live chapter metadata. Released spans select existing files in the same canonical version; their URLs are signed on demand. Locked previews sign only their permitted renditions.
type ReleaseRequest ¶ added in v0.128.0
type ReleaseRequest struct {
ID string
Target
ScheduledAt time.Time
State string
Current bool
Plan json.RawMessage
Result json.RawMessage
Error string
CompletedAt *time.Time
}
ReleaseRequest is one durable reconciliation attempt for an edition. Plan freezes only when execution starts. A newer current request never replaces the completed reader snapshot referenced by content_versions.release_id.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service owns publication for content versions and their optional media.
func (*Service) Archive ¶ added in v0.87.0
Archive opens the ZIP or single file a Download granted. The ticket binds its viewer, marks, name and exact ordered source revision. Access, publication, chapter release and policy are checked again, even when its ZIP is already cached.
func (*Service) CheckRestorableTx ¶ added in v0.126.0
CheckRestorableTx refuses a version after its permanent erasure claim, including a claim whose storage response or catalog transaction failed. Callers hold the same parent/version locks as DeleteTx.
func (*Service) Covers ¶
Covers resolves covers to their public renditions, per cover in order, in two queries for the page. A content's cover is the image its version's cover selects, else the version's first cover image, else its kind's default.
func (*Service) Delete ¶ added in v0.126.0
Delete erases the already-fenced exact versions. A stable operation ID preserves the original cleanup targets when a purge retries after failure.
func (*Service) DeleteTx ¶
DeleteTx permanently fences targets while their catalog rows are locked. The caller commits this claim before Delete erases storage, so retirement hooks never wait on catalog locks held by the erasing transaction.
func (*Service) DismissPageNotice ¶ added in v0.104.0
func (s *Service) DismissPageNotice(ctx context.Context, actor access.Actor, t Target, id string) error
DismissPageNotice hides a current notice; dismissing again is a no-op.
func (*Service) Download ¶
func (s *Service) Download(ctx context.Context, actor access.Actor, t Target) (*FileDownload, error)
Download grants t's download to actor, what its kind's download serves (kinds.Kind.Download), as the host's policy allows, and charges it to actor's quota. Page archives include only the released, authorized prefix; other files require whole-version access. ErrNotFound when the kind serves none, an UnavailableError when the policy refuses, ErrNoDownload when the version has nothing to serve, ErrNotReady while it is placed or produced, a QuotaError past the quota.
func (*Service) EntityCovers ¶ added in v0.117.0
func (s *Service) EntityCovers() entities.CoverResolver
EntityCovers is Covers for the entities API's cards and pages (entities.Options.Covers).
func (*Service) EntityFolders ¶ added in v0.117.0
EntityFolders hides, shows and deletes entities' media folders for the entities API (entities.Options.Folders).
func (*Service) Hooks ¶
Hooks are media's hooks over the content model; set them as media.Config.Hooks before building the registry.
func (*Service) Ladder ¶ added in v0.88.0
Ladder is the folder of the kind's first HLS ladder (a read's hls entry), "" when it streams none or one per upload.
func (*Service) PageNotices ¶ added in v0.104.0
func (s *Service) PageNotices(ctx context.Context, actor access.Actor, t Target) (PageNotices, error)
PageNotices returns a version's undismissed notices to its editors only.
func (*Service) PendingTx ¶ added in v0.104.0
func (s *Service) PendingTx(ctx context.Context, q pgx.Tx, targets []Target) ([]MediaPending, error)
PendingTx reports the versions whose media is not ready to go live. A version without uploads, or of a kind without versioned media, is ready. It reads manifests and q's publications and mutates nothing. Uploads a client has not committed yet are invisible here; editors guard those.
func (*Service) Plan ¶
Plan derives chapter spans from current metadata over an immutable file snapshot. Every span reads the same canonical version item.
func (*Service) RepublishTx ¶
RepublishTx queues versions' publication after their segments changed.
func (*Service) RestorePageNotice ¶ added in v0.104.0
func (s *Service) RestorePageNotice(ctx context.Context, actor access.Actor, t Target, id string) (PageNotices, error)
RestorePageNotice puts a removed notice's pages back where they were (an excluded source keeps its place) and clears the notice.
func (*Service) ResumeDeletes ¶ added in v0.126.0
ResumeDeletes keeps late-write cleanup in the content purge operation.
func (*Service) RiverJobs ¶
func (s *Service) RiverJobs() riverhelpers.Contribution
RiverJobs contributes the version release workers and queue to the host's River composition, beside media's own.
func (*Service) SchedulePublicationTx ¶ added in v0.128.0
SchedulePublicationTx accepts current catalog/manifest intent in the same transaction as its runnable River obligation. Empty Version expands to the gallery's editions; each remains an independent request and access boundary.
func (*Service) SetReaderMeta ¶
func (s *Service) SetReaderMeta(ctx context.Context, actor access.Actor, t Target, rm ReaderMeta) error
SetReaderMeta stores v's reader metadata for an editor: every page, anchor and file it names must exist.
func (*Service) ValidateChapterStartsTx ¶ added in v0.106.0
func (s *Service) ValidateChapterStartsTx(ctx context.Context, tx pgx.Tx, target Target, starts []string) error
ValidateChapterStartsTx checks authored starts against the current source manifest, including drafts whose renditions have not finished. The catalog caller holds the version's source lock before taking its row locks.
func (*Service) WithChapterLocks ¶ added in v0.128.0
WithChapterLocks settles admitted media changes before catalog marker authoring. The caller holds source locks first and takes catalog rows inside fn; uploads/recovery take manifest then catalog locks in the same order.
type TierQuota ¶
type TierQuota struct {
Tier string `json:"tier" yaml:"tier"`
Quotas []Quota `json:"quotas" yaml:"quotas"`
}
TierQuota is the bucket of a tier's holders.
type UnavailableError ¶ added in v0.87.0
type UnavailableError struct {
}
UnavailableError is a download the policy refused.
func (*UnavailableError) Error ¶ added in v0.87.0
func (e *UnavailableError) Error() string
Source Files
¶
- archive_cache.go
- archive_claims.go
- chapter_paths.go
- covers.go
- download.go
- entities.go
- facts.go
- hooks.go
- inspection.go
- jobs.go
- lifecycle.go
- meta.go
- migrate.go
- page_order.go
- pages.go
- plan.go
- processing.go
- publication.go
- queue.go
- ready.go
- release_migration.go
- release_queue.go
- release_work.go
- retirement.go
- routes.go
- segments.go
- source_digest.go
- source_lock.go
- versions.go