Documentation
¶
Overview ¶
Package content is ContentKit's interaction module: comments, reactions, favorites and polls over tenant-scoped content references, stored in the host schema's content_* interaction tables. Everything host-specific lives behind the ports in this file; the package imports no sibling kit and bakes in no host assumption. Content kinds are host-registered, access is an opaque host verdict, ids are opaque text, and every key, index and cursor carries the tenant pinned at construction.
Index ¶
- Constants
- Variables
- type AccountDeleted
- type AccountLifecycle
- type Action
- type AdminComment
- type Anonymous
- type AuthError
- type Avatars
- type BanInput
- type BanNotice
- type BanScope
- type BannedError
- type BannedWord
- type BannedWordInput
- type Comment
- type CommentBan
- type CommentEdit
- type CommentInput
- type CommentStanding
- type Config
- type ContentModerator
- type ContentProcessor
- type Decision
- type FavoriteState
- type FeedItem
- type HeldItem
- type HeldPage
- type IPBan
- type IPBanInput
- type ImageInput
- type ImportComment
- type ImportFavorite
- type ImportPoll
- type ImportPollOption
- type ImportReaction
- type ImportVote
- type MediaImages
- type MediaReader
- type ModerationInput
- type Nullable
- type Poll
- type PollImage
- type PollInput
- type PollOption
- type PollOptionInput
- type PollOptionPatch
- type PollUpdate
- type PollVote
- type Preference
- type PreferenceSender
- type PreferenceSyncReport
- type ProviderDataEraser
- type PublicUser
- type Rate
- type RateLimitError
- type ReactionCounts
- type RejectedError
- type ResolveInput
- type Restored
- type ReviewDecision
- type ReviewOutcome
- type StatelessPolicy
- type TargetType
- type TooLongError
- type Verdict
- type WordAction
Constants ¶
const ( // CodeCommentBanned: the caller is banned from commenting on this target; // the body's ban says the scope, reason and until. -> 403 CodeCommentBanned = "comment_banned" )
const ( // CodeCommentModerated: the comment is held or rejected, so its author // can't edit it; a reviewer's approval makes it editable again. -> 403 CodeCommentModerated = "comment_moderated" )
const ( // CodeCommentTooLong: the comment is longer than Options.CommentMaxLength; // details.max is the limit in characters. -> 422 CodeCommentTooLong = "comment_too_long" )
const (
// CodeCommentsClosed: the target's comments are closed or hidden. -> 403
CodeCommentsClosed = "comments_closed"
)
const ( // CodeCommentsLocked: the caller can't open the content and its kind's // locked view hides comments, so they take no writes from them. -> 403 CodeCommentsLocked = "comments_locked" )
const (
CodeConflict = "conflict"
)
const (
CodeDuplicateComment = "duplicate_comment"
)
const (
CodeForbidden = "forbidden"
)
const (
CodeInternal = "internal_error"
)
const (
CodeInvalidRequest = "invalid_request"
)
const (
CodeModerationRejected = "moderation_rejected"
)
const ( // CodeNotConfigured: the capability exists but the host never wired its // media port. Retrying does not help. -> 501 CodeNotConfigured = "not_configured" )
const (
CodeNotFound = "not_found"
)
const ( // CodeRateLimited: too many of one interaction; the body carries action // and retry_after (seconds, as the Retry-After header). -> 429 CodeRateLimited = "rate_limited" )
const ( // CodeTenantMismatch: a host port answered with another tenant's data. // A configuration fault, not a client fault; the cause stays in the log. CodeTenantMismatch = "tenant_mismatch" )
const (
)
const ( // retry. -> 503 CodeUnavailable = "unavailable" )
const (
CommentsClosed = "closed" // existing comments show; new ones and edits are refused
)
const (
CommentsHidden = "hidden" // comments neither show nor take writes
)
const (
CommentsOpen = "open"
)
const DefaultCommentMaxLength = 2200
DefaultCommentMaxLength is Options.CommentMaxLength unset.
const DefaultPreferenceSyncOverlap = 5 * time.Minute
DefaultPreferenceSyncOverlap is the default Options.PreferenceSyncOverlap.
const KindComment = "comment"
KindComment is the reserved content kind of comments: reactions on comments are keyed by it and never pass through the resolve.Resolver.
const (
ModerationApproved = "approved"
)
const (
ModerationHeld = "held"
)
const (
ModerationRejected = "rejected"
)
const PollMultipleChoice = "multiple_choice"
PollMultipleChoice is the supported poll kind.
const (
PreferenceAxisFavorite = "favorite" // value 1 favorited / 0 not
)
const (
PreferenceAxisReaction = "reaction" // value -1 dislike / 0 neutral / 1 like
)
const (
// ScopeGlobal is the whole tenant, managed by holders of root:comments:ban.
ScopeGlobal = "global"
)
const ScopeIP = "ip"
ScopeIP is the BanNotice scope of an IP ban.
Variables ¶
var ErrCommentBanned = errors.New("content: banned from commenting")
ErrCommentBanned refuses a comment write by a banned user. -> 403 comment_banned
var ErrRateLimited = errors.New("content: rate limited")
ErrRateLimited is a refusal a later attempt passes. -> 429 rate_limited
Functions ¶
This section is empty.
Types ¶
type AccountDeleted ¶ added in v0.135.0
type AccountDeleted struct {
// Deleted marks the account deleted (AuthKit's recovery period) or, false,
// restored.
Deleted bool `json:"deleted"`
}
AccountDeleted is PUT /v1/accounts/{id}/deleted's body.
type AccountLifecycle ¶ added in v0.135.0
type AccountLifecycle interface {
SetAccountDeleted(ctx context.Context, accountID string, deleted bool) error
AnonymizeAccount(ctx context.Context, accountID string) error
}
AccountLifecycle is the engine's account lifecycle, served to a host that delivers AuthKit's account events over HTTP.
type Action ¶ added in v0.63.0
type Action string
Action names one rate-limited interaction.
const (
ActionComment Action = "comment" // comment create or edit, top-level or reply
)
const (
ActionCommentReaction Action = "comment_reaction" // like, dislike, neutral on a comment
)
const (
ActionFavorite Action = "favorite" // favorite and unfavorite
)
const (
ActionPollVote Action = "poll_vote" // multiple-choice votes
)
const (
ActionReaction Action = "reaction" // like, dislike, neutral on content
)
type AdminComment ¶
type AdminComment struct {
Comment
contentref.ContentRef
DeletedAt *time.Time `json:"deleted_at,omitempty"`
AuthorHidden bool `json:"author_hidden"`
}
AdminComment is the moderation view: raw body (no tombstoning), deletion and moderation state and the content reference.
type Anonymous ¶ added in v0.68.0
type Anonymous struct {
// Comments: comment and reply under a name (anon_name).
Comments bool `json:"comments"`
// Reactions: like and dislike works, posts and comments, keyed by IP.
Reactions bool `json:"reactions"`
// Votes: signed-out votes in multiple-choice polls are keyed by IP and
// deduplicated separately from signed-in votes. One person can vote once
// signed out and once signed in; a changing address (e.g. IPv6) votes again.
Votes bool `json:"votes"`
}
Anonymous is what signed-out visitors may do. The zero value allows none of it: an anonymous attempt answers 401 unauthorized.
type AuthError ¶ added in v0.71.0
type AuthError struct{ Err error }
AuthError is a permission check the host's auth could not answer: 401 unauthorized when the credential ended since the request was verified (auth.ErrExpired, auth.ErrRevoked), else 503 unavailable. Never a grant.
type Avatars ¶ added in v0.86.0
type Avatars interface {
Avatars(ids ...string) []media.PublicImage
}
Avatars are people's avatars, built from their ids without a lookup; *media.Registry implements it.
type BanNotice ¶ added in v0.63.0
type BanNotice struct {
Scope string `json:"scope"`
Reason string `json:"reason,omitempty"`
Until *time.Time `json:"until,omitempty"`
}
BanNotice is what a banned user is told: the scope, the reason and when the ban ends (nil: when lifted). It never names who banned them.
type BanScope ¶ added in v0.68.0
type BanScope string
BanScope names a ban route family a caller may use on a target's commenters.
const (
BanGlobal BanScope = "global" // root:comments:ban: /global-comment-bans
)
const (
BanOwner BanScope = "owner" // the caller owns the target: /comment-bans
)
type BannedError ¶ added in v0.63.0
type BannedError struct{ BanNotice }
BannedError is ErrCommentBanned with the ban that applies.
func (*BannedError) Error ¶ added in v0.63.0
func (e *BannedError) Error() string
func (*BannedError) Is ¶ added in v0.63.0
func (e *BannedError) Is(target error) bool
type BannedWord ¶ added in v0.81.0
type BannedWord struct {
Word string `json:"word"`
Action WordAction `json:"action"`
CreatedBy string `json:"created_by"`
CreatedAt time.Time `json:"created_at"`
}
BannedWord is one banned word.
type BannedWordInput ¶ added in v0.81.0
type BannedWordInput struct {
Word string `json:"word"`
Action WordAction `json:"action,omitempty"`
}
BannedWordInput adds a banned word or changes its action (mask by default).
type Comment ¶
type Comment struct {
ID string `json:"id"`
ReplyToID string `json:"reply_to_id,omitempty"`
UserID string `json:"user_id,omitempty"`
AnonName string `json:"anon_name,omitempty"`
Language string `json:"language,omitempty"`
Body string `json:"body"`
Deleted bool `json:"deleted"`
Likes int `json:"likes"`
Dislikes int `json:"dislikes"`
Mine int16 `json:"mine"` // caller's own reaction: -1/0/1
ReplyCount int `json:"reply_count"`
Author *PublicUser `json:"author,omitempty"`
// Moderation is "held" or "rejected" on the author's own unpublished
// comments (with the reason); absent on published ones.
Moderation string `json:"moderation,omitempty"`
ModerationReason string `json:"moderation_reason,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
Comment is the API view of a content_comments row.
type CommentBan ¶ added in v0.63.0
type CommentBan struct {
UserID string `json:"user_id"`
User *PublicUser `json:"user,omitempty"`
Scope string `json:"scope"`
Reason string `json:"reason,omitempty"`
Until *time.Time `json:"until,omitempty"`
BannedBy string `json:"banned_by"`
BannedAt time.Time `json:"banned_at"`
Expired bool `json:"expired"`
}
CommentBan is one user's ban in one scope. An expired ban stays, Expired, until it is lifted or replaced.
type CommentEdit ¶ added in v0.68.0
type CommentEdit struct {
Body string `json:"body"`
}
CommentEdit is the body of a comment edit.
type CommentInput ¶ added in v0.68.0
type CommentInput struct {
Body string `json:"body"`
ReplyToID string `json:"reply_to_id,omitempty"`
AnonName string `json:"anon_name,omitempty"`
// Language is the thread the comment joins: one of the site's languages,
// or none. A reply joins its comment's.
Language string `json:"language,omitempty"`
}
CommentInput is the body of a new comment.
type CommentStanding ¶ added in v0.68.0
type CommentStanding struct {
// CanComment: the caller may comment now. A signed-out caller may only
// where Anonymous says so.
CanComment bool `json:"can_comment"`
// Comments is the target's comments setting: open, closed or hidden.
Comments string `json:"comments"`
// Count is the visible top-level thread size, including tombstones and
// the caller's held/rejected roots, in the requested language. Zero is
// present for an empty thread; hidden or locked comments withhold it.
Count *int `json:"count,omitempty"`
// Locked: the caller can't open the content (or the version) and its
// kind's locked view hides comments, so they are withheld from them and
// take none of their writes.
Locked bool `json:"locked"`
Ban *BanNotice `json:"ban,omitempty"`
// Anonymous: signed-out visitors may comment here, under a name
// (Options.Anonymous.Comments); otherwise they are asked to sign in.
Anonymous bool `json:"anonymous"`
// MaxLength is the longest comment, in characters (Options.CommentMaxLength).
MaxLength int `json:"max_length"`
// UserID is the caller's user id, absent when anonymous: the comments it
// wrote are the ones it may edit and delete.
UserID string `json:"user_id,omitempty"`
// Moderate: the caller may edit, delete and restore anyone's comments
// (root:comments:moderate).
Moderate bool `json:"moderate"`
// BanScopes are the scopes the caller may ban the target's commenters in.
BanScopes []BanScope `json:"ban_scopes"`
}
CommentStanding is the caller's standing on a target: may they comment, if a ban stops them which, and what they may do to others' comments.
type Config ¶ added in v0.68.0
type Config struct {
Anonymous Anonymous `json:"anonymous"`
// CommentMaxLength is the longest comment, in characters.
CommentMaxLength int `json:"comment_max_length"`
}
Config is what the content module allows, so clients choose between a sign-in prompt and an anonymous form, and bound a comment, before acting.
type ContentModerator ¶
type ContentModerator interface {
Screen(ctx context.Context, in ModerationInput) (Verdict, error)
}
ContentModerator screens every comment/post write before it publishes. Absent port: every write publishes. An error or an unknown decision fails closed to review: the submission is kept, held, never published unscreened.
type ContentProcessor ¶
ContentProcessor processes plain text on write. The default only trims whitespace; callers render the result as text.
type Decision ¶
type Decision string
Decision is a ContentModerator's outcome for one text write.
const (
DecisionApprove Decision = "approve" // publish
)
const (
DecisionReject Decision = "reject" // refuse the write: 422 with the reason, nothing stored
)
const (
DecisionReview Decision = "review" // store held: author-only until a reviewer resolves it
)
type FavoriteState ¶ added in v0.68.0
FavoriteState says whether the caller has favorited the target, and how many have: absent where the target's kind's locked view hides it from the caller.
type FeedItem ¶
type FeedItem struct {
Comment
contentref.ContentRef
}
FeedItem is a Comment plus its canonical content reference, for the cross-content latest feed (hosts hydrate titles/covers from the reference).
type HeldItem ¶
type HeldItem struct {
Kind string `json:"kind"` // KindComment
Revision int64 `json:"revision"` // required when resolving this exact screened text
ID string `json:"id"`
// Ref is the commented content, or the held item's own reference.
Ref contentref.ContentRef `json:"ref"`
AuthorID string `json:"author_id,omitempty"`
Author *PublicUser `json:"author,omitempty"`
AnonName string `json:"anon_name,omitempty"`
Title string `json:"title,omitempty"`
Body string `json:"body"`
Reason string `json:"reason"`
Model string `json:"model,omitempty"`
PromptVersion string `json:"prompt_version,omitempty"`
Confidence float64 `json:"confidence,omitempty"`
Error string `json:"error,omitempty"` // moderator failure that forced the hold
HeldAt time.Time `json:"held_at"`
CreatedAt time.Time `json:"created_at"`
}
HeldItem is one comment awaiting review.
func (*HeldItem) SetVerdict ¶ added in v0.81.0
SetVerdict fills the screening provenance from a moderation_verdict.
type IPBan ¶ added in v0.81.0
type IPBan struct {
Network string `json:"network"`
Reason string `json:"reason,omitempty"`
Until *time.Time `json:"until,omitempty"`
BannedBy string `json:"banned_by"`
BannedAt time.Time `json:"banned_at"`
Expired bool `json:"expired"`
}
IPBan refuses comments and answers from an address or network.
type IPBanInput ¶ added in v0.81.0
type IPBanInput struct {
Network string `json:"network"`
Reason string `json:"reason,omitempty"`
Until *time.Time `json:"until,omitempty"`
}
IPBanInput bans an address ("203.0.113.7") or a network ("203.0.113.0/24"), or replaces its ban.
type ImageInput ¶ added in v0.68.0
type ImageInput struct {
Image *string `json:"image"`
}
ImageInput names an inline image of the item's media folder ("i-{uuid}"); "" clears where the route allows it.
type ImportComment ¶ added in v0.81.0
type ImportComment struct {
ID string
Ref contentref.ContentRef
Language string
ReplyToID string
UserID string
AnonName string
Body string
DeletedAt *time.Time
CreatedAt *time.Time
UpdatedAt *time.Time
}
ImportComment is a comment as the bulk import writes it: approved, its id, thread and times kept. ReplyToID names a comment on the same reference; a reply to a reply joins its thread.
type ImportFavorite ¶ added in v0.81.0
type ImportFavorite struct {
Ref contentref.ContentRef
UserID string
CreatedAt *time.Time
}
ImportFavorite is a person's bookmark.
type ImportPoll ¶ added in v0.81.0
type ImportPoll struct {
ID string
Kind string
Question string
Language string
Active bool
LiveAt *time.Time
ClosesAt *time.Time
DeletedAt *time.Time
CreatedAt *time.Time
UpdatedAt *time.Time
Options []ImportPollOption
}
ImportPoll is a poll with its options, which replace the stored ones (and their votes).
type ImportPollOption ¶ added in v0.81.0
type ImportPollOption struct {
ID string `json:"id"`
Label string `json:"label"`
Position int `json:"position"`
}
ImportPollOption is one option of an ImportPoll.
type ImportReaction ¶ added in v0.81.0
type ImportReaction struct {
Ref contentref.ContentRef
UserID string
IP string
Value int16
CreatedAt *time.Time
UpdatedAt *time.Time
}
ImportReaction is a person's (or an IP's) reaction: -1, 0 or 1.
type ImportVote ¶ added in v0.81.0
type ImportVote struct {
PollID string
OptionID string
UserID string
IP string
CreatedAt *time.Time
}
ImportVote is one person's (or IP's) choice in a multiple-choice poll.
type MediaImages ¶ added in v0.70.0
type MediaImages interface {
Images(ctx context.Context, qs ...media.ImageQuery) ([][]media.PublicImage, error)
}
MediaImages answers image queries from the current publications in one read; *media.Manifests implements it.
type MediaReader ¶ added in v0.70.0
type MediaReader interface {
Read(ctx context.Context, ref contentref.ContentRef, actor access.Actor, o media.ReadOptions) (*media.ReadResult, error)
}
MediaReader reads an item as the media read API does; *media.Reader implements it.
type ModerationInput ¶
type ModerationInput struct {
SubjectID string // opaque content author; may differ from editing moderator
Tenant string
Actor access.Actor
// Ref is the commented content.
Ref contentref.ContentRef
Kind string // KindComment
ItemID string // the existing item on an edit; empty on create
Text string
}
ModerationInput is one comment, or a catalog item's text, about to publish. The moderator sees sanitized text and opaque ids only.
type Nullable ¶ added in v0.68.0
Nullable is a PATCH member that tells absent (leave it) from null (clear it): Set reports the member was present, Value is nil for null. Tag it omitzero, so an unset one is left out when encoded.
func (Nullable[T]) MarshalJSON ¶ added in v0.68.0
func (*Nullable[T]) UnmarshalJSON ¶ added in v0.68.0
type Poll ¶ added in v0.68.0
type Poll struct {
ID string `json:"id"`
Kind string `json:"kind"`
Question string `json:"question"`
Language string `json:"language"`
IsActive bool `json:"is_active"`
ImageURL string `json:"image_url,omitempty"`
LiveAt time.Time `json:"live_at"`
ClosesAt *time.Time `json:"closes_at,omitempty"`
Closed bool `json:"closed"` // inactive or past closes_at: no more votes
TotalVotes int `json:"total_votes"`
Options []PollOption `json:"options"`
Voted bool `json:"voted"`
MyOption string `json:"my_option,omitempty"`
}
Poll is a question, its predefined options and the caller's own vote.
type PollImage ¶ added in v0.68.0
type PollImage struct {
ImageURL *string `json:"image_url"`
}
PollImage is the image's public URL after an image change; null when cleared or while it has no public file.
type PollInput ¶ added in v0.68.0
type PollInput struct {
Kind string `json:"kind,omitempty"` // default multiple_choice
Question string `json:"question"`
Language string `json:"language"`
LiveAt *time.Time `json:"live_at,omitempty"` // nil = live now
ClosesAt *time.Time `json:"closes_at,omitempty"` // nil = open until deactivated
Options []PollOptionInput `json:"options,omitempty"`
}
PollInput is a new poll.
type PollOption ¶ added in v0.68.0
type PollOption struct {
ID string `json:"id"`
Label string `json:"label"`
ImageURL string `json:"image_url,omitempty"`
Position int `json:"position"`
VoteCount int `json:"vote_count"`
}
PollOption is one choice with its denormalized vote_count.
type PollOptionInput ¶ added in v0.68.0
PollOptionInput is one option of a new poll. Images are set once the poll exists (PUT /polls/{id}/options/{oid}/image), since they live in its folder.
type PollOptionPatch ¶ added in v0.68.0
PollOptionPatch is the option add and update body; pointers so an absent field is untouched.
type PollUpdate ¶ added in v0.68.0
type PollUpdate struct {
Question *string `json:"question"`
IsActive *bool `json:"is_active"`
LiveAt *time.Time `json:"live_at"`
ClosesAt Nullable[time.Time] `json:"closes_at,omitzero"`
}
PollUpdate leaves absent fields untouched; closes_at null clears it (open until deactivated).
type PollVote ¶ added in v0.68.0
type PollVote struct {
OptionID string `json:"option_id"`
}
PollVote is a vote for one option.
type Preference ¶ added in v0.15.0
type Preference struct {
contentref.ContentRef
ActorID string
Axis string
Value int16
Revision int64
UpdatedAt time.Time
}
Preference is one exported row: an actor's current value on one axis of a canonical reference, with the revision and time of its last change.
type PreferenceSender ¶ added in v0.15.0
type PreferenceSender func(ctx context.Context, page []Preference) error
PreferenceSender durably writes one page of preferences; an error aborts the sync without advancing the watermark. Re-sends must be idempotent.
type PreferenceSyncReport ¶ added in v0.15.0
PreferenceSyncReport reports one sync: the revision it scanned after and the rows it sent.
type ProviderDataEraser ¶ added in v0.15.0
type ProviderDataEraser interface {
EraseSubjects(ctx context.Context, tenant string, actorIDs []string) error
}
ProviderDataEraser deletes personal data retained by optional moderation providers. Success means a durable tenant/subject fence is installed: Screen calls begun before erasure cannot recreate data when they complete later. Merely queuing a delete is not success. Calls are idempotent; implementations must preserve fences across restore/restart. A host using multiple retaining providers must implement a composite eraser.
type PublicUser ¶
type PublicUser struct {
ID string `json:"id"`
Deleted bool `json:"deleted,omitempty"`
Name string `json:"name,omitempty"`
Username string `json:"username"`
Avatar string `json:"avatar,omitempty"`
AvatarSrcSet string `json:"avatar_srcset,omitempty"`
}
PublicUser is how an author is shown: its name and username from the host's directory (Options.UserInfo) and its avatar (Options.Avatars). Never its email.
type RateLimitError ¶ added in v0.63.0
RateLimitError is ErrRateLimited for one action, with how long to wait.
func (*RateLimitError) Error ¶ added in v0.63.0
func (e *RateLimitError) Error() string
func (*RateLimitError) Is ¶ added in v0.63.0
func (e *RateLimitError) Is(target error) bool
type ReactionCounts ¶ added in v0.68.0
type ReactionCounts struct {
Likes *int `json:"likes,omitempty"`
Dislikes *int `json:"dislikes,omitempty"`
Mine int16 `json:"mine"` // -1, 0, or 1; 0 also means "no reaction"
}
ReactionCounts is the split tally for a reference plus the caller's own value. The tally is absent where the kind's locked view hides it from the caller.
type RejectedError ¶
type RejectedError struct{ Reason string }
RejectedError is a policy rejection of a text write, answered as 422 with its reason: a ContentModerator's reject verdict.
func (RejectedError) Error ¶
func (e RejectedError) Error() string
type ResolveInput ¶ added in v0.68.0
type ResolveInput struct {
Decision Decision `json:"decision"`
Revision int64 `json:"revision"`
Reason string `json:"reason,omitempty"`
}
ResolveInput resolves a held item at the revision the queue listed; Reason replaces the moderator's on a rejection.
type Restored ¶ added in v0.68.0
type Restored struct {
Restored bool `json:"restored"`
}
Restored confirms a comment's restoration.
type ReviewDecision ¶
type ReviewDecision struct {
Revision int64 // the revision returned by ListHeld; stale decisions cannot publish edits
Decision Decision
Reviewer string
Reason string
}
ReviewDecision resolves a held item: approve publishes it, reject keeps it author-only with Reason (or the moderator's reason when empty).
type ReviewOutcome ¶ added in v0.68.0
type ReviewOutcome struct {
Decision Decision `json:"decision"`
}
ReviewOutcome is the decision applied.
type StatelessPolicy ¶
type StatelessPolicy interface{ StatelessPolicy() }
StatelessPolicy explicitly declares that a policy implementation retains no personal data outside this process. Built-in deterministic policies satisfy this marker; retaining providers must instead configure ProviderDataEraser.
type TargetType ¶ added in v0.81.0
type TargetType string
TargetType is what an interaction route names: a content item (optionally one of its versions) or an entity. Rows store the target under its kind from kinds.Config and its id.
const (
TargetChannel TargetType = "channels"
)
const (
TargetContent TargetType = "contents"
)
const (
TargetEntity TargetType = "entities"
)
type TooLongError ¶ added in v0.68.0
type TooLongError struct{ Max int }
TooLongError refuses a comment longer than Max characters. -> 422 comment_too_long
func (*TooLongError) Error ¶ added in v0.68.0
func (e *TooLongError) Error() string
type Verdict ¶
type Verdict struct {
Decision Decision
Reason string
Model string
PromptVersion string
Confidence float64
}
Verdict is a moderator's decision with its provenance. Reason is shown to the author on reject and review; Model, PromptVersion and Confidence are kept with a held item for the reviewer.
type WordAction ¶ added in v0.81.0
type WordAction string
WordAction is what a banned word does to text containing it.
const (
WordMask WordAction = "mask" // replaced by asterisks
)
const (
WordReject WordAction = "reject" // the write is refused
)