Initial Commit
This commit is contained in:
128
openspec/changes/enterprise-currency-providers/proposal.md
Normal file
128
openspec/changes/enterprise-currency-providers/proposal.md
Normal file
@@ -0,0 +1,128 @@
|
||||
# OpenSpec Change: enterprise-currency-providers
|
||||
|
||||
- **Change ID**: enterprise-currency-providers
|
||||
- **Package**: `@suaveplan/currency-providers`
|
||||
- **Category**: finance
|
||||
- **Target path**: `finance/currency/currency-providers`
|
||||
- **Status**: PROPOSED
|
||||
- **Date**: 2026-04-24
|
||||
- **Reference spec**: `/mnt/s/web/suaveplan/enterprise/currency-providers.md`
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
Deliver `@suaveplan/currency-providers` on the genesis branch from scratch at enterprise quality. The package implements concrete `CurrencyProvider` implementations (from `@suaveplan/currency`) for eight real exchange-rate APIs: three fiat providers (ECB XML feed, Open Exchange Rates, Fixer) and five crypto providers (CoinGecko, CoinMarketCap, Binance, Kraken, CryptoCompare), plus a `VirtualCurrencyProvider`. All HTTP calls go through a shared `fetch` wrapper with timeout, retry via `@suaveplan/retry`, rate-limit header parsing, and in-flight request coalescing. Typed error hierarchy (`AuthError`, `RateLimitError`, `NetworkError`, `ParseError`). Optional `RateLimitedProvider` decorator.
|
||||
|
||||
---
|
||||
|
||||
## Current-state audit (genesis)
|
||||
|
||||
Does not exist on genesis — fresh build.
|
||||
|
||||
---
|
||||
|
||||
## Available workspace deps on genesis
|
||||
|
||||
| Package | Role |
|
||||
|---|---|
|
||||
| `@suaveplan/error` (`workspace:^`) | Typed `CURRENCY_PROVIDER.*` error codes |
|
||||
| `@suaveplan/types` (`workspace:^`) | `LoggerLike` |
|
||||
| `@suaveplan/currency` (`workspace:^`) | `CurrencyProvider` interface |
|
||||
| `@suaveplan/retry` (`workspace:^`) | HTTP retry + backoff |
|
||||
| `@suaveplan/logger` (`workspace:^`) | Structured logs |
|
||||
| `zod` (`catalog:forms`) | Response parsing schemas |
|
||||
| `@opentelemetry/api` (`catalog:observability`) | Spans + counters + histograms |
|
||||
| `tslib` (`catalog:build`) | Runtime helpers |
|
||||
|
||||
---
|
||||
|
||||
## Public API surface
|
||||
|
||||
```ts
|
||||
// Fiat providers
|
||||
class EcbProvider implements CurrencyProvider { ... }
|
||||
class FixerProvider implements CurrencyProvider { constructor(config: ApiKeyConfig) }
|
||||
class OpenExchangeRatesProvider implements CurrencyProvider { constructor(config: ApiKeyConfig) }
|
||||
|
||||
// Crypto providers
|
||||
class BinanceProvider implements CurrencyProvider { ... }
|
||||
class CoinGeckoProvider implements CurrencyProvider { ... }
|
||||
class CoinMarketCapProvider implements CurrencyProvider { constructor(config: ApiKeyConfig) }
|
||||
class CryptoCompareProvider implements CurrencyProvider { ... }
|
||||
class KrakenProvider implements CurrencyProvider { ... }
|
||||
|
||||
// Virtual
|
||||
class VirtualCurrencyProvider implements CurrencyProvider { ... }
|
||||
|
||||
// Wrapper
|
||||
class RateLimitedProvider implements CurrencyProvider {
|
||||
constructor(provider: CurrencyProvider, options: RateLimitOptions)
|
||||
}
|
||||
|
||||
// Errors
|
||||
class ProviderError extends SuaveplanError { ... }
|
||||
class AuthError extends ProviderError { ... }
|
||||
class RateLimitError extends ProviderError { retryAfterMs?: number }
|
||||
class NetworkError extends ProviderError { ... }
|
||||
class ParseError extends ProviderError { ... }
|
||||
|
||||
// HTTP utilities
|
||||
function createFetchWrapper(options: FetchWrapperOptions): FetchWrapper
|
||||
function coalesce<T>(key: string, fn: () => Promise<T>): Promise<T>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File layout
|
||||
|
||||
```text
|
||||
finance/currency/currency-providers/
|
||||
package.json
|
||||
tsconfig.json
|
||||
vitest.config.ts
|
||||
src/
|
||||
index.ts
|
||||
error-codes.ts
|
||||
types/
|
||||
provider.types.ts
|
||||
provider.types.md
|
||||
http/
|
||||
fetch-wrapper/
|
||||
fetch-wrapper.ts
|
||||
fetch-wrapper.md
|
||||
fetch-wrapper.test.ts
|
||||
index.ts
|
||||
coalesce/
|
||||
coalesce.ts
|
||||
coalesce.md
|
||||
coalesce.test.ts
|
||||
index.ts
|
||||
fiat/
|
||||
ecb-provider/
|
||||
ecb-provider.ts / .md / .test.ts / index.ts
|
||||
fixer-provider/
|
||||
fixer-provider.ts / .md / .test.ts / index.ts
|
||||
open-exchange-rates-provider/
|
||||
open-exchange-rates-provider.ts / .md / .test.ts / index.ts
|
||||
crypto/
|
||||
binance-provider/ ...
|
||||
coingecko-provider/ ...
|
||||
coinmarketcap-provider/ ...
|
||||
cryptocompare-provider/ ...
|
||||
kraken-provider/ ...
|
||||
virtual/
|
||||
virtual-currency-provider/ ...
|
||||
wrappers/
|
||||
rate-limited-provider/ ...
|
||||
tests/
|
||||
integration.test.ts
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Impact
|
||||
|
||||
Requires `@suaveplan/currency` to be published first (implements its `CurrencyProvider` interface). Downstream: `@suaveplan/currency` consumers via the fallback chain.
|
||||
|
||||
**Prerequisites on Verdaccio**: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/currency`, `@suaveplan/retry`, `@suaveplan/logger`.
|
||||
Reference in New Issue
Block a user