···
// CommunityPDSAccount represents PDS account credentials for a community
type CommunityPDSAccount struct {
DID string // Community's DID (owns the repository)
+
Handle string // Community's handle (e.g., gaming.community.coves.social)
Email string // System email for PDS account
Password string // Cleartext password (MUST be encrypted before database storage)
AccessToken string // JWT for making API calls as the community
···
// 1. Generate unique handle for the community
+
// Format: {name}.community.{instance-domain}
+
// Example: "gaming.community.coves.social"
+
// NOTE: Using SINGULAR "community" to follow atProto lexicon conventions
+
// (all record types use singular: app.bsky.feed.post, app.bsky.graph.follow, etc.)
+
handle := fmt.Sprintf("%s.community.%s", strings.ToLower(communityName), p.instanceDomain)
// 2. Generate system email for PDS account management
// This email is used for account operations, not for user communication
+
email := fmt.Sprintf("community-%s@community.%s", strings.ToLower(communityName), p.instanceDomain)
// 3. Generate secure random password (32 characters)
// This password is never shown to users - it's for Coves to authenticate as the community
···
// The repository layer handles encryption using pgp_sym_encrypt()
return &CommunityPDSAccount{
DID: output.Did, // The community's DID (PDS-generated)
+
Handle: output.Handle, // e.g., gaming.community.coves.social
+
Email: email, // community-gaming@community.coves.social
Password: password, // Cleartext - will be encrypted by repository
AccessToken: output.AccessJwt, // JWT for making API calls
RefreshToken: output.RefreshJwt, // For refreshing sessions