A community based topic aggregation platform built on atproto
1package vote
2
3import (
4 "Coves/internal/api/handlers"
5 "Coves/internal/api/middleware"
6 "Coves/internal/core/votes"
7 "encoding/json"
8 "log"
9 "net/http"
10)
11
12// DeleteVoteHandler handles vote deletion
13type DeleteVoteHandler struct {
14 service votes.Service
15}
16
17// NewDeleteVoteHandler creates a new delete vote handler
18func NewDeleteVoteHandler(service votes.Service) *DeleteVoteHandler {
19 return &DeleteVoteHandler{
20 service: service,
21 }
22}
23
24// HandleDeleteVote removes a vote from a post/comment
25// POST /xrpc/social.coves.interaction.deleteVote
26//
27// Request body: { "subject": "at://..." }
28func (h *DeleteVoteHandler) HandleDeleteVote(w http.ResponseWriter, r *http.Request) {
29 if r.Method != http.MethodPost {
30 http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
31 return
32 }
33
34 // Parse request body
35 var req votes.DeleteVoteRequest
36
37 if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
38 handlers.WriteError(w, http.StatusBadRequest, "InvalidRequest", "Invalid request body")
39 return
40 }
41
42 if req.Subject == "" {
43 handlers.WriteError(w, http.StatusBadRequest, "InvalidRequest", "subject is required")
44 return
45 }
46
47 // Extract authenticated user DID and access token from request context (injected by auth middleware)
48 voterDID := middleware.GetUserDID(r)
49 if voterDID == "" {
50 handlers.WriteError(w, http.StatusUnauthorized, "AuthRequired", "Authentication required")
51 return
52 }
53
54 userAccessToken := middleware.GetUserAccessToken(r)
55 if userAccessToken == "" {
56 handlers.WriteError(w, http.StatusUnauthorized, "AuthRequired", "Missing access token")
57 return
58 }
59
60 // Delete vote via service (delete record on PDS)
61 err := h.service.DeleteVote(r.Context(), voterDID, userAccessToken, req)
62 if err != nil {
63 handleServiceError(w, err)
64 return
65 }
66
67 // Return success response
68 w.Header().Set("Content-Type", "application/json")
69 w.WriteHeader(http.StatusOK)
70 if err := json.NewEncoder(w).Encode(map[string]interface{}{
71 "success": true,
72 }); err != nil {
73 log.Printf("Failed to encode response: %v", err)
74 }
75}