A community based topic aggregation platform built on atproto

Implementation of community banning

Changed files
+333
internal
atproto
+76
internal/atproto/lexicon/social/coves/moderation/ban.json
···
+
{
+
"lexicon": 1,
+
"id": "social.coves.moderation.ban",
+
"defs": {
+
"main": {
+
"type": "record",
+
"description": "A ban record for a user in a community",
+
"key": "tid",
+
"record": {
+
"type": "object",
+
"required": ["community", "subject", "banType", "reason", "createdAt"],
+
"properties": {
+
"community": {
+
"type": "string",
+
"format": "at-uri",
+
"description": "AT-URI of the community"
+
},
+
"subject": {
+
"type": "string",
+
"format": "did",
+
"description": "DID of the banned user"
+
},
+
"banType": {
+
"type": "string",
+
"knownValues": ["moderator", "tribunal"],
+
"description": "How the ban was imposed"
+
},
+
"reason": {
+
"type": "string",
+
"maxLength": 2000,
+
"description": "Reason for the ban"
+
},
+
"duration": {
+
"type": "integer",
+
"minimum": 1,
+
"description": "Ban duration in hours (null for permanent)"
+
},
+
"bannedBy": {
+
"type": "string",
+
"format": "did",
+
"description": "DID of moderator who issued ban (null for tribunal bans)"
+
},
+
"tribunalCase": {
+
"type": "string",
+
"format": "at-uri",
+
"description": "AT-URI of tribunal case that resulted in ban"
+
},
+
"status": {
+
"type": "string",
+
"knownValues": ["active", "expired", "revoked"],
+
"default": "active"
+
},
+
"expiresAt": {
+
"type": "string",
+
"format": "datetime",
+
"description": "When the ban expires (null for permanent)"
+
},
+
"revokedAt": {
+
"type": "string",
+
"format": "datetime",
+
"description": "When the ban was revoked"
+
},
+
"revokedBy": {
+
"type": "string",
+
"format": "did",
+
"description": "DID of moderator who revoked the ban"
+
},
+
"createdAt": {
+
"type": "string",
+
"format": "datetime"
+
}
+
}
+
}
+
}
+
}
+
}
+70
internal/atproto/lexicon/social/coves/moderation/banUser.json
···
+
{
+
"lexicon": 1,
+
"id": "social.coves.moderation.banUser",
+
"defs": {
+
"main": {
+
"type": "procedure",
+
"description": "Ban a user from a community (moderator action)",
+
"input": {
+
"encoding": "application/json",
+
"schema": {
+
"type": "object",
+
"required": ["community", "subject", "reason"],
+
"properties": {
+
"community": {
+
"type": "string",
+
"format": "at-uri",
+
"description": "AT-URI of the community"
+
},
+
"subject": {
+
"type": "string",
+
"format": "did",
+
"description": "DID of the user to ban"
+
},
+
"reason": {
+
"type": "string",
+
"maxLength": 2000,
+
"description": "Reason for the ban"
+
},
+
"duration": {
+
"type": "integer",
+
"minimum": 1,
+
"description": "Ban duration in hours (omit for permanent)"
+
}
+
}
+
}
+
},
+
"output": {
+
"encoding": "application/json",
+
"schema": {
+
"type": "object",
+
"required": ["ban"],
+
"properties": {
+
"ban": {
+
"type": "ref",
+
"ref": "social.coves.moderation.ban"
+
}
+
}
+
}
+
},
+
"errors": [
+
{
+
"name": "NotAuthorized",
+
"description": "User is not authorized to ban users in this community"
+
},
+
{
+
"name": "UserNotFound",
+
"description": "Target user does not exist"
+
},
+
{
+
"name": "CommunityNotFound",
+
"description": "Community does not exist"
+
},
+
{
+
"name": "AlreadyBanned",
+
"description": "User is already banned from this community"
+
}
+
]
+
}
+
}
+
}
+54
internal/atproto/lexicon/social/coves/moderation/getBanStatus.json
···
+
{
+
"lexicon": 1,
+
"id": "social.coves.moderation.getBanStatus",
+
"defs": {
+
"main": {
+
"type": "query",
+
"description": "Check if a user is banned from a community",
+
"parameters": {
+
"type": "params",
+
"required": ["community", "subject"],
+
"properties": {
+
"community": {
+
"type": "string",
+
"format": "at-uri",
+
"description": "AT-URI of the community"
+
},
+
"subject": {
+
"type": "string",
+
"format": "did",
+
"description": "DID of the user to check"
+
}
+
}
+
},
+
"output": {
+
"encoding": "application/json",
+
"schema": {
+
"type": "object",
+
"required": ["isBanned"],
+
"properties": {
+
"isBanned": {
+
"type": "boolean",
+
"description": "Whether the user is currently banned"
+
},
+
"ban": {
+
"type": "ref",
+
"ref": "social.coves.moderation.ban",
+
"description": "Ban record if user is banned"
+
}
+
}
+
}
+
},
+
"errors": [
+
{
+
"name": "CommunityNotFound",
+
"description": "Community does not exist"
+
},
+
{
+
"name": "UserNotFound",
+
"description": "User does not exist"
+
}
+
]
+
}
+
}
+
}
+68
internal/atproto/lexicon/social/coves/moderation/listBans.json
···
+
{
+
"lexicon": 1,
+
"id": "social.coves.moderation.listBans",
+
"defs": {
+
"main": {
+
"type": "query",
+
"description": "List bans for a community (moderator only)",
+
"parameters": {
+
"type": "params",
+
"required": ["community"],
+
"properties": {
+
"community": {
+
"type": "string",
+
"format": "at-uri",
+
"description": "AT-URI of the community"
+
},
+
"status": {
+
"type": "string",
+
"knownValues": ["active", "expired", "revoked", "all"],
+
"default": "active",
+
"description": "Filter by ban status"
+
},
+
"limit": {
+
"type": "integer",
+
"minimum": 1,
+
"maximum": 100,
+
"default": 50,
+
"description": "Maximum number of bans to return"
+
},
+
"cursor": {
+
"type": "string",
+
"description": "Pagination cursor"
+
}
+
}
+
},
+
"output": {
+
"encoding": "application/json",
+
"schema": {
+
"type": "object",
+
"required": ["bans"],
+
"properties": {
+
"bans": {
+
"type": "array",
+
"items": {
+
"type": "ref",
+
"ref": "social.coves.moderation.ban"
+
}
+
},
+
"cursor": {
+
"type": "string",
+
"description": "Pagination cursor for next page"
+
}
+
}
+
}
+
},
+
"errors": [
+
{
+
"name": "NotAuthorized",
+
"description": "User is not authorized to view bans for this community"
+
},
+
{
+
"name": "CommunityNotFound",
+
"description": "Community does not exist"
+
}
+
]
+
}
+
}
+
}
+65
internal/atproto/lexicon/social/coves/moderation/unbanUser.json
···
+
{
+
"lexicon": 1,
+
"id": "social.coves.moderation.unbanUser",
+
"defs": {
+
"main": {
+
"type": "procedure",
+
"description": "Unban a user from a community (moderator action)",
+
"input": {
+
"encoding": "application/json",
+
"schema": {
+
"type": "object",
+
"required": ["community", "subject"],
+
"properties": {
+
"community": {
+
"type": "string",
+
"format": "at-uri",
+
"description": "AT-URI of the community"
+
},
+
"subject": {
+
"type": "string",
+
"format": "did",
+
"description": "DID of the user to unban"
+
},
+
"reason": {
+
"type": "string",
+
"maxLength": 1000,
+
"description": "Reason for unbanning (optional)"
+
}
+
}
+
}
+
},
+
"output": {
+
"encoding": "application/json",
+
"schema": {
+
"type": "object",
+
"required": ["success"],
+
"properties": {
+
"success": {
+
"type": "boolean",
+
"description": "Whether the unban was successful"
+
}
+
}
+
}
+
},
+
"errors": [
+
{
+
"name": "NotAuthorized",
+
"description": "User is not authorized to unban users in this community"
+
},
+
{
+
"name": "UserNotFound",
+
"description": "Target user does not exist"
+
},
+
{
+
"name": "CommunityNotFound",
+
"description": "Community does not exist"
+
},
+
{
+
"name": "NotBanned",
+
"description": "User is not currently banned from this community"
+
}
+
]
+
}
+
}
+
}