init
This commit is contained in:
133
pkg/api/response.go
Normal file
133
pkg/api/response.go
Normal file
@@ -0,0 +1,133 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// Response represents a standard API response
|
||||
type Response struct {
|
||||
Success bool `json:"success"`
|
||||
Data interface{} `json:"data,omitempty"`
|
||||
Error *ErrorInfo `json:"error,omitempty"`
|
||||
Meta *Meta `json:"meta,omitempty"`
|
||||
}
|
||||
|
||||
// ErrorInfo contains error details
|
||||
type ErrorInfo struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Details string `json:"details,omitempty"`
|
||||
}
|
||||
|
||||
// Meta contains pagination and other metadata
|
||||
type Meta struct {
|
||||
Page int `json:"page,omitempty"`
|
||||
PageSize int `json:"page_size,omitempty"`
|
||||
TotalCount int64 `json:"total_count,omitempty"`
|
||||
TotalPages int `json:"total_pages,omitempty"`
|
||||
}
|
||||
|
||||
// Success sends a successful response
|
||||
func Success(c *gin.Context, data interface{}) {
|
||||
c.JSON(http.StatusOK, Response{
|
||||
Success: true,
|
||||
Data: data,
|
||||
})
|
||||
}
|
||||
|
||||
// SuccessWithMeta sends a successful response with metadata
|
||||
func SuccessWithMeta(c *gin.Context, data interface{}, meta *Meta) {
|
||||
c.JSON(http.StatusOK, Response{
|
||||
Success: true,
|
||||
Data: data,
|
||||
Meta: meta,
|
||||
})
|
||||
}
|
||||
|
||||
// Created sends a 201 Created response
|
||||
func Created(c *gin.Context, data interface{}) {
|
||||
c.JSON(http.StatusCreated, Response{
|
||||
Success: true,
|
||||
Data: data,
|
||||
})
|
||||
}
|
||||
|
||||
// NoContent sends a 204 No Content response
|
||||
func NoContent(c *gin.Context) {
|
||||
c.Status(http.StatusNoContent)
|
||||
}
|
||||
|
||||
// Error sends an error response
|
||||
func Error(c *gin.Context, statusCode int, code, message string) {
|
||||
c.JSON(statusCode, Response{
|
||||
Success: false,
|
||||
Error: &ErrorInfo{
|
||||
Code: code,
|
||||
Message: message,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// ErrorWithDetails sends an error response with additional details
|
||||
func ErrorWithDetails(c *gin.Context, statusCode int, code, message, details string) {
|
||||
c.JSON(statusCode, Response{
|
||||
Success: false,
|
||||
Error: &ErrorInfo{
|
||||
Code: code,
|
||||
Message: message,
|
||||
Details: details,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// BadRequest sends a 400 Bad Request response
|
||||
func BadRequest(c *gin.Context, message string) {
|
||||
Error(c, http.StatusBadRequest, "BAD_REQUEST", message)
|
||||
}
|
||||
|
||||
// NotFound sends a 404 Not Found response
|
||||
func NotFound(c *gin.Context, message string) {
|
||||
Error(c, http.StatusNotFound, "NOT_FOUND", message)
|
||||
}
|
||||
|
||||
// Conflict sends a 409 Conflict response
|
||||
func Conflict(c *gin.Context, message string) {
|
||||
Error(c, http.StatusConflict, "CONFLICT", message)
|
||||
}
|
||||
|
||||
// InternalError sends a 500 Internal Server Error response
|
||||
func InternalError(c *gin.Context, message string) {
|
||||
Error(c, http.StatusInternalServerError, "INTERNAL_ERROR", message)
|
||||
}
|
||||
|
||||
// ValidationError sends a 400 response for validation errors
|
||||
func ValidationError(c *gin.Context, message string) {
|
||||
Error(c, http.StatusBadRequest, "VALIDATION_ERROR", message)
|
||||
}
|
||||
|
||||
// BadGateway sends a 502 Bad Gateway response
|
||||
func BadGateway(c *gin.Context, message string) {
|
||||
Error(c, http.StatusBadGateway, "BAD_GATEWAY", message)
|
||||
}
|
||||
|
||||
// ServiceUnavailable sends a 503 Service Unavailable response
|
||||
func ServiceUnavailable(c *gin.Context, message string) {
|
||||
Error(c, http.StatusServiceUnavailable, "SERVICE_UNAVAILABLE", message)
|
||||
}
|
||||
|
||||
// Unauthorized sends a 401 Unauthorized response
|
||||
func Unauthorized(c *gin.Context, message string) {
|
||||
Error(c, http.StatusUnauthorized, "UNAUTHORIZED", message)
|
||||
}
|
||||
|
||||
// Forbidden sends a 403 Forbidden response
|
||||
func Forbidden(c *gin.Context, message string) {
|
||||
Error(c, http.StatusForbidden, "FORBIDDEN", message)
|
||||
}
|
||||
|
||||
// RequestEntityTooLarge sends a 413 Request Entity Too Large response
|
||||
func RequestEntityTooLarge(c *gin.Context, message string) {
|
||||
Error(c, http.StatusRequestEntityTooLarge, "REQUEST_ENTITY_TOO_LARGE", message)
|
||||
}
|
||||
94
pkg/utils/utils.go
Normal file
94
pkg/utils/utils.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"math"
|
||||
"time"
|
||||
)
|
||||
|
||||
// RoundToTwoDecimals rounds a float64 to two decimal places
|
||||
func RoundToTwoDecimals(value float64) float64 {
|
||||
return math.Round(value*100) / 100
|
||||
}
|
||||
|
||||
// StartOfDay returns the start of the day for a given time
|
||||
func StartOfDay(t time.Time) time.Time {
|
||||
return time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())
|
||||
}
|
||||
|
||||
// EndOfDay returns the end of the day for a given time
|
||||
func EndOfDay(t time.Time) time.Time {
|
||||
return time.Date(t.Year(), t.Month(), t.Day(), 23, 59, 59, 999999999, t.Location())
|
||||
}
|
||||
|
||||
// StartOfMonth returns the first day of the month for a given time
|
||||
func StartOfMonth(t time.Time) time.Time {
|
||||
return time.Date(t.Year(), t.Month(), 1, 0, 0, 0, 0, t.Location())
|
||||
}
|
||||
|
||||
// EndOfMonth returns the last day of the month for a given time
|
||||
func EndOfMonth(t time.Time) time.Time {
|
||||
return StartOfMonth(t).AddDate(0, 1, 0).Add(-time.Nanosecond)
|
||||
}
|
||||
|
||||
// StartOfYear returns the first day of the year for a given time
|
||||
func StartOfYear(t time.Time) time.Time {
|
||||
return time.Date(t.Year(), 1, 1, 0, 0, 0, 0, t.Location())
|
||||
}
|
||||
|
||||
// EndOfYear returns the last day of the year for a given time
|
||||
func EndOfYear(t time.Time) time.Time {
|
||||
return time.Date(t.Year(), 12, 31, 23, 59, 59, 999999999, t.Location())
|
||||
}
|
||||
|
||||
// StartOfWeek returns the start of the week (Monday) for a given time
|
||||
func StartOfWeek(t time.Time) time.Time {
|
||||
weekday := int(t.Weekday())
|
||||
if weekday == 0 {
|
||||
weekday = 7 // Sunday is 7
|
||||
}
|
||||
return StartOfDay(t.AddDate(0, 0, -(weekday - 1)))
|
||||
}
|
||||
|
||||
// EndOfWeek returns the end of the week (Sunday) for a given time
|
||||
func EndOfWeek(t time.Time) time.Time {
|
||||
return EndOfDay(StartOfWeek(t).AddDate(0, 0, 6))
|
||||
}
|
||||
|
||||
// ParseDate parses a date string in YYYY-MM-DD format
|
||||
func ParseDate(dateStr string) (time.Time, error) {
|
||||
return time.Parse("2006-01-02", dateStr)
|
||||
}
|
||||
|
||||
// FormatDate formats a time to YYYY-MM-DD string
|
||||
func FormatDate(t time.Time) string {
|
||||
return t.Format("2006-01-02")
|
||||
}
|
||||
|
||||
// Min returns the minimum of two integers
|
||||
func Min(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// Max returns the maximum of two integers
|
||||
func Max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// Abs returns the absolute value of a float64
|
||||
func Abs(value float64) float64 {
|
||||
return math.Abs(value)
|
||||
}
|
||||
|
||||
// CalculatePercentage calculates the percentage of part relative to total
|
||||
func CalculatePercentage(part, total float64) float64 {
|
||||
if total == 0 {
|
||||
return 0
|
||||
}
|
||||
return RoundToTwoDecimals((part / total) * 100)
|
||||
}
|
||||
Reference in New Issue
Block a user