A community based topic aggregation platform built on atproto

feat(lexicon): add reusable defs and remove unimplemented features

- Add social.coves.actor.defs.json with profileView, profileViewDetailed,
profileStats, viewerState, and geoLocation definitions
- Add social.coves.community.defs.json with communityView, communityViewDetailed,
communityStats, and viewerState definitions
- Remove unimplemented actor lexicons: block, blockUser, unblockUser, saved,
saveItem, unsaveItem, getSaved, preferences
- Remove duplicate actor.subscription (replaced by community.subscription)

Following atProto best practices: reusable definitions in defs.json,
removing unimplemented features from pre-production codebase.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

+393 -588
-33
internal/atproto/lexicon/social/coves/actor/block.json
··· 1 - { 2 - "lexicon": 1, 3 - "id": "social.coves.actor.block", 4 - "defs": { 5 - "main": { 6 - "type": "record", 7 - "description": "A block relationship where one user blocks another", 8 - "key": "tid", 9 - "record": { 10 - "type": "object", 11 - "required": ["subject", "createdAt"], 12 - "properties": { 13 - "subject": { 14 - "type": "string", 15 - "format": "did", 16 - "description": "DID of the user being blocked" 17 - }, 18 - "createdAt": { 19 - "type": "string", 20 - "format": "datetime", 21 - "description": "When the block was created" 22 - }, 23 - "reason": { 24 - "type": "string", 25 - "maxGraphemes": 300, 26 - "maxLength": 3000, 27 - "description": "Optional reason for blocking" 28 - } 29 - } 30 - } 31 - } 32 - } 33 - }
-59
internal/atproto/lexicon/social/coves/actor/blockUser.json
··· 1 - { 2 - "lexicon": 1, 3 - "id": "social.coves.actor.blockUser", 4 - "defs": { 5 - "main": { 6 - "type": "procedure", 7 - "description": "Block another user", 8 - "input": { 9 - "encoding": "application/json", 10 - "schema": { 11 - "type": "object", 12 - "required": ["subject"], 13 - "properties": { 14 - "subject": { 15 - "type": "string", 16 - "format": "did", 17 - "description": "DID of the user to block" 18 - }, 19 - "reason": { 20 - "type": "string", 21 - "maxGraphemes": 300, 22 - "maxLength": 3000, 23 - "description": "Optional reason for blocking" 24 - } 25 - } 26 - } 27 - }, 28 - "output": { 29 - "encoding": "application/json", 30 - "schema": { 31 - "type": "object", 32 - "required": ["uri", "cid"], 33 - "properties": { 34 - "uri": { 35 - "type": "string", 36 - "format": "at-uri", 37 - "description": "AT-URI of the created block record" 38 - }, 39 - "cid": { 40 - "type": "string", 41 - "format": "cid", 42 - "description": "CID of the created block record" 43 - }, 44 - "existing": { 45 - "type": "boolean", 46 - "description": "True if user was already blocked" 47 - } 48 - } 49 - } 50 - }, 51 - "errors": [ 52 - { 53 - "name": "SubjectNotFound", 54 - "description": "Subject user not found" 55 - } 56 - ] 57 - } 58 - } 59 - }
+139
internal/atproto/lexicon/social/coves/actor/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.coves.actor.defs", 4 + "defs": { 5 + "profileView": { 6 + "type": "object", 7 + "description": "Basic profile view with essential information", 8 + "required": ["did"], 9 + "properties": { 10 + "did": { 11 + "type": "string", 12 + "format": "did" 13 + }, 14 + "handle": { 15 + "type": "string", 16 + "format": "handle", 17 + "description": "Current handle resolved from DID" 18 + }, 19 + "displayName": { 20 + "type": "string", 21 + "maxGraphemes": 64, 22 + "maxLength": 640 23 + }, 24 + "avatar": { 25 + "type": "string", 26 + "format": "uri", 27 + "description": "URL to avatar image" 28 + } 29 + } 30 + }, 31 + "profileViewDetailed": { 32 + "type": "object", 33 + "description": "Detailed profile view with stats and viewer state", 34 + "required": ["did"], 35 + "properties": { 36 + "did": { 37 + "type": "string", 38 + "format": "did" 39 + }, 40 + "handle": { 41 + "type": "string", 42 + "format": "handle", 43 + "description": "Current handle resolved from DID" 44 + }, 45 + "displayName": { 46 + "type": "string", 47 + "maxGraphemes": 64, 48 + "maxLength": 640 49 + }, 50 + "bio": { 51 + "type": "string", 52 + "maxGraphemes": 256, 53 + "maxLength": 2560 54 + }, 55 + "bioFacets": { 56 + "type": "array", 57 + "description": "Rich text annotations for bio", 58 + "items": { 59 + "type": "ref", 60 + "ref": "social.coves.richtext.facet" 61 + } 62 + }, 63 + "avatar": { 64 + "type": "string", 65 + "format": "uri", 66 + "description": "URL to avatar image" 67 + }, 68 + "banner": { 69 + "type": "string", 70 + "format": "uri", 71 + "description": "URL to banner image" 72 + }, 73 + "createdAt": { 74 + "type": "string", 75 + "format": "datetime" 76 + }, 77 + "stats": { 78 + "type": "ref", 79 + "ref": "#profileStats", 80 + "description": "Aggregated statistics" 81 + }, 82 + "viewer": { 83 + "type": "ref", 84 + "ref": "#viewerState", 85 + "description": "Viewer's relationship to this profile" 86 + } 87 + } 88 + }, 89 + "profileStats": { 90 + "type": "object", 91 + "description": "Aggregated statistics for a user profile", 92 + "properties": { 93 + "postCount": { 94 + "type": "integer", 95 + "minimum": 0, 96 + "description": "Total number of posts created" 97 + }, 98 + "commentCount": { 99 + "type": "integer", 100 + "minimum": 0, 101 + "description": "Total number of comments made" 102 + }, 103 + "communityCount": { 104 + "type": "integer", 105 + "minimum": 0, 106 + "description": "Number of communities subscribed to" 107 + }, 108 + "reputation": { 109 + "type": "integer", 110 + "description": "Global reputation score" 111 + }, 112 + "membershipCount": { 113 + "type": "integer", 114 + "minimum": 0, 115 + "description": "Number of communities with membership status" 116 + } 117 + } 118 + }, 119 + "viewerState": { 120 + "type": "object", 121 + "description": "The viewing user's relationship to this profile", 122 + "properties": { 123 + "blocked": { 124 + "type": "boolean", 125 + "description": "Whether the viewer has blocked this user" 126 + }, 127 + "blockedBy": { 128 + "type": "boolean", 129 + "description": "Whether the viewer is blocked by this user" 130 + }, 131 + "blockUri": { 132 + "type": "string", 133 + "format": "at-uri", 134 + "description": "AT-URI of the block record if viewer blocked this user" 135 + } 136 + } 137 + } 138 + } 139 + }
-85
internal/atproto/lexicon/social/coves/actor/getSaved.json
··· 1 - { 2 - "lexicon": 1, 3 - "id": "social.coves.actor.getSaved", 4 - "defs": { 5 - "main": { 6 - "type": "query", 7 - "description": "Get all saved posts and comments for the authenticated user", 8 - "input": { 9 - "encoding": "application/json", 10 - "schema": { 11 - "type": "object", 12 - "properties": { 13 - "limit": { 14 - "type": "integer", 15 - "minimum": 1, 16 - "maximum": 100, 17 - "default": 50, 18 - "description": "Number of items to return" 19 - }, 20 - "cursor": { 21 - "type": "string", 22 - "description": "Cursor for pagination" 23 - }, 24 - "type": { 25 - "type": "string", 26 - "enum": ["post", "comment"], 27 - "description": "Filter by content type (optional)" 28 - } 29 - } 30 - } 31 - }, 32 - "output": { 33 - "encoding": "application/json", 34 - "schema": { 35 - "type": "object", 36 - "required": ["savedItems"], 37 - "properties": { 38 - "savedItems": { 39 - "type": "array", 40 - "description": "All saved items for the user", 41 - "items": { 42 - "type": "ref", 43 - "ref": "#savedItemView" 44 - } 45 - }, 46 - "cursor": { 47 - "type": "string", 48 - "description": "Cursor for next page" 49 - } 50 - } 51 - } 52 - } 53 - }, 54 - "savedItemView": { 55 - "type": "object", 56 - "required": ["uri", "subject", "type", "savedAt"], 57 - "properties": { 58 - "uri": { 59 - "type": "string", 60 - "format": "at-uri", 61 - "description": "AT-URI of the saved record" 62 - }, 63 - "subject": { 64 - "type": "string", 65 - "format": "at-uri", 66 - "description": "AT-URI of the saved post or comment" 67 - }, 68 - "type": { 69 - "type": "string", 70 - "enum": ["post", "comment"], 71 - "description": "Type of content that was saved" 72 - }, 73 - "savedAt": { 74 - "type": "string", 75 - "format": "datetime", 76 - "description": "When the item was saved" 77 - }, 78 - "note": { 79 - "type": "string", 80 - "description": "Optional note about why this was saved" 81 - } 82 - } 83 - } 84 - } 85 - }
-198
internal/atproto/lexicon/social/coves/actor/preferences.json
··· 1 - { 2 - "lexicon": 1, 3 - "id": "social.coves.actor.preferences", 4 - "defs": { 5 - "main": { 6 - "type": "record", 7 - "description": "User preferences and settings", 8 - "key": "literal:self", 9 - "record": { 10 - "type": "object", 11 - "properties": { 12 - "feedPreferences": { 13 - "type": "ref", 14 - "ref": "#feedPreferences" 15 - }, 16 - "contentFiltering": { 17 - "type": "ref", 18 - "ref": "#contentFiltering" 19 - }, 20 - "notificationSettings": { 21 - "type": "ref", 22 - "ref": "#notificationSettings" 23 - }, 24 - "privacySettings": { 25 - "type": "ref", 26 - "ref": "#privacySettings" 27 - }, 28 - "displayPreferences": { 29 - "type": "ref", 30 - "ref": "#displayPreferences" 31 - } 32 - } 33 - } 34 - }, 35 - "feedPreferences": { 36 - "type": "object", 37 - "description": "Feed and content preferences", 38 - "properties": { 39 - "defaultFeed": { 40 - "type": "string", 41 - "enum": ["home", "all"], 42 - "default": "home" 43 - }, 44 - "defaultSort": { 45 - "type": "string", 46 - "enum": ["hot", "new", "top"], 47 - "default": "hot", 48 - "description": "Default sort order for community feeds" 49 - }, 50 - "showNSFW": { 51 - "type": "boolean", 52 - "default": false 53 - }, 54 - "blurNSFW": { 55 - "type": "boolean", 56 - "default": true, 57 - "description": "Blur NSFW content until clicked" 58 - }, 59 - "autoplayVideos": { 60 - "type": "boolean", 61 - "default": false 62 - }, 63 - "infiniteScroll": { 64 - "type": "boolean", 65 - "default": true 66 - } 67 - } 68 - }, 69 - "contentFiltering": { 70 - "type": "object", 71 - "description": "Content filtering preferences", 72 - "properties": { 73 - "blockedTags": { 74 - "type": "array", 75 - "items": { 76 - "type": "string" 77 - }, 78 - "description": "Tags to filter out from feeds" 79 - }, 80 - "blockedCommunities": { 81 - "type": "array", 82 - "items": { 83 - "type": "string", 84 - "format": "did" 85 - }, 86 - "description": "Communities to filter out from /all feeds" 87 - }, 88 - "mutedWords": { 89 - "type": "array", 90 - "items": { 91 - "type": "string" 92 - }, 93 - "description": "Words to filter out from content" 94 - }, 95 - "languageFilter": { 96 - "type": "array", 97 - "items": { 98 - "type": "string", 99 - "format": "language" 100 - }, 101 - "description": "Only show content in these languages" 102 - } 103 - } 104 - }, 105 - "notificationSettings": { 106 - "type": "object", 107 - "description": "Notification preferences", 108 - "properties": { 109 - "postReplies": { 110 - "type": "boolean", 111 - "default": true 112 - }, 113 - "commentReplies": { 114 - "type": "boolean", 115 - "default": true 116 - }, 117 - "mentions": { 118 - "type": "boolean", 119 - "default": true 120 - }, 121 - "upvotes": { 122 - "type": "boolean", 123 - "default": false 124 - }, 125 - "newFollowers": { 126 - "type": "boolean", 127 - "default": true 128 - }, 129 - "communityInvites": { 130 - "type": "boolean", 131 - "default": true 132 - }, 133 - "moderatorNotifications": { 134 - "type": "boolean", 135 - "default": true, 136 - "description": "Notifications for moderator actions in your communities" 137 - } 138 - } 139 - }, 140 - "privacySettings": { 141 - "type": "object", 142 - "description": "Privacy preferences", 143 - "properties": { 144 - "profileVisibility": { 145 - "type": "string", 146 - "enum": ["public", "authenticated", "followers"], 147 - "default": "public" 148 - }, 149 - "showSubscriptions": { 150 - "type": "boolean", 151 - "default": true 152 - }, 153 - "showSavedPosts": { 154 - "type": "boolean", 155 - "default": false 156 - }, 157 - "showVoteHistory": { 158 - "type": "boolean", 159 - "default": false 160 - }, 161 - "allowDMs": { 162 - "type": "string", 163 - "enum": ["everyone", "followers", "none"], 164 - "default": "everyone" 165 - } 166 - } 167 - }, 168 - "displayPreferences": { 169 - "type": "object", 170 - "description": "Display and UI preferences", 171 - "properties": { 172 - "theme": { 173 - "type": "string", 174 - "enum": ["light", "dark", "auto"], 175 - "default": "auto" 176 - }, 177 - "compactView": { 178 - "type": "boolean", 179 - "default": false 180 - }, 181 - "showAvatars": { 182 - "type": "boolean", 183 - "default": true 184 - }, 185 - "showThumbnails": { 186 - "type": "boolean", 187 - "default": true 188 - }, 189 - "postsPerPage": { 190 - "type": "integer", 191 - "minimum": 10, 192 - "maximum": 100, 193 - "default": 25 194 - } 195 - } 196 - } 197 - } 198 - }
-63
internal/atproto/lexicon/social/coves/actor/saveItem.json
··· 1 - { 2 - "lexicon": 1, 3 - "id": "social.coves.actor.saveItem", 4 - "defs": { 5 - "main": { 6 - "type": "procedure", 7 - "description": "Save a post or comment", 8 - "input": { 9 - "encoding": "application/json", 10 - "schema": { 11 - "type": "object", 12 - "required": ["subject", "type"], 13 - "properties": { 14 - "subject": { 15 - "type": "string", 16 - "format": "at-uri", 17 - "description": "AT-URI of the post or comment to save" 18 - }, 19 - "type": { 20 - "type": "string", 21 - "enum": ["post", "comment"], 22 - "description": "Type of content being saved" 23 - }, 24 - "note": { 25 - "type": "string", 26 - "maxLength": 300, 27 - "description": "Optional note about why this was saved" 28 - } 29 - } 30 - } 31 - }, 32 - "output": { 33 - "encoding": "application/json", 34 - "schema": { 35 - "type": "object", 36 - "required": ["uri", "cid"], 37 - "properties": { 38 - "uri": { 39 - "type": "string", 40 - "format": "at-uri", 41 - "description": "AT-URI of the created saved record" 42 - }, 43 - "cid": { 44 - "type": "string", 45 - "format": "cid", 46 - "description": "CID of the created saved record" 47 - }, 48 - "existing": { 49 - "type": "boolean", 50 - "description": "True if item was already saved" 51 - } 52 - } 53 - } 54 - }, 55 - "errors": [ 56 - { 57 - "name": "SubjectNotFound", 58 - "description": "The post or comment to save was not found" 59 - } 60 - ] 61 - } 62 - } 63 - }
-37
internal/atproto/lexicon/social/coves/actor/saved.json
··· 1 - { 2 - "lexicon": 1, 3 - "id": "social.coves.actor.saved", 4 - "defs": { 5 - "main": { 6 - "type": "record", 7 - "description": "A saved post or comment", 8 - "key": "tid", 9 - "record": { 10 - "type": "object", 11 - "required": ["subject", "type", "createdAt"], 12 - "properties": { 13 - "subject": { 14 - "type": "string", 15 - "format": "at-uri", 16 - "description": "AT-URI of the post or comment being saved" 17 - }, 18 - "type": { 19 - "type": "string", 20 - "enum": ["post", "comment"], 21 - "description": "Type of content being saved" 22 - }, 23 - "createdAt": { 24 - "type": "string", 25 - "format": "datetime", 26 - "description": "When the item was saved" 27 - }, 28 - "note": { 29 - "type": "string", 30 - "maxLength": 300, 31 - "description": "Optional note about why this was saved" 32 - } 33 - } 34 - } 35 - } 36 - } 37 - }
-39
internal/atproto/lexicon/social/coves/actor/subscription.json
··· 1 - { 2 - "lexicon": 1, 3 - "id": "social.coves.actor.subscription", 4 - "defs": { 5 - "main": { 6 - "type": "record", 7 - "description": "A subscription to a community", 8 - "key": "tid", 9 - "record": { 10 - "type": "object", 11 - "required": ["community", "createdAt"], 12 - "properties": { 13 - "community": { 14 - "type": "string", 15 - "format": "at-identifier", 16 - "description": "DID or handle of the community" 17 - }, 18 - "createdAt": { 19 - "type": "string", 20 - "format": "datetime", 21 - "description": "When the subscription started" 22 - }, 23 - "endedAt": { 24 - "type": "string", 25 - "format": "datetime", 26 - "description": "When the subscription ended (null if current)" 27 - }, 28 - "contentVisibility": { 29 - "type": "integer", 30 - "minimum": 1, 31 - "maximum": 5, 32 - "default": 3, 33 - "description": "Content visibility level (1=only best content, 5=all content)" 34 - } 35 - } 36 - } 37 - } 38 - } 39 - }
-37
internal/atproto/lexicon/social/coves/actor/unblockUser.json
··· 1 - { 2 - "lexicon": 1, 3 - "id": "social.coves.actor.unblockUser", 4 - "defs": { 5 - "main": { 6 - "type": "procedure", 7 - "description": "Unblock a previously blocked user", 8 - "input": { 9 - "encoding": "application/json", 10 - "schema": { 11 - "type": "object", 12 - "required": ["subject"], 13 - "properties": { 14 - "subject": { 15 - "type": "string", 16 - "format": "did", 17 - "description": "DID of the user to unblock" 18 - } 19 - } 20 - } 21 - }, 22 - "output": { 23 - "encoding": "application/json", 24 - "schema": { 25 - "type": "object", 26 - "properties": {} 27 - } 28 - }, 29 - "errors": [ 30 - { 31 - "name": "NotBlocked", 32 - "description": "User is not currently blocked" 33 - } 34 - ] 35 - } 36 - } 37 - }
-37
internal/atproto/lexicon/social/coves/actor/unsaveItem.json
··· 1 - { 2 - "lexicon": 1, 3 - "id": "social.coves.actor.unsaveItem", 4 - "defs": { 5 - "main": { 6 - "type": "procedure", 7 - "description": "Unsave a previously saved post or comment", 8 - "input": { 9 - "encoding": "application/json", 10 - "schema": { 11 - "type": "object", 12 - "required": ["subject"], 13 - "properties": { 14 - "subject": { 15 - "type": "string", 16 - "format": "at-uri", 17 - "description": "AT-URI of the post or comment to unsave" 18 - } 19 - } 20 - } 21 - }, 22 - "output": { 23 - "encoding": "application/json", 24 - "schema": { 25 - "type": "object", 26 - "properties": {} 27 - } 28 - }, 29 - "errors": [ 30 - { 31 - "name": "NotSaved", 32 - "description": "Item is not currently saved" 33 - } 34 - ] 35 - } 36 - } 37 - }
+254
internal/atproto/lexicon/social/coves/community/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.coves.community.defs", 4 + "defs": { 5 + "communityView": { 6 + "type": "object", 7 + "description": "Basic community view with essential information and basic stats", 8 + "required": ["did", "name"], 9 + "properties": { 10 + "did": { 11 + "type": "string", 12 + "format": "did", 13 + "description": "DID of the community" 14 + }, 15 + "handle": { 16 + "type": "string", 17 + "format": "handle", 18 + "description": "Current handle resolved from DID" 19 + }, 20 + "name": { 21 + "type": "string", 22 + "maxLength": 64, 23 + "description": "Short community name" 24 + }, 25 + "displayName": { 26 + "type": "string", 27 + "maxGraphemes": 128, 28 + "maxLength": 1280, 29 + "description": "Display name for the community" 30 + }, 31 + "avatar": { 32 + "type": "string", 33 + "format": "uri", 34 + "description": "URL to community avatar image" 35 + }, 36 + "visibility": { 37 + "type": "string", 38 + "knownValues": ["public", "unlisted", "private"], 39 + "description": "Community visibility level" 40 + }, 41 + "subscriberCount": { 42 + "type": "integer", 43 + "minimum": 0, 44 + "description": "Total number of subscribers" 45 + }, 46 + "memberCount": { 47 + "type": "integer", 48 + "minimum": 0, 49 + "description": "Number of users with formal membership status" 50 + }, 51 + "postCount": { 52 + "type": "integer", 53 + "minimum": 0, 54 + "description": "Total number of posts in the community" 55 + }, 56 + "viewer": { 57 + "type": "object", 58 + "description": "Simplified viewer state for list views", 59 + "properties": { 60 + "subscribed": { 61 + "type": "boolean", 62 + "description": "Whether the viewer is subscribed" 63 + }, 64 + "member": { 65 + "type": "boolean", 66 + "description": "Whether the viewer has membership status" 67 + } 68 + } 69 + } 70 + } 71 + }, 72 + "communityViewDetailed": { 73 + "type": "object", 74 + "description": "Detailed community view with stats and viewer state", 75 + "required": ["did", "name"], 76 + "properties": { 77 + "did": { 78 + "type": "string", 79 + "format": "did", 80 + "description": "DID of the community" 81 + }, 82 + "handle": { 83 + "type": "string", 84 + "format": "handle", 85 + "description": "Current handle resolved from DID" 86 + }, 87 + "name": { 88 + "type": "string", 89 + "maxLength": 64, 90 + "description": "Short community name" 91 + }, 92 + "displayName": { 93 + "type": "string", 94 + "maxGraphemes": 128, 95 + "maxLength": 1280, 96 + "description": "Display name for the community" 97 + }, 98 + "description": { 99 + "type": "string", 100 + "maxGraphemes": 1000, 101 + "maxLength": 10000, 102 + "description": "Community description with rich text support" 103 + }, 104 + "descriptionFacets": { 105 + "type": "array", 106 + "description": "Rich text annotations for description", 107 + "items": { 108 + "type": "ref", 109 + "ref": "social.coves.richtext.facet" 110 + } 111 + }, 112 + "avatar": { 113 + "type": "string", 114 + "format": "uri", 115 + "description": "URL to community avatar image" 116 + }, 117 + "banner": { 118 + "type": "string", 119 + "format": "uri", 120 + "description": "URL to community banner image" 121 + }, 122 + "createdBy": { 123 + "type": "string", 124 + "format": "did", 125 + "description": "DID of the user who created this community" 126 + }, 127 + "createdByProfile": { 128 + "type": "ref", 129 + "ref": "social.coves.actor.defs#profileView", 130 + "description": "Profile of the community creator" 131 + }, 132 + "hostedBy": { 133 + "type": "string", 134 + "format": "did", 135 + "description": "DID of the instance hosting this community" 136 + }, 137 + "visibility": { 138 + "type": "string", 139 + "knownValues": ["public", "unlisted", "private"], 140 + "description": "Community visibility level" 141 + }, 142 + "moderationType": { 143 + "type": "string", 144 + "knownValues": ["moderator", "sortition"], 145 + "description": "Type of moderation system" 146 + }, 147 + "contentWarnings": { 148 + "type": "array", 149 + "description": "Required content warnings for this community", 150 + "items": { 151 + "type": "string", 152 + "knownValues": ["nsfw", "violence", "spoilers"], 153 + "maxLength": 32 154 + } 155 + }, 156 + "createdAt": { 157 + "type": "string", 158 + "format": "datetime" 159 + }, 160 + "stats": { 161 + "type": "ref", 162 + "ref": "#communityStats", 163 + "description": "Aggregated community statistics" 164 + }, 165 + "viewer": { 166 + "type": "ref", 167 + "ref": "#viewerState", 168 + "description": "Viewer's relationship to this community" 169 + } 170 + } 171 + }, 172 + "communityStats": { 173 + "type": "object", 174 + "description": "Aggregated statistics for a community", 175 + "properties": { 176 + "memberCount": { 177 + "type": "integer", 178 + "minimum": 0, 179 + "description": "Number of users with formal membership status" 180 + }, 181 + "subscriberCount": { 182 + "type": "integer", 183 + "minimum": 0, 184 + "description": "Total number of subscribers" 185 + }, 186 + "postCount": { 187 + "type": "integer", 188 + "minimum": 0, 189 + "description": "Total number of posts in the community" 190 + }, 191 + "commentCount": { 192 + "type": "integer", 193 + "minimum": 0, 194 + "description": "Total number of comments across all posts" 195 + }, 196 + "activeUserCount": { 197 + "type": "integer", 198 + "minimum": 0, 199 + "description": "Number of users active in the last 30 days" 200 + }, 201 + "activePostersCount": { 202 + "type": "integer", 203 + "minimum": 0, 204 + "description": "Number of unique posters in the last 30 days" 205 + }, 206 + "moderatorCount": { 207 + "type": "integer", 208 + "minimum": 0, 209 + "description": "Number of active moderators" 210 + } 211 + } 212 + }, 213 + "viewerState": { 214 + "type": "object", 215 + "description": "The viewing user's relationship to this community", 216 + "properties": { 217 + "subscribed": { 218 + "type": "boolean", 219 + "description": "Whether the viewer is subscribed to this community" 220 + }, 221 + "subscriptionUri": { 222 + "type": "string", 223 + "format": "at-uri", 224 + "description": "AT-URI of the viewer's subscription record if subscribed" 225 + }, 226 + "member": { 227 + "type": "boolean", 228 + "description": "Whether the viewer has membership status (AppView-computed)" 229 + }, 230 + "reputation": { 231 + "type": "integer", 232 + "description": "Viewer's reputation in this community" 233 + }, 234 + "moderator": { 235 + "type": "boolean", 236 + "description": "Whether the viewer is a moderator of this community" 237 + }, 238 + "creator": { 239 + "type": "boolean", 240 + "description": "Whether the viewer created this community" 241 + }, 242 + "banned": { 243 + "type": "boolean", 244 + "description": "Whether the viewer is banned from this community" 245 + }, 246 + "banUri": { 247 + "type": "string", 248 + "format": "at-uri", 249 + "description": "AT-URI of the ban record if viewer is banned" 250 + } 251 + } 252 + } 253 + } 254 + }