backend-ci.yml's `test -z "$(gofmt -l .)"` strict gate (added in
13c21ac11) failed on a backlog of unformatted files. None of the
85 files in this commit had been edited since the gate was added
because no push touched veza-backend-api/** in between, so the
gate never fired until today's CI fixes triggered it.
The diff is exclusively whitespace alignment in struct literals
and trailing-space comments. `go build ./...` and the full test
suite (with VEZA_SKIP_INTEGRATION=1 -short) pass identically.
84 lines
2.2 KiB
Go
84 lines
2.2 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
|
|
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
|
|
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
|
|
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)
|
|
}
|