Files
edr-platform/packages/api-common/src/services/exchange/exchange.options.ts

75 lines
2.7 KiB
TypeScript

/** Injection token carrying the resolved {@link ExchangeOptions}. */
export const EXCHANGE_OPTIONS = Symbol("EXCHANGE_OPTIONS");
/** Configuration for the {@link ExchangeService} and its CBE provider. */
export interface ExchangeOptions {
/**
* CBE daily-exchange-rates JSON endpoint. Returns an array of daily records;
* `_limit=1&_sort=Date%3ADESC` narrows it to the most recent day.
* @default 'https://combanketh.et/cbeapi/daily-exchange-rates/?_limit=1&_sort=Date%3ADESC'
*/
scrapeUrl?: string;
/**
* Last-resort USD→ETB rate, used only when the fetch fails, no cached rate
* exists, and {@link loadFallbackRate} supplies nothing. The ETB→USD
* direction is derived as its inverse.
* @default 162
*/
fallbackRate?: number;
/**
* Reads the persisted fallback rate — the last known good CBE rate, or one
* set by an operator. Consulted only when the live fetch fails and no cached
* rate is available; a `null` result falls through to {@link fallbackRate}.
*
* Optional: omit it and the provider uses the static `fallbackRate` alone.
*/
loadFallbackRate?: () => Promise<number | null>;
/**
* Persists a freshly fetched live rate as the new fallback, so the stored
* value is never more than one successful fetch stale. Called after every
* successful fetch that produced a changed rate.
*
* Failures here are logged and swallowed — persisting the fallback must
* never break the pricing call that triggered it.
*/
saveFallbackRate?: (rate: number) => Promise<void>;
/**
* How long a successfully fetched rate is cached, in milliseconds.
* @default 3_600_000 (1 hour)
*/
cacheTtlMs?: number;
/**
* Timeout for the rate HTTP request, in milliseconds.
* @default 8_000
*/
requestTimeoutMs?: number;
}
/** The scalar options, all resolved — the callbacks stay genuinely optional. */
export type ResolvedExchangeOptions = Required<
Omit<ExchangeOptions, "loadFallbackRate" | "saveFallbackRate">
> &
Pick<ExchangeOptions, "loadFallbackRate" | "saveFallbackRate">;
/** Defaults applied to any unset scalar {@link ExchangeOptions} field. */
export const EXCHANGE_DEFAULTS: ResolvedExchangeOptions = {
scrapeUrl:
"https://combanketh.et/cbeapi/daily-exchange-rates/?_limit=1&_sort=Date%3ADESC",
fallbackRate: 162,
cacheTtlMs: 3_600_000,
requestTimeoutMs: 8_000,
};
/** Factory contract for {@link ExchangeModule.forRootAsync}. */
export interface ExchangeAsyncOptions {
/** Providers to inject into {@link useFactory} (e.g. `[ConfigService]`). */
inject?: unknown[];
/** Returns the options, possibly async. */
useFactory: (...args: never[]) => ExchangeOptions | Promise<ExchangeOptions>;
}