Documentation
¶
Index ¶
- Constants
- Variables
- func CreateTrackRouteID(title, handle string) string
- func GeneratePlaylistSlugAndCollisionID(ctx context.Context, dbtx db.DBTX, ownerID, playlistID int64, name string) (slug, titleSlug string, collisionID int, err error)
- func GenerateSlugAndCollisionID(ctx context.Context, dbtx db.DBTX, ownerID, trackID int64, title string) (slug, titleSlug string, collisionID int, err error)
- func IsValidationError(err error) bool
- func NormalizeGenre(genre string) string
- func SanitizeSlug(title string, recordID int64, collisionID int) string
- func ValidateAccessConditions(p *Params) error
- func ValidateBio(bio string) error
- func ValidateDescription(desc string) error
- func ValidateGenre(genre string) error
- func ValidateHandle(handle string) error
- func ValidateSigner(ctx context.Context, params *Params) error
- func ValidateUserName(name string) error
- type Dispatcher
- type Handler
- func AssociatedWalletCreate() Handler
- func AssociatedWalletDelete() Handler
- func CommentCreate() Handler
- func CommentDelete() Handler
- func CommentMute() Handler
- func CommentPin() Handler
- func CommentReact() Handler
- func CommentReport() Handler
- func CommentUnmute() Handler
- func CommentUnpin() Handler
- func CommentUnreact() Handler
- func CommentUpdate() Handler
- func DashboardWalletCreate() Handler
- func DashboardWalletDelete() Handler
- func DeveloperAppCreate() Handler
- func DeveloperAppDelete() Handler
- func DeveloperAppUpdate() Handler
- func EmailAccessUpdate() Handler
- func EncryptedEmailCreate() Handler
- func EventCreate() Handler
- func EventDelete() Handler
- func EventUpdate() Handler
- func Follow() Handler
- func GrantApprove() Handler
- func GrantCreate() Handler
- func GrantDelete() Handler
- func GrantReject() Handler
- func MuteUser() Handler
- func NotificationCreate() Handler
- func NotificationView() Handler
- func PlayCountReconcile() Handler
- func PlaylistCreate() Handler
- func PlaylistDelete() Handler
- func PlaylistSeenView() Handler
- func PlaylistUpdate() Handler
- func Repost() Handler
- func Save() Handler
- func Share() Handler
- func Subscribe() Handler
- func TipReaction() Handler
- func TrackCollaboratorApprove() Handler
- func TrackCollaboratorReject() Handler
- func TrackCreate() Handler
- func TrackDelete() Handler
- func TrackDownload() Handler
- func TrackMute() Handler
- func TrackUnmute() Handler
- func TrackUpdate() Handler
- func Unfollow() Handler
- func UnmuteUser() Handler
- func Unrepost() Handler
- func Unsave() Handler
- func Unsubscribe() Handler
- func UserCreate() Handler
- func UserUpdate() Handler
- func UserVerify() Handler
- type Params
- func (p *Params) MetadataBool(key string) (bool, bool)
- func (p *Params) MetadataBoolOr(key string, def bool) bool
- func (p *Params) MetadataFloat64(key string) (float64, bool)
- func (p *Params) MetadataInt64(key string) (int64, bool)
- func (p *Params) MetadataJSON(key string) (any, bool)
- func (p *Params) MetadataString(key string) string
- func (p *Params) Queries() *db.Queries
- type PostHook
- type ValidationError
Constants ¶
const ( CharacterLimitAppName = 50 CharacterLimitAppDescription = 160 )
const ( EntityTypeUser = "User" EntityTypeTrack = "Track" EntityTypePlaylist = "Playlist" EntityTypeDashboardWalletUser = "DashboardWalletUser" EntityTypeUserWallet = "UserWallet" EntityTypeFollow = "Follow" EntityTypeSave = "Save" EntityTypeRepost = "Repost" EntityTypeSubscription = "Subscription" EntityTypeNotificationSeen = "NotificationSeen" EntityTypeNotification = "Notification" EntityTypePlaylistSeen = "PlaylistSeen" EntityTypeDeveloperApp = "DeveloperApp" EntityTypeGrant = "Grant" EntityTypeAssociatedWallet = "AssociatedWallet" EntityTypeUserEvent = "UserEvent" EntityTypeStem = "Stem" EntityTypeRemix = "Remix" EntityTypeTrackRoute = "TrackRoute" EntityTypePlaylistRoute = "PlaylistRoute" EntityTypeTip = "Tip" EntityTypeComment = "Comment" EntityTypeCommentReaction = "CommentReaction" EntityTypeCommentReport = "CommentReport" EntityTypeCommentThread = "CommentThread" EntityTypeCommentMention = "CommentMention" EntityTypeMutedUser = "MutedUser" EntityTypeCommentNotificationSetting = "CommentNotificationSetting" EntityTypeEncryptedEmail = "EncryptedEmail" EntityTypeEmailAccess = "EmailAccess" EntityTypeEvent = "Event" EntityTypeTrackCollaborator = "TrackCollaborator" EntityTypePlayCount = "PlayCount" )
Entity type constants.
const ( ActionCreate = "Create" ActionUpdate = "Update" ActionDelete = "Delete" ActionFollow = "Follow" ActionUnfollow = "Unfollow" ActionSave = "Save" ActionUnsave = "Unsave" ActionRepost = "Repost" ActionUnrepost = "Unrepost" ActionVerify = "Verify" ActionSubscribe = "Subscribe" ActionUnsubscribe = "Unsubscribe" ActionView = "View" ActionViewPlaylist = "ViewPlaylist" ActionApprove = "Approve" ActionReject = "Reject" ActionDownload = "Download" ActionReact = "React" ActionUnreact = "Unreact" ActionPin = "Pin" ActionUnpin = "Unpin" ActionMute = "Mute" ActionUnmute = "Unmute" ActionAddEmail = "AddEmail" ActionReport = "Report" ActionReconcile = "Reconcile" )
Action constants.
const ( PlaylistIDOffset = 400_000 TrackIDOffset = 2_000_000 UserIDOffset = 3_000_000 CommentIDOffset = 4_000_000 )
ID offsets.
const ( CharacterLimitUserBio = 256 CharacterLimitUserName = 32 CharacterLimitHandle = 30 CharacterLimitDescription = 2500 CharacterLimitCommentBody = 400 )
Character limit constants.
const EntityTypeAny = "*"
EntityTypeAny is a wildcard entity type for handlers that match any entity type for a given action (e.g., social features: Follow matches entity_type "User", Save matches "Track" or "Playlist").
const MaxRedirectURILength = 2000
MaxRedirectURILength caps each individual URI string length.
const MaxRedirectURIs = 50
MaxRedirectURIs caps how many redirect URIs a single developer app may register.
const MaxTrackCollaborators = 50
MaxTrackCollaborators bounds how many collaborators a single track may invite, so a malformed or hostile metadata blob can't enqueue an unbounded number of rows. Excess entries beyond the cap are ignored.
const SubscriptionEntityTypeEvent = "Event"
SubscriptionEntityTypeEvent: when subscriptions.entity_type is "Event", subscriptions.user_id is the event_id (the column is overloaded).
Variables ¶
var GenreAllowlist = map[string]struct{}{
"Acoustic": {}, "Alternative": {}, "Ambient": {}, "Audiobooks": {}, "Blues": {},
"Classical": {}, "Comedy": {}, "Country": {}, "Dancehall": {}, "Deep House": {},
"Devotional": {}, "Disco": {}, "Downtempo": {}, "Drum & Bass": {}, "Dubstep": {},
"Electro": {}, "Electronic": {}, "Experimental": {}, "Folk": {}, "Funk": {},
"Future Bass": {}, "Future House": {}, "Glitch Hop": {}, "Hardstyle": {},
"Hip-Hop/Rap": {}, "House": {}, "Hyperpop": {}, "Jazz": {}, "Jersey Club": {},
"Jungle": {}, "Kids": {}, "Latin": {}, "Lo-Fi": {}, "Metal": {}, "Moombahton": {},
"Podcasts": {}, "Pop": {}, "Progressive House": {}, "Punk": {}, "R&B/Soul": {},
"Reggae": {}, "Rock": {}, "Soundtrack": {}, "Spoken Word": {}, "Tech House": {},
"Techno": {}, "Trance": {}, "Trap": {}, "Tropical House": {}, "Vaporwave": {}, "World": {},
}
GenreAllowlist is the canonical set of genre strings used for autocomplete suggestions in UIs. It is NOT used for validation — the Open Audio Protocol accepts any non-empty genre string up to 100 characters.
var VerifiedAddress = "0xbeef8E42e8B5964fDD2b7ca8efA0d9aef38AA996"
VerifiedAddress is the wallet address authorized to sign User Verify transactions.
Functions ¶
func CreateTrackRouteID ¶
CreateTrackRouteID constructs a track's route_id from an unsanitized title and handle. Resulting route_ids are of the shape `<handle>/<sanitized_title>`.
func GeneratePlaylistSlugAndCollisionID ¶
func GeneratePlaylistSlugAndCollisionID(ctx context.Context, dbtx db.DBTX, ownerID, playlistID int64, name string) (slug, titleSlug string, collisionID int, err error)
GeneratePlaylistSlugAndCollisionID resolves slug collisions for playlist_routes.
func GenerateSlugAndCollisionID ¶
func GenerateSlugAndCollisionID(ctx context.Context, dbtx db.DBTX, ownerID, trackID int64, title string) (slug, titleSlug string, collisionID int, err error)
GenerateSlugAndCollisionID resolves slug collisions for track_routes (task_helpers.generate_slug_and_collision_id).
func IsValidationError ¶
IsValidationError returns true if the error is a ValidationError.
func NormalizeGenre ¶ added in v1.5.0
NormalizeGenre maps a genre string to its canonical Audius form. Known community variants (e.g. "hiphop", "r and b", "dnb") are mapped to the matching GenreAllowlist entry; anything unrecognized is returned in a title-cased baseline form. Matching is case-insensitive and surrounding / repeated whitespace is trimmed and collapsed. Empty input returns "".
func SanitizeSlug ¶
SanitizeSlug converts a title into a URL-friendly slug.
func ValidateAccessConditions ¶
ValidateAccessConditions checks gating field consistency, matching Only validates when gating fields are present in metadata.
func ValidateDescription ¶
ValidateDescription checks description length (used for tracks, playlists).
func ValidateGenre ¶
ValidateGenre checks that a genre string is within the 100-character limit. Any non-empty string is accepted; the Open Audio Protocol treats genre as a free-form field at the protocol layer. GenreAllowlist provides canonical autocomplete suggestions for UIs only.
func ValidateHandle ¶
ValidateHandle checks handle format, length, and reserved words.
func ValidateSigner ¶
ValidateSigner checks that the signer is params.UserID's wallet or holds a valid grant from that user. Grants come from either a developer app (auto-approved at creation) or another user wallet acting in manager mode (must be approved by the grantor).
func ValidateUserName ¶
ValidateUserName checks name length.
Types ¶
type Dispatcher ¶
type Dispatcher struct {
// contains filtered or unexported fields
}
Dispatcher routes ManageEntity transactions to registered handlers.
func NewDispatcher ¶
func NewDispatcher(logger *zap.Logger) *Dispatcher
NewDispatcher creates a Dispatcher with no registered handlers.
func (*Dispatcher) Dispatch ¶
func (d *Dispatcher) Dispatch(ctx context.Context, params *Params) error
Dispatch routes a ManageEntity transaction to the appropriate handler. Returns nil if no handler is registered (unhandled entity/action pairs are silently skipped). Returns a ValidationError if the handler rejects the transaction. Returns a non-ValidationError for unexpected failures.
After a successful handler invocation, any post-hooks registered for the same (entity_type, action) — or for (EntityTypeAny, action) as a fallback — run in registration order. Hook errors are logged but do not propagate.
func (*Dispatcher) HandlerCount ¶
func (d *Dispatcher) HandlerCount() int
HandlerCount returns the number of registered handlers.
func (*Dispatcher) HasHandler ¶
func (d *Dispatcher) HasHandler(entityType, action string) bool
HasHandler returns true if a handler is registered for the given entity_type and action.
func (*Dispatcher) Register ¶
func (d *Dispatcher) Register(h Handler)
Register adds a handler for a specific (entity_type, action) pair.
func (*Dispatcher) RegisterPostHook ¶ added in v1.4.0
func (d *Dispatcher) RegisterPostHook(entityType, action string, fn PostHook)
RegisterPostHook attaches fn to fire after every successful Handle for (entityType, action). See PostHook for error and ordering semantics.
Wildcard entityType (EntityTypeAny) is supported and follows the same fallback rule as Register: a tx whose (type, action) has no exact hook match will fire any hooks registered against (EntityTypeAny, action).
type Handler ¶
type Handler interface {
EntityType() string
Action() string
Handle(ctx context.Context, params *Params) error
}
Handler processes a specific (entity_type, action) pair.
func AssociatedWalletCreate ¶
func AssociatedWalletCreate() Handler
func AssociatedWalletDelete ¶
func AssociatedWalletDelete() Handler
func CommentUnreact ¶
func CommentUnreact() Handler
CommentUnreact returns the Comment Unreact handler.
func DashboardWalletCreate ¶
func DashboardWalletCreate() Handler
func DashboardWalletDelete ¶
func DashboardWalletDelete() Handler
func DeveloperAppCreate ¶
func DeveloperAppCreate() Handler
DeveloperAppCreate returns the DeveloperApp Create handler.
func DeveloperAppDelete ¶
func DeveloperAppDelete() Handler
DeveloperAppDelete returns the DeveloperApp Delete handler.
func DeveloperAppUpdate ¶
func DeveloperAppUpdate() Handler
DeveloperAppUpdate returns the DeveloperApp Update handler.
func EmailAccessUpdate ¶
func EmailAccessUpdate() Handler
func EncryptedEmailCreate ¶
func EncryptedEmailCreate() Handler
func EventCreate ¶
func EventCreate() Handler
func EventDelete ¶
func EventDelete() Handler
func EventUpdate ¶
func EventUpdate() Handler
func GrantDelete ¶
func GrantDelete() Handler
GrantDelete returns the Grant Delete (Revoke) handler.
func NotificationCreate ¶
func NotificationCreate() Handler
NotificationCreate returns the Notification Create handler.
func NotificationView ¶
func NotificationView() Handler
NotificationView returns the Notification View handler.
func PlayCountReconcile ¶ added in v1.6.0
func PlayCountReconcile() Handler
func PlaylistCreate ¶
func PlaylistCreate() Handler
PlaylistCreate returns the Playlist Create handler.
func PlaylistDelete ¶
func PlaylistDelete() Handler
PlaylistDelete returns the Playlist Delete handler.
func PlaylistSeenView ¶
func PlaylistSeenView() Handler
PlaylistSeenView returns the PlaylistSeen View handler.
func PlaylistUpdate ¶
func PlaylistUpdate() Handler
PlaylistUpdate returns the Playlist Update handler.
func TipReaction ¶
func TipReaction() Handler
func TrackCollaboratorApprove ¶ added in v1.4.0
func TrackCollaboratorApprove() Handler
TrackCollaboratorApprove returns the TrackCollaborator Approve handler.
func TrackCollaboratorReject ¶ added in v1.4.0
func TrackCollaboratorReject() Handler
TrackCollaboratorReject returns the TrackCollaborator Reject handler.
func TrackDownload ¶
func TrackDownload() Handler
func TrackMute ¶
func TrackMute() Handler
TrackMute returns the Track Mute handler (comment notification settings).
func TrackUnmute ¶
func TrackUnmute() Handler
TrackUnmute returns the Track Unmute handler (comment notification settings).
func Unsubscribe ¶
func Unsubscribe() Handler
type Params ¶
type Params struct {
TX *corev1.ManageEntityLegacy
UserID int64
EntityID int64
EntityType string
Action string
Signer string
Metadata map[string]any
RawMetadata string
BlockNumber int64
BlockTime time.Time
BlockHash string
TxHash string
DBTX db.DBTX
Logger *zap.Logger
}
Params holds all context for processing a single ManageEntity transaction.
func NewParams ¶
func NewParams(tx *corev1.ManageEntityLegacy, blockNumber int64, blockTime time.Time, blockHash, txHash string, dbtx db.DBTX, logger *zap.Logger) *Params
NewParams creates Params from a ManageEntityLegacy proto and block context.
func (*Params) MetadataBool ¶
MetadataBool returns a bool from parsed metadata.
func (*Params) MetadataBoolOr ¶
MetadataBoolOr returns the bool value or default if the key is absent.
func (*Params) MetadataFloat64 ¶ added in v1.4.0
MetadataFloat64 returns a float64 from parsed metadata (supports number and integer JSON values). Returns ok=false when the key is absent or not numeric.
func (*Params) MetadataInt64 ¶
MetadataInt64 returns an int64 from parsed metadata (supports number and string).
func (*Params) MetadataJSON ¶
MetadataJSON returns the raw value for a JSONB column (map, slice, etc.). Caller should json.Marshal for DB insertion.
func (*Params) MetadataString ¶
MetadataString returns a string field from parsed metadata, or empty string.
type PostHook ¶ added in v1.4.0
PostHook fires after a successful Handler.Handle for a registered (entity_type, action) pair. It receives the same Params the handler did, so it has access to the proto (Params.TX), the DB tx (Params.DBTX), the parsed metadata, and block context.
Hooks run only when the parent handler returned nil — a ValidationError or other handler failure short-circuits the dispatch before any hook fires. Errors returned from a hook itself are logged but do NOT fail the parent dispatch; this matches the semantics of apps' Postgres triggers (which swallow errors via `EXCEPTION WHEN others THEN raise warning`) and prevents a buggy consumer-side hook from halting the indexer.
Multiple hooks may be registered for the same key; they run in registration order.
type ValidationError ¶
type ValidationError struct {
// contains filtered or unexported fields
}
ValidationError indicates a transaction should be skipped (not a fatal indexing error).
func NewValidationError ¶
func NewValidationError(format string, args ...any) *ValidationError
func (*ValidationError) Error ¶
func (e *ValidationError) Error() string
Source Files
¶
- access_authorities.go
- associated_wallet.go
- comment_create.go
- comment_delete.go
- comment_mute.go
- comment_pin.go
- comment_queries.go
- comment_react.go
- comment_report.go
- comment_update.go
- crypto.go
- dashboard_wallet.go
- developer_app_create.go
- developer_app_delete.go
- developer_app_update.go
- email.go
- event_create.go
- event_delete.go
- event_queries.go
- event_update.go
- genre_allowlist.go
- genre_normalize.go
- grant_create.go
- grant_revoke.go
- handler.go
- immutable_fields.go
- muted_user.go
- notification.go
- oauth_redirect_uris.go
- play_count.go
- playlist_create.go
- playlist_delete.go
- playlist_queries.go
- playlist_row.go
- playlist_tracks.go
- playlist_update.go
- price_history.go
- release_date.go
- slug.go
- social_follow.go
- social_repost.go
- social_save.go
- social_share.go
- social_subscription.go
- tip_reaction.go
- track_collaborator_approve.go
- track_collaborators.go
- track_contest_subscribe.go
- track_create.go
- track_delete.go
- track_download.go
- track_mute.go
- track_queries.go
- track_remixes.go
- track_routes.go
- track_row.go
- track_stems.go
- track_update.go
- user_create.go
- user_update.go
- user_verify.go
- validate.go