A community based topic aggregation platform built on atproto
1package vote
2
3import (
4 "Coves/internal/api/middleware"
5 "Coves/internal/core/votes"
6 "encoding/json"
7 "log"
8 "net/http"
9)
10
11// DeleteVoteHandler handles vote deletion
12type DeleteVoteHandler struct {
13 service votes.Service
14}
15
16// NewDeleteVoteHandler creates a new delete vote handler
17func NewDeleteVoteHandler(service votes.Service) *DeleteVoteHandler {
18 return &DeleteVoteHandler{
19 service: service,
20 }
21}
22
23// DeleteVoteInput represents the request body for deleting a vote
24type DeleteVoteInput struct {
25 Subject struct {
26 URI string `json:"uri"`
27 CID string `json:"cid"`
28 } `json:"subject"`
29}
30
31// DeleteVoteOutput represents the response body for deleting a vote
32// Per lexicon: output is an empty object
33type DeleteVoteOutput struct{}
34
35// HandleDeleteVote removes a vote from a post or comment
36// POST /xrpc/social.coves.vote.delete
37//
38// Request body: { "subject": { "uri": "at://...", "cid": "..." } }
39// Response: { "success": true }
40func (h *DeleteVoteHandler) HandleDeleteVote(w http.ResponseWriter, r *http.Request) {
41 if r.Method != http.MethodPost {
42 http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
43 return
44 }
45
46 // Parse request body
47 var input DeleteVoteInput
48 if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
49 writeError(w, http.StatusBadRequest, "InvalidRequest", "Invalid request body")
50 return
51 }
52
53 // Validate required fields
54 if input.Subject.URI == "" {
55 writeError(w, http.StatusBadRequest, "InvalidRequest", "subject.uri is required")
56 return
57 }
58 if input.Subject.CID == "" {
59 writeError(w, http.StatusBadRequest, "InvalidRequest", "subject.cid is required")
60 return
61 }
62
63 // Get OAuth session from context (injected by auth middleware)
64 session := middleware.GetOAuthSession(r)
65 if session == nil {
66 writeError(w, http.StatusUnauthorized, "AuthRequired", "Authentication required")
67 return
68 }
69
70 // Create delete vote request
71 req := votes.DeleteVoteRequest{
72 Subject: votes.StrongRef{
73 URI: input.Subject.URI,
74 CID: input.Subject.CID,
75 },
76 }
77
78 // Call service to delete vote
79 err := h.service.DeleteVote(r.Context(), session, req)
80 if err != nil {
81 handleServiceError(w, err)
82 return
83 }
84
85 // Return success response (empty object per lexicon)
86 output := DeleteVoteOutput{}
87
88 w.Header().Set("Content-Type", "application/json")
89 w.WriteHeader(http.StatusOK)
90 if err := json.NewEncoder(w).Encode(output); err != nil {
91 log.Printf("Failed to encode response: %v", err)
92 }
93}