+ quotation provider

This commit is contained in:
Stephan D
2025-12-11 01:13:13 +01:00
parent bdf766075e
commit a4481fb63d
102 changed files with 2242 additions and 246 deletions

View File

@@ -1,8 +1,33 @@
package srequest
type Money struct {
Amount string `json:"amount"`
Currency string `json:"currency"`
import (
"github.com/shopspring/decimal"
"github.com/tech/sendico/pkg/merrors"
"github.com/tech/sendico/pkg/model"
)
func ValidateMoney(m *model.Money) error {
if m.Amount == "" {
return merrors.InvalidArgument("amount is required", "intent.amount")
}
if m.Currency == "" {
return merrors.InvalidArgument("currency is required", "intent.currency")
}
if _, err := decimal.NewFromString(m.Amount); err != nil {
return merrors.InvalidArgument("invalid amount decimal", "intent.amount")
}
if len(m.Currency) != 3 {
return merrors.InvalidArgument("currency must be 3 letters", "intent.currency")
}
for _, c := range m.Currency {
if c < 'A' || c > 'Z' {
return merrors.InvalidArgument("currency must be uppercase A-Z", "intent.currency")
}
}
return nil
}
type CurrencyPair struct {
@@ -10,6 +35,35 @@ type CurrencyPair struct {
Quote string `json:"quote"`
}
func (p *CurrencyPair) Validate() error {
if p.Base == "" {
return merrors.InvalidArgument("base currency is required", "intent.fx.pair.base")
}
if p.Quote == "" {
return merrors.InvalidArgument("quote currency is required", "intent.fx.pair.quote")
}
if len(p.Base) != 3 {
return merrors.InvalidArgument("base currency must be 3 letters", "intent.fx.pair.base")
}
if len(p.Quote) != 3 {
return merrors.InvalidArgument("quote currency must be 3 letters", "intent.fx.pair.quote")
}
for _, c := range p.Base {
if c < 'A' || c > 'Z' {
return merrors.InvalidArgument("base currency must be uppercase A-Z", "intent.fx.pair.base")
}
}
for _, c := range p.Quote {
if c < 'A' || c > 'Z' {
return merrors.InvalidArgument("quote currency must be uppercase A-Z", "intent.fx.pair.quote")
}
}
return nil
}
type FXIntent struct {
Pair *CurrencyPair `json:"pair,omitempty"`
Side FXSide `json:"side,omitempty"`
@@ -18,3 +72,29 @@ type FXIntent struct {
PreferredProvider string `json:"preferred_provider,omitempty"`
MaxAgeMs int32 `json:"max_age_ms,omitempty"`
}
func (fx *FXIntent) Validate() error {
if fx.Pair != nil {
if err := fx.Pair.Validate(); err != nil {
return err
}
}
var zeroSide FXSide
if fx.Side == zeroSide {
return merrors.InvalidArgument("fx side is required", "intent.fx.side")
}
if fx.TTLms < 0 {
return merrors.InvalidArgument("fx ttl_ms cannot be negative", "intent.fx.ttl_ms")
}
if fx.TTLms == 0 && fx.Firm {
return merrors.InvalidArgument("firm quote requires positive ttl_ms", "intent.fx.ttl_ms")
}
if fx.MaxAgeMs < 0 {
return merrors.InvalidArgument("fx max_age_ms cannot be negative", "intent.fx.max_age_ms")
}
return nil
}