refactor: Replace interface{} with any alias and optimize string formatting with fmt.Appendf

- Replace map[string]interface{} with map[string]any in GraphQL, metrics, payment gateway, and webhook handlers
- Replace []byte(fmt.Sprintf()) with fmt.Appendf(nil, ...) for cursor encoding in GraphQL resolvers and tests
- Replace strings.HasPrefix/TrimPrefix with strings.CutPrefix for webhook signature parsing
- Replace stripe.Int64/Bool with new() constructor for Stripe payment parameters
- Rename Error
This commit is contained in:
nutcas3
2026-04-23 02:56:24 +03:00
parent a839b1cde5
commit d114f1960f
8 changed files with 58 additions and 57 deletions
@@ -370,6 +370,6 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
return nil
}
func (e *executableSchema) Extensions() map[string]interface{} {
return map[string]interface{}{}
func (e *executableSchema) Extensions() map[string]any {
return map[string]any{}
}
@@ -54,8 +54,8 @@ func strPtr(s string) *string { return new(s) }
func buildConnectionPageInfo(offset, count int, total int64) *PageInfo {
var startCursor, endCursor *string
if count > 0 {
startCursor = strPtr(base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%d", offset+1))))
endCursor = strPtr(base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%d", offset+count))))
startCursor = strPtr(base64.StdEncoding.EncodeToString(fmt.Appendf(nil, "%d", offset+1)))
endCursor = strPtr(base64.StdEncoding.EncodeToString(fmt.Appendf(nil, "%d", offset+count)))
}
return &PageInfo{
HasNextPage: int64(offset+count) < total,
@@ -104,7 +104,7 @@ func (r *Resolver) Subscribers(ctx context.Context, first *int, after *string, f
s := sub // avoid loop-variable capture
edges[i] = &SubscriberEdge{
Node: &s,
Cursor: base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%d", offset+i+1))),
Cursor: base64.StdEncoding.EncodeToString(fmt.Appendf(nil, "%d", offset+i+1)),
}
}
@@ -143,7 +143,7 @@ func (r *Resolver) UsageEvents(ctx context.Context, first *int, after *string, i
for i, event := range events {
edges[i] = &UsageEventEdge{
Node: event,
Cursor: base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%d", offset+i+1))),
Cursor: base64.StdEncoding.EncodeToString(fmt.Appendf(nil, "%d", offset+i+1)),
}
}
@@ -225,7 +225,7 @@ func (r *Resolver) Invoices(ctx context.Context, first *int, after *string, imsi
for i, inv := range invoices {
edges[i] = &InvoiceEdge{
Node: inv,
Cursor: base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%d", offset+i+1))),
Cursor: base64.StdEncoding.EncodeToString(fmt.Appendf(nil, "%d", offset+i+1)),
}
}
@@ -271,7 +271,7 @@ func (r *Resolver) Alerts(ctx context.Context, first *int, after *string, subscr
for i, alert := range alerts {
edges[i] = &AlertEdge{
Node: alert,
Cursor: base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%d", offset+i+1))),
Cursor: base64.StdEncoding.EncodeToString(fmt.Appendf(nil, "%d", offset+i+1)),
}
}
@@ -118,7 +118,7 @@ func TestResolverRoot_Methods(t *testing.T) {
// Helper functions for testing (these should match the implementations in resolvers.go)
func encodeCursor(offset int) string {
return base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("cursor:%d", offset)))
return base64.StdEncoding.EncodeToString(fmt.Appendf(nil, "cursor:%d", offset))
}
func decodeCursor(cursor string) (int, error) {
@@ -264,7 +264,8 @@ func (h *SubscriberHandler) TerminateSubscriber(c *gin.Context) {
}
// ErrorResponse represents an API error response
type ErrorResponse struct {
type SubscriberErrorResponse struct {
Error string `json:"error"`
Code string `json:"code"`
Details string `json:"details,omitempty"`
}
@@ -79,7 +79,7 @@ func (ts *TimeSeriesStorage) StoreUsageMetrics(ctx context.Context, metrics Usag
"subscriber_id": metrics.SubscriberID,
"imsi": metrics.IMSI,
},
map[string]interface{}{
map[string]any{
"data_up": metrics.DataUp,
"data_down": metrics.DataDown,
"voice_seconds": metrics.VoiceSeconds,
@@ -96,7 +96,7 @@ func (ts *TimeSeriesStorage) StoreSystemMetrics(ctx context.Context, metrics Sys
point := influxdb2.NewPoint(
"system",
map[string]string{},
map[string]interface{}{
map[string]any{
"active_sessions": metrics.ActiveSessions,
"cpu_usage": metrics.CPUUsage,
"memory_usage": metrics.MemoryUsage,
@@ -119,7 +119,7 @@ func (ts *TimeSeriesStorage) StoreChargingMetrics(ctx context.Context, metrics C
"currency": metrics.Currency,
"status": metrics.Status,
},
map[string]interface{}{
map[string]any{
"balance": metrics.Balance,
"amount": metrics.Amount,
},
@@ -136,7 +136,7 @@ func (ts *TimeSeriesStorage) StorePacketMetrics(ctx context.Context, subscriberI
map[string]string{
"subscriber_id": subscriberID,
},
map[string]interface{}{
map[string]any{
"packets_processed": packetsProcessed,
"packets_dropped": packetsDropped,
"bytes_processed": bytesProcessed,
@@ -295,7 +295,7 @@ func (ts *TimeSeriesStorage) GetChargingHistory(ctx context.Context, subscriberI
}
// GetTopDataUsers retrieves top data users for a time period
func (ts *TimeSeriesStorage) GetTopDataUsers(ctx context.Context, start, end time.Time, limit int) ([]map[string]interface{}, error) {
func (ts *TimeSeriesStorage) GetTopDataUsers(ctx context.Context, start, end time.Time, limit int) ([]map[string]any, error) {
query := fmt.Sprintf(`
from(bucket: "%s")
|> range(start: %s, stop: %s)
@@ -312,10 +312,10 @@ func (ts *TimeSeriesStorage) GetTopDataUsers(ctx context.Context, start, end tim
return nil, fmt.Errorf("failed to query top data users: %w", err)
}
var users []map[string]interface{}
var users []map[string]any
for result.Next() {
record := result.Record()
user := map[string]interface{}{
user := map[string]any{
"subscriber_id": record.ValueByKey("subscriber_id"),
"total_data": record.ValueByKey("total_data"),
"data_up": record.ValueByKey("data_up"),
+24 -24
View File
@@ -179,7 +179,7 @@ func (s *StripeGateway) ProcessPayment(ctx context.Context, req *PaymentRequest)
return nil, fmt.Errorf("failed to create payment intent: %w", err)
}
intent, ok := intentResp.(map[string]interface{})
intent, ok := intentResp.(map[string]any)
if !ok {
return nil, fmt.Errorf("invalid payment intent response")
}
@@ -188,7 +188,7 @@ func (s *StripeGateway) ProcessPayment(ctx context.Context, req *PaymentRequest)
var failureReason *string
if status == PaymentStatusFailed {
if lastPaymentError, ok := intent["last_payment_error"].(map[string]interface{}); ok {
if lastPaymentError, ok := intent["last_payment_error"].(map[string]any); ok {
if message, ok := lastPaymentError["message"].(string); ok {
failureReason = &message
}
@@ -197,8 +197,8 @@ func (s *StripeGateway) ProcessPayment(ctx context.Context, req *PaymentRequest)
var redirectURL *string
if status == PaymentStatusPending {
if nextAction, ok := intent["next_action"].(map[string]interface{}); ok {
if url, ok := nextAction["redirect_to_url"].(map[string]interface{}); ok {
if nextAction, ok := intent["next_action"].(map[string]any); ok {
if url, ok := nextAction["redirect_to_url"].(map[string]any); ok {
if redirect, ok := url["url"].(string); ok {
redirectURL = &redirect
}
@@ -220,7 +220,7 @@ func (s *StripeGateway) ProcessPayment(ctx context.Context, req *PaymentRequest)
// RefundPayment refunds a payment via Stripe
func (s *StripeGateway) RefundPayment(ctx context.Context, transactionID string, amount float64) (*RefundResponse, error) {
refundData := map[string]interface{}{
refundData := map[string]any{
"payment_intent": transactionID,
"amount": int64(amount * 100), // Stripe uses cents
}
@@ -230,7 +230,7 @@ func (s *StripeGateway) RefundPayment(ctx context.Context, transactionID string,
return nil, fmt.Errorf("failed to create refund: %w", err)
}
refund, ok := refundResp.(map[string]interface{})
refund, ok := refundResp.(map[string]any)
if !ok {
return nil, fmt.Errorf("invalid refund response")
}
@@ -262,7 +262,7 @@ func (s *StripeGateway) GetPaymentStatus(ctx context.Context, transactionID stri
return nil, fmt.Errorf("failed to get payment intent: %w", err)
}
intent, ok := intentResp.(map[string]interface{})
intent, ok := intentResp.(map[string]any)
if !ok {
return nil, fmt.Errorf("invalid payment intent response")
}
@@ -273,12 +273,12 @@ func (s *StripeGateway) GetPaymentStatus(ctx context.Context, transactionID stri
return nil, fmt.Errorf("failed to get refunds: %w", err)
}
refundsData, _ := refundsResp.(map[string]interface{})
refundsList, _ := refundsData["data"].([]interface{})
refundsData, _ := refundsResp.(map[string]any)
refundsList, _ := refundsData["data"].([]any)
refunds := make([]RefundInfo, len(refundsList))
for i, refundInterface := range refundsList {
refund, _ := refundInterface.(map[string]interface{})
refund, _ := refundInterface.(map[string]any)
createdAt, _ := time.Parse(time.RFC3339, refund["created"].(string))
refunds[i] = RefundInfo{
RefundID: refund["id"].(string),
@@ -291,7 +291,7 @@ func (s *StripeGateway) GetPaymentStatus(ctx context.Context, transactionID stri
createdAt, _ := time.Parse(time.RFC3339, intent["created"].(string))
var failureReason *string
if lastPaymentError, ok := intent["last_payment_error"].(map[string]interface{}); ok {
if lastPaymentError, ok := intent["last_payment_error"].(map[string]any); ok {
if message, ok := lastPaymentError["message"].(string); ok {
failureReason = &message
}
@@ -311,7 +311,7 @@ func (s *StripeGateway) GetPaymentStatus(ctx context.Context, transactionID stri
// CreatePaymentMethod creates a payment method in Stripe
func (s *StripeGateway) CreatePaymentMethod(ctx context.Context, req *CreatePaymentMethodRequest) (*PaymentMethod, error) {
pmData := map[string]interface{}{
pmData := map[string]any{
"type": s.mapPaymentMethodType(req.Type),
"card": map[string]string{
"token": req.Token,
@@ -324,13 +324,13 @@ func (s *StripeGateway) CreatePaymentMethod(ctx context.Context, req *CreatePaym
return nil, fmt.Errorf("failed to create payment method: %w", err)
}
pm, ok := pmResp.(map[string]interface{})
pm, ok := pmResp.(map[string]any)
if !ok {
return nil, fmt.Errorf("invalid payment method response")
}
// Attach payment method to customer
attachData := map[string]interface{}{
attachData := map[string]any{
"customer": req.CustomerID,
}
_, err = s.makeStripeRequest(ctx, "POST", "/v1/payment_methods/"+pm["id"].(string)+"/attach", attachData)
@@ -340,7 +340,7 @@ func (s *StripeGateway) CreatePaymentMethod(ctx context.Context, req *CreatePaym
// Set as default if requested
if req.IsDefault {
customerData := map[string]interface{}{
customerData := map[string]any{
"invoice_settings": map[string]string{
"default_payment_method": pm["id"].(string),
},
@@ -351,7 +351,7 @@ func (s *StripeGateway) CreatePaymentMethod(ctx context.Context, req *CreatePaym
}
}
card, _ := pm["card"].(map[string]interface{})
card, _ := pm["card"].(map[string]any)
createdAt, _ := time.Parse(time.RFC3339, pm["created"].(string))
return &PaymentMethod{
@@ -388,10 +388,10 @@ func (s *StripeGateway) ValidateWebhook(ctx context.Context, signature string, b
var timestamp, v1Signature string
for _, part := range parts {
part = strings.TrimSpace(part)
if strings.HasPrefix(part, "t=") {
timestamp = strings.TrimPrefix(part, "t=")
} else if strings.HasPrefix(part, "v1=") {
v1Signature = strings.TrimPrefix(part, "v1=")
if after, ok := strings.CutPrefix(part, "t="); ok {
timestamp = after
} else if after, ok := strings.CutPrefix(part, "v1="); ok {
v1Signature = after
}
}
@@ -406,7 +406,7 @@ func (s *StripeGateway) ValidateWebhook(ctx context.Context, signature string, b
}
// Helper methods
func (s *StripeGateway) makeStripeRequest(ctx context.Context, method, path string, data interface{}) (interface{}, error) {
func (s *StripeGateway) makeStripeRequest(ctx context.Context, method, path string, data any) (any, error) {
url := "https://api.stripe.com" + path
var body io.Reader
@@ -439,9 +439,9 @@ func (s *StripeGateway) makeStripeRequest(ctx context.Context, method, path stri
}
if resp.StatusCode >= 400 {
var errorResp map[string]interface{}
var errorResp map[string]any
if err := json.Unmarshal(respBody, &errorResp); err == nil {
if errorMsg, ok := errorResp["error"].(map[string]interface{}); ok {
if errorMsg, ok := errorResp["error"].(map[string]any); ok {
if message, ok := errorMsg["message"].(string); ok {
return nil, fmt.Errorf("stripe error: %s", message)
}
@@ -450,7 +450,7 @@ func (s *StripeGateway) makeStripeRequest(ctx context.Context, method, path stri
return nil, fmt.Errorf("stripe error: %s", string(respBody))
}
var result interface{}
var result any
if err := json.Unmarshal(respBody, &result); err != nil {
return nil, fmt.Errorf("failed to unmarshal response: %w", err)
}
@@ -42,7 +42,7 @@ func NewStripeGateway(secretKey, webhookSecret string) *StripeGateway {
func (g *StripeGateway) ProcessPayment(ctx context.Context, req *PaymentRequest) (*PaymentResponse, error) {
// Create payment intent
params := &stripe.PaymentIntentParams{
Amount: stripe.Int64(int64(req.Amount * 100)), // Convert to cents
Amount: new(int64(req.Amount * 100)), // Convert to cents
Currency: stripe.String(string(req.Currency)),
Metadata: map[string]string{
"subscriber_id": fmt.Sprintf("%d", req.SubscriberID),
@@ -132,7 +132,7 @@ func (g *StripeGateway) ProcessRefund(ctx context.Context, transactionID string,
}
if amount > 0 {
params.Amount = stripe.Int64(int64(amount * 100)) // Convert to cents
params.Amount = new(int64(amount * 100)) // Convert to cents
}
refund, err := refund.New(params)
@@ -185,10 +185,10 @@ func (g *StripeGateway) CreateInvoice(ctx context.Context, customerID string, it
for _, item := range items {
itemParams := &stripe.InvoiceItemParams{
Customer: stripe.String(customerID),
Amount: stripe.Int64(int64(item.Amount * 100)),
Amount: new(int64(item.Amount * 100)),
Currency: stripe.String(string(item.Currency)),
Description: stripe.String(item.Description),
Quantity: stripe.Int64(int64(item.Quantity)),
Quantity: new(int64(item.Quantity)),
}
_, err := invoiceitem.New(itemParams)
@@ -200,7 +200,7 @@ func (g *StripeGateway) CreateInvoice(ctx context.Context, customerID string, it
// Create the invoice
params := &stripe.InvoiceParams{
Customer: stripe.String(customerID),
AutoAdvance: stripe.Bool(true),
AutoAdvance: new(true),
}
inv, err := invoice.New(params)
+11 -11
View File
@@ -15,12 +15,12 @@ import (
// WebhookEvent represents a payment webhook event
type WebhookEvent struct {
ID string `json:"id"`
Type string `json:"type"`
Object string `json:"object"`
Created int64 `json:"created"`
Livemode bool `json:"livemode"`
Data map[string]interface{} `json:"data"`
ID string `json:"id"`
Type string `json:"type"`
Object string `json:"object"`
Created int64 `json:"created"`
Livemode bool `json:"livemode"`
Data map[string]any `json:"data"`
}
// WebhookHandler handles payment webhooks
@@ -97,7 +97,7 @@ func (wh *WebhookHandler) HandleStripeWebhook(c *gin.Context) {
// handlePaymentSucceeded handles successful payment events
func (wh *WebhookHandler) handlePaymentSucceeded(ctx context.Context, event WebhookEvent) error {
paymentIntent, ok := event.Data["object"].(map[string]interface{})
paymentIntent, ok := event.Data["object"].(map[string]any)
if !ok {
return fmt.Errorf("invalid payment intent object")
}
@@ -145,7 +145,7 @@ func (wh *WebhookHandler) handlePaymentSucceeded(ctx context.Context, event Webh
// handlePaymentFailed handles failed payment events
func (wh *WebhookHandler) handlePaymentFailed(ctx context.Context, event WebhookEvent) error {
paymentIntent, ok := event.Data["object"].(map[string]interface{})
paymentIntent, ok := event.Data["object"].(map[string]any)
if !ok {
return fmt.Errorf("invalid payment intent object")
}
@@ -166,7 +166,7 @@ func (wh *WebhookHandler) handlePaymentFailed(ctx context.Context, event Webhook
transaction.UpdatedAt = time.Now()
// Add failure reason if available
if lastPaymentError, ok := paymentIntent["last_payment_error"].(map[string]interface{}); ok {
if lastPaymentError, ok := paymentIntent["last_payment_error"].(map[string]any); ok {
if message, ok := lastPaymentError["message"].(string); ok {
transaction.Description += " - Failed: " + message
}
@@ -199,7 +199,7 @@ func (wh *WebhookHandler) handlePaymentFailed(ctx context.Context, event Webhook
// handlePaymentCanceled handles canceled payment events
func (wh *WebhookHandler) handlePaymentCanceled(ctx context.Context, event WebhookEvent) error {
paymentIntent, ok := event.Data["object"].(map[string]interface{})
paymentIntent, ok := event.Data["object"].(map[string]any)
if !ok {
return fmt.Errorf("invalid payment intent object")
}
@@ -230,7 +230,7 @@ func (wh *WebhookHandler) handlePaymentCanceled(ctx context.Context, event Webho
// handleDisputeCreated handles dispute events
func (wh *WebhookHandler) handleDisputeCreated(ctx context.Context, event WebhookEvent) error {
dispute, ok := event.Data["object"].(map[string]interface{})
dispute, ok := event.Data["object"].(map[string]any)
if !ok {
return fmt.Errorf("invalid dispute object")
}