veza/veza-backend-api/internal/handlers/payout_handler.go
senke ef386e0ae3 fix(backend): commit swagger annotation pass + missing handler methods
routes_users.go (already on main) calls settingsHandler.GetPreferences /
UpdatePreferences and gdprExportHandler.ExportJSON, but the methods only
existed in the working tree — main wouldn't compile, so deploy.yml's
build-backend job was stuck on the same compile error every run.

Bundles the WIP swagger annotation sweep across chat / marketplace /
role / settings / gdpr / etc. handlers with the regenerated swagger.json,
swagger.yaml, docs.go and openapi.yaml.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 10:16:57 +02:00

114 lines
3.4 KiB
Go

package handlers
import (
"net/http"
"strconv"
"veza-backend-api/internal/core/marketplace"
apperrors "veza-backend-api/internal/errors"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
// PayoutHandler handles seller balance and payout endpoints (v0.12.0 F254)
type PayoutHandler struct {
marketService *marketplace.Service
logger *zap.Logger
}
// NewPayoutHandler creates a new PayoutHandler
func NewPayoutHandler(service *marketplace.Service, logger *zap.Logger) *PayoutHandler {
return &PayoutHandler{
marketService: service,
logger: logger,
}
}
// GetSellerBalance returns the seller's marketplace balance
// @Summary Get seller marketplace balance
// @Description Get current available and pending balance from marketplace sales.
// @Tags Sell
// @Accept json
// @Produce json
// @Security BearerAuth
// @Success 200 {object} handlers.APIResponse{data=object}
// @Failure 401 {object} handlers.APIResponse "Unauthorized"
// @Router /api/v1/sell/marketplace-balance [get]
func (h *PayoutHandler) GetSellerBalance(c *gin.Context) {
userID, ok := GetUserIDUUID(c)
if !ok {
return
}
balance, err := h.marketService.GetSellerBalance(c.Request.Context(), userID)
if err != nil {
RespondWithAppError(c, apperrors.NewInternalErrorWrap("Failed to get balance", err))
return
}
RespondSuccess(c, http.StatusOK, gin.H{
"available_cents": balance.AvailableCents,
"pending_cents": balance.PendingCents,
"total_earned_cents": balance.TotalEarnedCents,
"total_paid_out_cents": balance.TotalPaidOutCents,
"currency": balance.Currency,
})
}
// GetPayoutHistory returns the seller's payout history
// @Summary Get payout history
// @Description Get a list of past payout requests and their status.
// @Tags Sell
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param limit query int false "Limit" default(20)
// @Param offset query int false "Offset" default(0)
// @Success 200 {object} handlers.APIResponse{data=object{payouts=array}}
// @Failure 401 {object} handlers.APIResponse "Unauthorized"
// @Router /api/v1/sell/payouts [get]
func (h *PayoutHandler) GetPayoutHistory(c *gin.Context) {
userID, ok := GetUserIDUUID(c)
if !ok {
return
}
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "20"))
limit = clampLimit(limit) // SECURITY(MEDIUM-004)
offset, _ := strconv.Atoi(c.DefaultQuery("offset", "0"))
payouts, err := h.marketService.GetSellerPayouts(c.Request.Context(), userID, limit, offset)
if err != nil {
RespondWithAppError(c, apperrors.NewInternalErrorWrap("Failed to get payouts", err))
return
}
RespondSuccess(c, http.StatusOK, gin.H{"payouts": payouts})
}
// RequestPayout creates a manual payout request
// @Summary Request payout
// @Description Initiate a manual payout request for the available balance.
// @Tags Sell
// @Accept json
// @Produce json
// @Security BearerAuth
// @Success 201 {object} marketplace.SellerPayout
// @Failure 400 {object} handlers.APIResponse "Validation Error"
// @Failure 401 {object} handlers.APIResponse "Unauthorized"
// @Router /api/v1/sell/payouts/request [post]
func (h *PayoutHandler) RequestPayout(c *gin.Context) {
userID, ok := GetUserIDUUID(c)
if !ok {
return
}
payout, err := h.marketService.RequestPayout(c.Request.Context(), userID)
if err != nil {
RespondWithAppError(c, apperrors.NewValidationError(err.Error()))
return
}
RespondSuccess(c, http.StatusCreated, payout)
}