mirror of
https://github.com/marcusDenslow/terminalShop.git
synced 2026-10-25 10:02:21 +01:00
db telemetry
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package bring
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -9,6 +10,8 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
)
|
||||
|
||||
const baseURL = "https://api.bring.com/address"
|
||||
@@ -27,6 +30,7 @@ func NewClient(apiUID, apiKey string) *Client {
|
||||
apiKey: apiKey,
|
||||
httpClient: &http.Client{
|
||||
Timeout: 10 * time.Second,
|
||||
Transport: otelhttp.NewTransport(http.DefaultTransport),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -79,7 +83,7 @@ func parseStreet(street string) (name string, number string) {
|
||||
return strings.TrimSpace(street), ""
|
||||
}
|
||||
|
||||
func (c *Client) ValidateAddress(addr Address) (*Address, error) {
|
||||
func (c *Client) ValidateAddress(ctx context.Context, addr Address) (*Address, error) {
|
||||
streetName, streetNumber := parseStreet(addr.Street1)
|
||||
|
||||
params := url.Values{}
|
||||
@@ -93,7 +97,7 @@ func (c *Client) ValidateAddress(addr Address) (*Address, error) {
|
||||
|
||||
reqURL := fmt.Sprintf("%s/api/no/validation?%s", baseURL, params.Encode())
|
||||
|
||||
req, err := http.NewRequest("GET", reqURL, nil)
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", reqURL, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create request: %w", err)
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ import (
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
|
||||
"gorm.io/plugin/opentelemetry/tracing"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -42,6 +44,14 @@ func Connect(dsn string) (*gorm.DB, error) {
|
||||
return
|
||||
}
|
||||
|
||||
if pluginErr := db.Use(tracing.NewPlugin(
|
||||
tracing.WithoutMetrics(),
|
||||
tracing.WithoutQueryVariables(),
|
||||
)); pluginErr != nil {
|
||||
err = fmt.Errorf("failed to register otel plugin: %w", pluginErr)
|
||||
return
|
||||
}
|
||||
|
||||
// Configure connection pool for PostgreSQL.
|
||||
if isPostgres {
|
||||
sqlDB, poolErr := db.DB()
|
||||
|
||||
@@ -2,11 +2,14 @@ package shippo
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
)
|
||||
|
||||
const baseURL = "https://api.goshippo.com"
|
||||
@@ -22,7 +25,8 @@ func NewClient(apiKey string) *Client {
|
||||
return &Client{
|
||||
apiKey: apiKey,
|
||||
httpClient: &http.Client{
|
||||
Timeout: 10 * time.Second,
|
||||
Timeout: 10 * time.Second,
|
||||
Transport: otelhttp.NewTransport(http.DefaultTransport),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -75,7 +79,7 @@ type addressResponse struct {
|
||||
|
||||
// ValidateAddress sends an address to Shippo for validation.
|
||||
// Returns the normalized/corrected address if valid, or an error if invalid.
|
||||
func (c *Client) ValidateAddress(addr Address) (*Address, error) {
|
||||
func (c *Client) ValidateAddress(ctx context.Context, addr Address) (*Address, error) {
|
||||
reqBody := addressRequest{
|
||||
Name: addr.Name,
|
||||
Street1: addr.Street1,
|
||||
@@ -93,7 +97,7 @@ func (c *Client) ValidateAddress(addr Address) (*Address, error) {
|
||||
return nil, fmt.Errorf("failed to marshal address: %w", err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", baseURL+"/v1/addresses", bytes.NewReader(body))
|
||||
req, err := http.NewRequestWithContext(ctx, "POST", baseURL+"/v1/addresses", bytes.NewReader(body))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create request: %w", err)
|
||||
}
|
||||
|
||||
22
pkg/stripeclient/init.go
Normal file
22
pkg/stripeclient/init.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package stripeclient
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/stripe/stripe-go/v78"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
)
|
||||
|
||||
// InitOTel wires the Stripe SDK to use an HTTP client whose transport emits
|
||||
// OpenTelemetry client spans. Call once at startup, after tracing is initialized.
|
||||
func InitOTel() {
|
||||
httpClient := &http.Client{
|
||||
Timeout: 80 * time.Second,
|
||||
Transport: otelhttp.NewTransport(http.DefaultTransport),
|
||||
}
|
||||
backends := stripe.NewBackends(httpClient)
|
||||
stripe.SetBackend(stripe.APIBackend, backends.API)
|
||||
stripe.SetBackend(stripe.UploadsBackend, backends.Uploads)
|
||||
stripe.SetBackend(stripe.ConnectBackend, backends.Connect)
|
||||
}
|
||||
@@ -108,7 +108,7 @@ type Model struct {
|
||||
pendingWidth int // buffered width from latest resize
|
||||
pendingHeight int // buffered height from latest resize
|
||||
|
||||
Loading bool // true when fetching data from API
|
||||
Loading bool // true when fetching data from API
|
||||
error *VisibleError
|
||||
APIClient *api.Client
|
||||
|
||||
@@ -587,6 +587,38 @@ func (m Model) deleteCardCmd(id uint) tea.Cmd {
|
||||
}
|
||||
}
|
||||
|
||||
// resolveCartAddress sets the shipping address on the cart, creating it first
|
||||
// if the address had no ID yet (i.e the user typed it in fresh rather than picking
|
||||
// from saved addresses)
|
||||
func (m Model) resolveCartAddress() error {
|
||||
if m.ShippingInfo == nil {
|
||||
return nil
|
||||
}
|
||||
if m.ShippingInfo.ID != 0 {
|
||||
if err := m.APIClient.SetCartAddress(m.ShippingInfo.ID); err != nil {
|
||||
return fmt.Errorf("failed to set address: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
saved, err := m.APIClient.CreateAddress(api.CreateAddressRequest{
|
||||
Name: m.ShippingInfo.Name,
|
||||
Street: m.ShippingInfo.Street,
|
||||
Street2: m.ShippingInfo.Street2,
|
||||
City: m.ShippingInfo.City,
|
||||
State: m.ShippingInfo.State,
|
||||
Zip: m.ShippingInfo.Zip,
|
||||
Country: m.ShippingInfo.Country,
|
||||
Phone: m.ShippingInfo.Phone,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to save address: %w", err)
|
||||
}
|
||||
if err := m.APIClient.SetCartAddress(saved.ID); err != nil {
|
||||
return fmt.Errorf("failed to set address: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkoutWithSavedCard sets address and saved card on the cart, then converts.
|
||||
// Used when the user selects an existing card from the list (no tokenization needed).
|
||||
func (m Model) checkoutWithSavedCard() tea.Cmd {
|
||||
@@ -595,28 +627,8 @@ func (m Model) checkoutWithSavedCard() tea.Cmd {
|
||||
return CheckoutResultMsg{Err: fmt.Errorf("API client or card not available")}
|
||||
}
|
||||
|
||||
// 1. Set the shipping address on the cart
|
||||
if m.ShippingInfo != nil && m.ShippingInfo.ID != 0 {
|
||||
if err := m.APIClient.SetCartAddress(m.ShippingInfo.ID); err != nil {
|
||||
return CheckoutResultMsg{Err: fmt.Errorf("failed to set address: %w", err)}
|
||||
}
|
||||
} else if m.ShippingInfo != nil {
|
||||
saved, err := m.APIClient.CreateAddress(api.CreateAddressRequest{
|
||||
Name: m.ShippingInfo.Name,
|
||||
Street: m.ShippingInfo.Street,
|
||||
Street2: m.ShippingInfo.Street2,
|
||||
City: m.ShippingInfo.City,
|
||||
State: m.ShippingInfo.State,
|
||||
Zip: m.ShippingInfo.Zip,
|
||||
Country: m.ShippingInfo.Country,
|
||||
Phone: m.ShippingInfo.Phone,
|
||||
})
|
||||
if err != nil {
|
||||
return CheckoutResultMsg{Err: fmt.Errorf("failed to save address: %w", err)}
|
||||
}
|
||||
if err := m.APIClient.SetCartAddress(saved.ID); err != nil {
|
||||
return CheckoutResultMsg{Err: fmt.Errorf("failed to set address: %w", err)}
|
||||
}
|
||||
if err := m.resolveCartAddress(); err != nil {
|
||||
return CheckoutResultMsg{Err: err}
|
||||
}
|
||||
|
||||
// 2. Set the saved card on the cart
|
||||
@@ -682,29 +694,8 @@ func (m Model) saveCardAndConvert(form PaymentFormCompleteMsg) tea.Cmd {
|
||||
return CheckoutResultMsg{Err: fmt.Errorf("failed to save card: %w", err)}
|
||||
}
|
||||
|
||||
// 2. Set the shipping address on the cart
|
||||
if m.ShippingInfo != nil && m.ShippingInfo.ID != 0 {
|
||||
if err := m.APIClient.SetCartAddress(m.ShippingInfo.ID); err != nil {
|
||||
return CheckoutResultMsg{Err: fmt.Errorf("failed to set address: %w", err)}
|
||||
}
|
||||
} else if m.ShippingInfo != nil {
|
||||
// Address was entered fresh (not from saved list), save it first
|
||||
saved, err := m.APIClient.CreateAddress(api.CreateAddressRequest{
|
||||
Name: m.ShippingInfo.Name,
|
||||
Street: m.ShippingInfo.Street,
|
||||
Street2: m.ShippingInfo.Street2,
|
||||
City: m.ShippingInfo.City,
|
||||
State: m.ShippingInfo.State,
|
||||
Zip: m.ShippingInfo.Zip,
|
||||
Country: m.ShippingInfo.Country,
|
||||
Phone: m.ShippingInfo.Phone,
|
||||
})
|
||||
if err != nil {
|
||||
return CheckoutResultMsg{Err: fmt.Errorf("failed to save address: %w", err)}
|
||||
}
|
||||
if err := m.APIClient.SetCartAddress(saved.ID); err != nil {
|
||||
return CheckoutResultMsg{Err: fmt.Errorf("failed to set address: %w", err)}
|
||||
}
|
||||
if err := m.resolveCartAddress(); err != nil {
|
||||
return CheckoutResultMsg{Err: err}
|
||||
}
|
||||
|
||||
// 3. Set the card on the cart
|
||||
|
||||
Reference in New Issue
Block a user