A community based topic aggregation platform built on atproto
1package community 2 3import ( 4 "Coves/internal/api/middleware" 5 "Coves/internal/core/communities" 6 "encoding/json" 7 "net/http" 8) 9 10// CreateHandler handles community creation 11type CreateHandler struct { 12 service communities.Service 13} 14 15// NewCreateHandler creates a new create handler 16func NewCreateHandler(service communities.Service) *CreateHandler { 17 return &CreateHandler{ 18 service: service, 19 } 20} 21 22// HandleCreate creates a new community 23// POST /xrpc/social.coves.community.create 24// Body matches CreateCommunityRequest 25func (h *CreateHandler) HandleCreate(w http.ResponseWriter, r *http.Request) { 26 if r.Method != http.MethodPost { 27 http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) 28 return 29 } 30 31 // Parse request body 32 var req communities.CreateCommunityRequest 33 if err := json.NewDecoder(r.Body).Decode(&req); err != nil { 34 writeError(w, http.StatusBadRequest, "InvalidRequest", "Invalid request body") 35 return 36 } 37 38 // Extract authenticated user DID from request context (injected by auth middleware) 39 userDID := middleware.GetUserDID(r) 40 if userDID == "" { 41 writeError(w, http.StatusUnauthorized, "AuthRequired", "Authentication required") 42 return 43 } 44 45 // Client should not send createdByDid - we derive it from authenticated user 46 if req.CreatedByDID != "" { 47 writeError(w, http.StatusBadRequest, "InvalidRequest", 48 "createdByDid must not be provided - derived from authenticated user") 49 return 50 } 51 52 // Client should not send hostedByDid - we derive it from the instance 53 if req.HostedByDID != "" { 54 writeError(w, http.StatusBadRequest, "InvalidRequest", 55 "hostedByDid must not be provided - derived from instance") 56 return 57 } 58 59 // Set the authenticated user as the creator 60 req.CreatedByDID = userDID 61 // Note: hostedByDID will be set by the service layer based on instance configuration 62 63 // Create community via service (write-forward to PDS) 64 community, err := h.service.CreateCommunity(r.Context(), req) 65 if err != nil { 66 handleServiceError(w, err) 67 return 68 } 69 70 // Return success response matching lexicon output 71 response := map[string]interface{}{ 72 "uri": community.RecordURI, 73 "cid": community.RecordCID, 74 "did": community.DID, 75 "handle": community.Handle, 76 } 77 78 w.Header().Set("Content-Type", "application/json") 79 w.WriteHeader(http.StatusOK) 80 if err := json.NewEncoder(w).Encode(response); err != nil { 81 // Log encoding errors but don't return error response (headers already sent) 82 // This follows Go's standard practice for HTTP handlers 83 _ = err 84 } 85}