Use explicit currency for locked prices
Build and deploy Docker image / build (push) Successful in 1m20s

This commit is contained in:
Ruslan Bakiev
2026-08-24 21:10:09 +07:00
parent ca0e70d723
commit fe883afde2
4 changed files with 11 additions and 41 deletions
@@ -0,0 +1,2 @@
-- DropTable
DROP TABLE "exchange_pricing_currency_policies";
-9
View File
@@ -99,12 +99,3 @@ model CurrencyRate {
@@index([quoteCurrency]) @@index([quoteCurrency])
@@map("exchange_currency_rates") @@map("exchange_currency_rates")
} }
model PricingCurrencyPolicy {
countryCode String @id @map("country_code") @db.VarChar(2)
currencyCode String @map("currency_code") @db.VarChar(3)
updatedAt DateTime @updatedAt @map("updated_at")
@@index([currencyCode])
@@map("exchange_pricing_currency_policies")
}
+8 -31
View File
@@ -10,6 +10,7 @@ import { prisma } from './db.js'
type LockCurrencyPriceInput = { type LockCurrencyPriceInput = {
sourceAmount: number sourceAmount: number
sourceCurrency: string sourceCurrency: string
clientCurrency: string
pricingCountryCode: string pricingCountryCode: string
rateDate?: string | null rateDate?: string | null
} }
@@ -18,6 +19,7 @@ export const m2mTypeDefs = `#graphql
input LockCurrencyPriceInput { input LockCurrencyPriceInput {
sourceAmount: Float! sourceAmount: Float!
sourceCurrency: String! sourceCurrency: String!
clientCurrency: String!
pricingCountryCode: String! pricingCountryCode: String!
rateDate: String rateDate: String
} }
@@ -37,13 +39,8 @@ export const m2mTypeDefs = `#graphql
pricingCountryCode: String! pricingCountryCode: String!
} }
type PricingCurrencyPolicy {
countryCode: String!
currencyCode: String!
}
type Query { type Query {
pricingCurrencyForCountry(countryCode: String!): PricingCurrencyPolicy health: String!
} }
type Mutation { type Mutation {
@@ -70,18 +67,6 @@ function historicalDate(value: string): Date {
return result return result
} }
async function pricingCurrencyForCountryValue(rawCountryCode: unknown) {
const normalizedCountryCode = countryCode(rawCountryCode)
const policy = await prisma.pricingCurrencyPolicy.findUnique({
where: { countryCode: normalizedCountryCode },
})
if (policy === null) return null
return {
countryCode: policy.countryCode,
currencyCode: policy.currencyCode,
}
}
async function lockCurrencyPrice( async function lockCurrencyPrice(
_: unknown, _: unknown,
args: { input: LockCurrencyPriceInput }, args: { input: LockCurrencyPriceInput },
@@ -92,13 +77,8 @@ async function lockCurrencyPrice(
throw new GraphQLError('sourceAmount must be a non-negative finite number') throw new GraphQLError('sourceAmount must be a non-negative finite number')
} }
const sourceCurrency = currencyCode(args.input.sourceCurrency) const sourceCurrency = currencyCode(args.input.sourceCurrency)
const policy = await pricingCurrencyForCountryValue(args.input.pricingCountryCode) const clientCurrency = currencyCode(args.input.clientCurrency)
if (policy === null) { const pricingCountryCode = countryCode(args.input.pricingCountryCode)
throw new GraphQLError(
`Pricing currency policy is missing for country ${countryCode(args.input.pricingCountryCode)}`,
)
}
const clientCurrency = currencyCode(policy.currencyCode)
if (sourceCurrency === clientCurrency) { if (sourceCurrency === clientCurrency) {
const effectiveDate = args.input.rateDate const effectiveDate = args.input.rateDate
? historicalDate(args.input.rateDate) ? historicalDate(args.input.rateDate)
@@ -115,7 +95,7 @@ async function lockCurrencyPrice(
rateLockedAt: lockedAt.toISOString(), rateLockedAt: lockedAt.toISOString(),
provider: 'identity', provider: 'identity',
attributionUrl: null, attributionUrl: null,
pricingCountryCode: policy.countryCode, pricingCountryCode,
} }
} }
const snapshot = args.input.rateDate const snapshot = args.input.rateDate
@@ -134,16 +114,13 @@ async function lockCurrencyPrice(
rateLockedAt: lockedAt.toISOString(), rateLockedAt: lockedAt.toISOString(),
provider: snapshot.provider, provider: snapshot.provider,
attributionUrl: snapshot.attributionUrl, attributionUrl: snapshot.attributionUrl,
pricingCountryCode: policy.countryCode, pricingCountryCode,
} }
} }
export const m2mResolvers = { export const m2mResolvers = {
Query: { Query: {
pricingCurrencyForCountry: ( health: () => 'ok',
_: unknown,
args: { countryCode: string },
) => pricingCurrencyForCountryValue(args.countryCode),
}, },
Mutation: { Mutation: {
lockCurrencyPrice, lockCurrencyPrice,