neq quotation definition + priced_at field

This commit is contained in:
Stephan D
2026-02-13 15:35:17 +01:00
parent da1636014b
commit 52c4c046c9
85 changed files with 1180 additions and 162 deletions

View File

@@ -130,6 +130,10 @@ func (qc *quoteComputation) buildModelQuote(firm bool, expiryMillis int64, req *
if qc.baseRounded == nil || qc.quoteRounded == nil || qc.priceRounded == nil {
return nil, merrors.Internal("oracle: computation not executed")
}
pricedAtUnixMs := qc.rate.AsOfUnixMs
if pricedAtUnixMs <= 0 {
pricedAtUnixMs = time.Now().UnixMilli()
}
quote := &model.Quote{
QuoteRef: uuid.NewString(),
@@ -147,6 +151,7 @@ func (qc *quoteComputation) buildModelQuote(firm bool, expiryMillis int64, req *
Amount: formatRat(qc.quoteRounded, qc.quoteScale),
},
AmountType: qc.amountType,
PricedAtUnixMs: pricedAtUnixMs,
RateRef: qc.rate.RateRef,
Provider: qc.provider,
PreferredProvider: req.GetPreferredProvider(),

View File

@@ -111,6 +111,7 @@ func (currencyStoreStub) List(ctx context.Context, codes ...string) ([]*model.Cu
func (currencyStoreStub) Upsert(ctx context.Context, currency *model.Currency) error { return nil }
func TestServiceGetQuoteFirm(t *testing.T) {
pricedAt := time.Date(2024, 1, 2, 3, 4, 5, 0, time.UTC)
repo := &repositoryStub{}
repo.pairs = &pairStoreStub{
getFn: func(ctx context.Context, pair model.CurrencyPair) (*model.Pair, error) {
@@ -129,7 +130,7 @@ func TestServiceGetQuoteFirm(t *testing.T) {
Ask: "1.10",
Bid: "1.08",
RateRef: "rate#1",
AsOfUnixMs: time.Now().UnixMilli(),
AsOfUnixMs: pricedAt.UnixMilli(),
}, nil
},
}
@@ -169,9 +170,15 @@ func TestServiceGetQuoteFirm(t *testing.T) {
if resp.GetQuote().GetQuoteAmount().GetAmount() != "110.00" {
t.Fatalf("unexpected quote amount: %s", resp.GetQuote().GetQuoteAmount().GetAmount())
}
if got := resp.GetQuote().GetPricedAt(); got == nil || !got.AsTime().Equal(pricedAt) {
t.Fatalf("expected priced_at %s, got %v", pricedAt, got)
}
if savedQuote.QuoteRef == "" {
t.Fatalf("expected quote persisted")
}
if savedQuote.PricedAtUnixMs != pricedAt.UnixMilli() {
t.Fatalf("expected stored pricedAtUnixMs %d, got %d", pricedAt.UnixMilli(), savedQuote.PricedAtUnixMs)
}
}
func TestServiceGetQuoteRateNotFound(t *testing.T) {

View File

@@ -2,12 +2,14 @@ package oracle
import (
"strings"
"time"
"github.com/tech/sendico/fx/storage/model"
paymenttypes "github.com/tech/sendico/pkg/payments/types"
fxv1 "github.com/tech/sendico/pkg/proto/common/fx/v1"
moneyv1 "github.com/tech/sendico/pkg/proto/common/money/v1"
oraclev1 "github.com/tech/sendico/pkg/proto/oracle/v1"
"google.golang.org/protobuf/types/known/timestamppb"
)
func buildResponseMeta(meta *oraclev1.RequestMeta) *oraclev1.ResponseMeta {
@@ -36,6 +38,7 @@ func quoteModelToProto(q *model.Quote) *oraclev1.Quote {
BaseAmount: moneyModelToProto(&q.BaseAmount),
QuoteAmount: moneyModelToProto(&q.QuoteAmount),
ExpiresAtUnixMs: q.ExpiresAtUnixMs,
PricedAt: timestampFromUnixMillis(q.PricedAtUnixMs, q.CreatedAt),
Provider: q.Provider,
RateRef: q.RateRef,
Firm: q.Firm,
@@ -117,3 +120,13 @@ func decimalStringToProto(value string) *moneyv1.Decimal {
}
return &moneyv1.Decimal{Value: value}
}
func timestampFromUnixMillis(ms int64, fallback time.Time) *timestamppb.Timestamp {
if ms > 0 {
return timestamppb.New(time.UnixMilli(ms).UTC())
}
if !fallback.IsZero() {
return timestamppb.New(fallback.UTC())
}
return nil
}