app.tempomusic.staff.defs

lexicons.tempomusic.fan

{
  "id": "app.tempomusic.staff.defs",
  "defs": {
    "staffRole": {
      "type": "string",
      "maxLength": 100,
      "description": "Privilege level on the admin surface. `superAdmin` is the only role permitted to grant or revoke other moderators.",
      "knownValues": [
        "moderator",
        "superAdmin"
      ]
    },
    "staffView": {
      "type": "object",
      "required": [
        "did",
        "role",
        "grantedAt"
      ],
      "properties": {
        "did": {
          "type": "string",
          "format": "did"
        },
        "role": {
          "ref": "#staffRole",
          "type": "ref"
        },
        "grantedAt": {
          "type": "string",
          "format": "datetime"
        },
        "revokedAt": {
          "type": "string",
          "format": "datetime",
          "description": "When set, the row is no longer active; the gate denies the DID. Listed in listStaff only when explicitly requested via the includeRevoked parameter."
        },
        "grantedByDid": {
          "type": "string",
          "format": "did",
          "description": "DID of the super-admin who granted this row. Absent for bootstrap rows seeded from the TEMPO_STAFF_BOOTSTRAP_DIDS env var."
        },
        "revokeReason": {
          "type": "string",
          "maxLength": 5000,
          "maxGraphemes": 500
        }
      },
      "description": "AppView projection of a row in the moderators table."
    },
    "reportView": {
      "type": "object",
      "required": [
        "id",
        "subject",
        "reporterDid",
        "reasonType",
        "status",
        "subjectKnownAtIntake",
        "createdAt"
      ],
      "properties": {
        "id": {
          "type": "integer",
          "minimum": 1
        },
        "status": {
          "ref": "#reportStatus",
          "type": "ref"
        },
        "details": {
          "type": "string",
          "maxLength": 500,
          "description": "Free-text context provided by the reporter. Absent when not provided.",
          "maxGraphemes": 500
        },
        "subject": {
          "refs": [
            "app.tempomusic.moderation.defs#postSubject",
            "app.tempomusic.moderation.defs#replySubject",
            "app.tempomusic.moderation.defs#accountSubject"
          ],
          "type": "union"
        },
        "createdAt": {
          "type": "string",
          "format": "datetime"
        },
        "triagedAt": {
          "type": "string",
          "format": "datetime"
        },
        "reasonType": {
          "ref": "app.tempomusic.moderation.defs#reasonType",
          "type": "ref"
        },
        "resolvedAt": {
          "type": "string",
          "format": "datetime"
        },
        "reporterDid": {
          "type": "string",
          "format": "did"
        },
        "triagedByDid": {
          "type": "string",
          "format": "did"
        },
        "resolvedByDid": {
          "type": "string",
          "format": "did"
        },
        "resolutionNote": {
          "type": "string",
          "maxLength": 5000,
          "maxGraphemes": 500
        },
        "subjectResolvedAt": {
          "type": "string",
          "format": "datetime",
          "description": "Timestamp at which the daily resolver job flipped subjectKnownAtIntake from false to true. Absent when intake was already known."
        },
        "subjectKnownAtIntake": {
          "type": "boolean",
          "description": "True when the subject was already projected into the AppView at the moment of intake. False when the resolver job had to catch up; combined with subjectResolvedAt to distinguish the two known-at-intake variants. State combinations: (a) `true` + subjectResolvedAt absent = known at intake; (b) `true` + subjectResolvedAt present = resolver flipped after the fact; (c) `false` = still unresolved."
        }
      },
      "description": "AppView projection of a single report row."
    },
    "reportStatus": {
      "type": "string",
      "maxLength": 100,
      "description": "Lifecycle state of a report. `open` → `underReview` → terminal `actioned` | `dismissed`. Current implementations MUST NOT emit any value outside this set; future audit-clarity states (e.g. resolvedDuplicate) require an additive lexicon update plus an implementation that writes them.",
      "knownValues": [
        "open",
        "underReview",
        "actioned",
        "dismissed"
      ]
    },
    "inviteCodeUse": {
      "type": "object",
      "required": [
        "usedBy",
        "usedAt"
      ],
      "properties": {
        "usedAt": {
          "type": "string",
          "format": "datetime"
        },
        "usedBy": {
          "type": "string",
          "format": "did"
        }
      }
    },
    "takedownClass": {
      "type": "string",
      "maxLength": 100,
      "description": "Classification of a takedown action. All three classes make the subject invisible to read paths identically; the distinction is downstream retention/purge policy. `reported` is the standard moderation hold. `tagged` is reserved for future classifier-driven holds with auto-purge after a sweep. `legalHold` is exempt from any future purge endpoint and is audit-mandatory.",
      "knownValues": [
        "reported",
        "tagged",
        "legalHold"
      ]
    },
    "auditEntryView": {
      "type": "object",
      "required": [
        "id",
        "actorDid",
        "actionType",
        "createdAt"
      ],
      "properties": {
        "id": {
          "type": "integer",
          "minimum": 1
        },
        "reason": {
          "type": "string",
          "maxLength": 5000,
          "description": "Free-text reason provided by the actor.",
          "maxGraphemes": 500
        },
        "subject": {
          "refs": [
            "app.tempomusic.moderation.defs#postSubject",
            "app.tempomusic.moderation.defs#replySubject",
            "app.tempomusic.moderation.defs#accountSubject"
          ],
          "type": "union"
        },
        "actorDid": {
          "type": "string",
          "format": "did",
          "description": "DID of the moderator who performed the action, or of the reporter for `reportCreated` entries."
        },
        "reportId": {
          "type": "integer",
          "minimum": 1,
          "description": "Linked report row when relevant (report-lifecycle entries, takedowns with closeAttachedReports)."
        },
        "createdAt": {
          "type": "string",
          "format": "datetime"
        },
        "actionType": {
          "ref": "#staffActionType",
          "type": "ref"
        },
        "afterStatus": {
          "type": "integer",
          "minimum": 0,
          "description": "moderation_status value after the action, when applicable. 0 = live, 1 = reported, 2 = tagged, 3 = legalHold."
        },
        "beforeStatus": {
          "type": "integer",
          "minimum": 0,
          "description": "moderation_status value before the action, when applicable. 0 = live, 1 = reported, 2 = tagged, 3 = legalHold."
        },
        "takedownClass": {
          "ref": "#takedownClass",
          "type": "ref",
          "description": "For subjectTakedown actions, the class chosen by the moderator. Equivalent to afterStatus but in symbolic form; populated to spare clients from translating the integer code."
        }
      },
      "description": "AppView projection of a moderation_audit row. The audit log is append-only and never purged; entries survive hard-deletion of the actor account."
    },
    "inviteCodeView": {
      "type": "object",
      "required": [
        "code",
        "available",
        "disabled",
        "createdBy",
        "createdAt"
      ],
      "properties": {
        "code": {
          "type": "string",
          "maxLength": 128,
          "description": "Suffix only — the env prefix has been stripped by the server before surfacing."
        },
        "uses": {
          "type": "array",
          "items": {
            "ref": "#inviteCodeUse",
            "type": "ref"
          }
        },
        "disabled": {
          "type": "boolean",
          "description": "True when the code has been disabled by a super-admin via disableInviteCodes."
        },
        "available": {
          "type": "integer",
          "minimum": 0,
          "description": "Number of remaining uses. `1 - uses.length` for the single-use codes emitted by this feature."
        },
        "createdAt": {
          "type": "string",
          "format": "datetime"
        },
        "createdBy": {
          "type": "string",
          "format": "did",
          "description": "DID of the staff account that generated this code."
        },
        "forAccount": {
          "type": "string",
          "format": "did",
          "description": "When the code was minted for a specific DID (unused by this feature — the staff panel only generates unbound codes)."
        }
      },
      "description": "AppView projection of a single PDS invite code, sourced on-demand from `com.atproto.admin.getInviteCodes`. No local mirror."
    },
    "staffActionType": {
      "type": "string",
      "maxLength": 100,
      "description": "Categorical action recorded in the moderation audit log. Covers report-lifecycle transitions, subject status changes, moderator-role mutations, and invite-code lifecycle (TEM-502).",
      "knownValues": [
        "reportCreated",
        "reportTriaged",
        "reportDismissed",
        "reportClosedByCascade",
        "subjectTakedown",
        "subjectRestore",
        "moderatorGranted",
        "moderatorRevoked",
        "accountSuspended",
        "accountUnsuspended",
        "accountBanned",
        "reportReopened",
        "inviteCodeCreated",
        "inviteCodeDisabled"
      ]
    }
  },
  "$type": "com.atproto.lexicon.schema",
  "lexicon": 1
}

Validate Record

Validate a record against app.tempomusic.staff.defs

Validation Options
Automatically resolve and include external schemas for full validation
Treat any remaining unresolved references as valid

Metadata

DID
did:plc:pxsuqmultto34oks44m2lgxm
CID
bafyreif2ozpm442tup3xvl7x2acoqqep6vvsnff6x4knvoe4cisemupl6y
Indexed At
2026-08-24 09:06 UTC
AT-URI
at://did:plc:pxsuqmultto34oks44m2lgxm/com.atproto.lexicon.schema/app.tempomusic.staff.defs

Referenced Schemas (4)

Lexicon Garden

@