{"$type":"com.atproto.lexicon.schema","defs":{"notificationView":{"description":"A single notification surfaced to the recipient. Server-projected from indexed like, reply and post records; recipients are scoped server-side from the viewer parameter.","properties":{"author":{"description":"The actor whose action produced this notification. Its handle is the one the AppView has verified for that account, absent until projected.","ref":"app.tempomusic.actor.defs#profileViewBasic","type":"ref"},"cid":{"format":"cid","type":"string"},"indexedAt":{"description":"Timestamp at which the AppView indexed the source record.","format":"datetime","type":"string"},"isRead":{"description":"Server-computed from indexedAt and the recipient's stored seenAt; true when this notification predates seenAt.","type":"boolean"},"reason":{"description":"Why this notification was produced. knownValues is informational; clients should accept unknown values and skip them.","knownValues":["post-liked","post-replied","reply-liked","post-mentioned","reply-mentioned"],"maxLength":100,"type":"string"},"reasonSubject":{"description":"AT-URI of the post or reply that was acted upon (the recipient's own record). Matches Bluesky's reasonSubject semantics. Absent for mentions: the source record is the subject.","format":"at-uri","type":"string"},"record":{"description":"The underlying app.tempomusic.feed.like, app.tempomusic.feed.reply or app.tempomusic.feed.post record carried verbatim with its $type discriminator. Lexicon-typed as unknown to match the AT Protocol convention for embedded records.","type":"unknown"},"subject":{"description":"The recipient's own post or reply that was acted upon (reasonSubject), for the row excerpt. Present for post-liked and reply-liked while that record is live and has something to show; absent for post-replied and the two mention reasons, where the source record in `record` carries the text the row shows, and absent whenever the AppView has nothing to serve — the liked record is gone, or it is a liked reply whose text is blank, leaving nothing to excerpt.","ref":"#subjectView","type":"ref"},"subjectRootUri":{"description":"AT-URI of the root post for navigation. For post-liked / post-replied this equals reasonSubject; for reply-liked this is the root post the liked reply hangs off, letting clients open the right thread without a second lookup. For post-mentioned this is the source post itself; for reply-mentioned the root post of the thread the source reply belongs to.","format":"at-uri","type":"string"},"uri":{"description":"AT-URI of the source record (the like, reply or post) that produced this notification.","format":"at-uri","type":"string"}},"required":["uri","cid","author","reason","record","isRead","indexedAt"],"type":"object"},"subjectView":{"description":"The acted-upon record reduced to what a notification row shows of it: its text and, for a post, the music it is about — the fallback when the post has no text.","properties":{"music":{"description":"The music the acted-upon post is about, so a row can fall back to it when the post has no text. Absent when the record is a reply. The union is open: clients must keep decoding a notification whose music $type they do not know.","refs":["app.tempomusic.feed.defs#songRef","app.tempomusic.feed.defs#albumRef","app.tempomusic.feed.defs#artistRef"],"type":"union"},"text":{"description":"The record's text. Absent when the record carries none, or only whitespace. A post with no text still carries its music, so a subject always has one of the two: a liked reply whose text is blank carries no subject at all. Bounds mirror app.tempomusic.feed.post#text.","maxGraphemes":300,"maxLength":3000,"type":"string"},"uri":{"description":"AT-URI of the acted-upon record, equal to the notification's reasonSubject.","format":"at-uri","type":"string"}},"required":["uri"],"type":"object"}},"id":"app.tempomusic.notification.defs","lexicon":1}