A community based topic aggregation platform built on atproto

refactor(lexicon): align richtext facets with atProto best practices

Align richtext facet lexicon with atProto Lexinomicon style guide:

- Remove $type from required fields (automatically added by SDK for union discrimination)
- Remove handle field from mention type (use persistent DIDs only per best practices)
- Add maxGraphemes constraint to spoiler reason field for proper internationalization
- Update descriptions to match Bluesky documentation patterns
- Update tests to remove handle field references

References: https://github.com/bluesky-social/atproto/discussions/4245

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

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

+12 -51
+9 -46
internal/atproto/lexicon/social/coves/richtext/facet.json
··· 47 47 }, 48 48 "mention": { 49 49 "type": "object", 50 - "description": "Facet feature for user or community mentions", 51 - "required": ["$type", "did"], 50 + "description": "Facet feature for mention of a user or community. The text is usually a handle with '@' (user) or '!' (community) prefix, but the facet reference is a DID.", 51 + "required": ["did"], 52 52 "properties": { 53 - "$type": { 54 - "type": "string", 55 - "const": "social.coves.richtext.facet#mention" 56 - }, 57 53 "did": { 58 54 "type": "string", 59 55 "format": "did", 60 - "description": "DID of the mentioned user (@) or community (!)" 61 - }, 62 - "handle": { 63 - "type": "string", 64 - "description": "Handle at time of mention (may change)" 56 + "description": "DID of the mentioned user or community" 65 57 } 66 58 } 67 59 }, 68 60 "link": { 69 61 "type": "object", 70 - "description": "Facet feature for hyperlinks", 71 - "required": ["$type", "uri"], 62 + "description": "Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL.", 63 + "required": ["uri"], 72 64 "properties": { 73 - "$type": { 74 - "type": "string", 75 - "const": "social.coves.richtext.facet#link" 76 - }, 77 65 "uri": { 78 66 "type": "string", 79 67 "format": "uri", ··· 83 71 }, 84 72 "bold": { 85 73 "type": "object", 86 - "description": "Bold text formatting", 87 - "required": ["$type"], 88 - "properties": { 89 - "$type": { 90 - "type": "string", 91 - "const": "social.coves.richtext.facet#bold" 92 - } 93 - } 74 + "description": "Bold text formatting" 94 75 }, 95 76 "italic": { 96 77 "type": "object", 97 - "description": "Italic text formatting", 98 - "required": ["$type"], 99 - "properties": { 100 - "$type": { 101 - "type": "string", 102 - "const": "social.coves.richtext.facet#italic" 103 - } 104 - } 78 + "description": "Italic text formatting" 105 79 }, 106 80 "strikethrough": { 107 81 "type": "object", 108 - "description": "Strikethrough text formatting", 109 - "required": ["$type"], 110 - "properties": { 111 - "$type": { 112 - "type": "string", 113 - "const": "social.coves.richtext.facet#strikethrough" 114 - } 115 - } 82 + "description": "Strikethrough text formatting" 116 83 }, 117 84 "spoiler": { 118 85 "type": "object", 119 86 "description": "Hidden/spoiler text that requires user interaction to reveal", 120 - "required": ["$type"], 121 87 "properties": { 122 - "$type": { 123 - "type": "string", 124 - "const": "social.coves.richtext.facet#spoiler" 125 - }, 126 88 "reason": { 127 89 "type": "string", 128 90 "maxLength": 128, 91 + "maxGraphemes": 32, 129 92 "description": "Optional explanation of what's hidden" 130 93 } 131 94 }
+3 -5
internal/atproto/lexicon/social/coves/richtext/facet_test.go
··· 21 21 }, 22 22 "features": [{ 23 23 "$type": "social.coves.richtext.facet#mention", 24 - "did": "did:plc:example123", 25 - "handle": "alice.bsky.social" 24 + "did": "did:plc:example123" 26 25 }] 27 26 }`, 28 27 wantErr: false, ··· 276 275 name: "mention", 277 276 typeName: "social.coves.richtext.facet#mention", 278 277 feature: map[string]interface{}{ 279 - "$type": "social.coves.richtext.facet#mention", 280 - "did": "did:plc:example123", 281 - "handle": "alice.bsky.social", 278 + "$type": "social.coves.richtext.facet#mention", 279 + "did": "did:plc:example123", 282 280 }, 283 281 }, 284 282 {