// codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/interface/http/blockedemail/create.go package blockedemail import ( "bytes" "context" "encoding/json" "io" "net/http" "go.uber.org/zap" "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config" "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/interface/http/middleware" svc_blockedemail "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/service/blockedemail" "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/httperror" ) type CreateBlockedEmailHTTPHandler struct { config *config.Configuration logger *zap.Logger service svc_blockedemail.CreateBlockedEmailService middleware middleware.Middleware } func NewCreateBlockedEmailHTTPHandler( config *config.Configuration, logger *zap.Logger, service svc_blockedemail.CreateBlockedEmailService, middleware middleware.Middleware, ) *CreateBlockedEmailHTTPHandler { logger = logger.Named("CreateBlockedEmailHTTPHandler") return &CreateBlockedEmailHTTPHandler{ config: config, logger: logger, service: service, middleware: middleware, } } func (*CreateBlockedEmailHTTPHandler) Pattern() string { return "POST /api/v1/me/blocked-emails" } func (h *CreateBlockedEmailHTTPHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { h.middleware.Attach(h.Execute)(w, req) } func (h *CreateBlockedEmailHTTPHandler) unmarshalRequest( ctx context.Context, r *http.Request, ) (*svc_blockedemail.CreateBlockedEmailRequestDTO, error) { var requestData svc_blockedemail.CreateBlockedEmailRequestDTO defer r.Body.Close() var rawJSON bytes.Buffer teeReader := io.TeeReader(r.Body, &rawJSON) err := json.NewDecoder(teeReader).Decode(&requestData) if err != nil { h.logger.Error("decoding error", zap.Any("err", err)) // Log raw JSON at debug level only to avoid PII exposure in production logs h.logger.Debug("raw request body for debugging", zap.String("json", rawJSON.String())) return nil, httperror.NewForSingleField(http.StatusBadRequest, "non_field_error", "payload structure is wrong") } return &requestData, nil } func (h *CreateBlockedEmailHTTPHandler) Execute(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") ctx := r.Context() req, err := h.unmarshalRequest(ctx, r) if err != nil { httperror.RespondWithError(w, r, err) return } resp, err := h.service.Execute(ctx, req) if err != nil { httperror.RespondWithError(w, r, err) return } w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(resp); err != nil { h.logger.Error("failed to encode response", zap.Any("error", err)) httperror.RespondWithError(w, r, err) return } }