← スキル一覧に戻る

multi-currency
by avifenesh
⭐ 0🍴 0📅 2026年1月25日
SKILL.md
name: multi-currency description: Exchange rate management, currency conversion, and Frankfurter API integration. Use when working with USD/EUR/ILS conversions, exchange rates, or multi-currency dashboard displays.
Multi-Currency Domain Knowledge
Supported Currencies
enum Currency {
USD // US Dollar
EUR // Euro
ILS // Israeli Shekel
}
Exchange Rate Storage
model ExchangeRate {
id String @id @default(cuid())
baseCurrency Currency
targetCurrency Currency
rate Decimal @db.Decimal(12, 6) // 6 decimal precision
date DateTime
fetchedAt DateTime @default(now())
@@unique([baseCurrency, targetCurrency, date])
}
Frankfurter API Integration
Location: src/lib/currency.ts
Base URL: https://api.frankfurter.dev/v1
fetchExchangeRates
export async function fetchExchangeRates(baseCurrency: Currency): Promise<FrankfurterResponse>
Features:
- Request deduplication via
inFlightRequestsMap - Concurrent requests for same base currency return same Promise
- Automatic cleanup after request completes
getExchangeRate
export async function getExchangeRate(from: Currency, to: Currency, date?: Date): Promise<number>
Strategy:
- Same currency returns 1 (no conversion needed)
- Check cache (ExchangeRate table) for today's rate
- Fetch from API if not cached
- Upsert to cache
- Fallback to most recent cached rate if API fails
convertAmount
export async function convertAmount(
amount: number,
from: Currency,
to: Currency,
date?: Date
): Promise<number>
- Returns amount unchanged if same currency
- Rounds to 2 decimal places:
Math.round(converted * 100) / 100
Batch Loading Pattern (N+1 Prevention)
For dashboard aggregations, use batch loading:
batchLoadExchangeRates
export async function batchLoadExchangeRates(date?: Date): Promise<RateCache>
// Returns Map<string, number> for O(1) lookups
convertAmountWithCache
export function convertAmountWithCache(
amount: number,
from: Currency,
to: Currency,
cache: RateCache
): number
- No database calls (uses preloaded cache)
- Logs warning if rate missing, returns original amount
- Use in loops/aggregations to avoid N+1 queries
Cache Key Format
function rateCacheKey(from: Currency, to: Currency): string {
return `${from}:${to}` // e.g., "USD:EUR"
}
Refresh Workflow
export async function refreshExchangeRates(): Promise<
{ success: true; updatedAt: Date } | { error: { general: string[] }; updatedAt: Date }
>
- Fetches rates for ALL base currencies
- Upserts all currency pairs for today
- Called via
refreshExchangeRatesActionfrom dashboard UI
User Preference
model User {
preferredCurrency Currency @default(USD)
}
Dashboard displays amounts in user's preferred currency via conversion.
Key Files
src/lib/currency.ts- All currency functionssrc/app/actions/misc.ts- refreshExchangeRatesActionsrc/lib/dashboard-ux.ts- Uses batchLoadExchangeRates for aggregation
スコア
総合スコア
50/100
リポジトリの品質指標に基づく評価
✓SKILL.md
SKILL.mdファイルが含まれている
+20
○LICENSE
ライセンスが設定されている
0/10
○説明文
100文字以上の説明がある
0/10
○人気
GitHub Stars 100以上
0/15
○最近の活動
3ヶ月以内に更新がある
0/10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
○タグ
1つ以上のタグが設定されている
0/5
レビュー
💬
レビュー機能は近日公開予定です