Сформулируй функциональные требования для отображения суммы в иностранной валюте
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Функциональные требования: отображение суммы в иностранной валюте
Требование FREQ-FX-001: Отображение сумм в иностранной валюте
╔═══════════════════════════════════════════════════════════════════╗
║ Functional Requirement: Display Amounts in Foreign Currency ║
║ ID: FREQ-FX-001 ║
║ Приоритет: Высокий ║
║ История версий: ║
║ v1.0 - 2026-04-01: Инициальная версия ║
║ v1.1 - 2026-04-15: Added real-time rates ║
╚═══════════════════════════════════════════════════════════════════╝
1. ОБЗОР (OVERVIEW)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Система должна отображать финансовые суммы в разных валютах.
Это необходимо для международных пользователей, чтобы они видели
цены в своей локальной валюте.
Основной сценарий:
User выбирает валюту → System конвертирует сумму → User видит в выбранной валюте
2. ВХОДНЫЕ ДАННЫЕ (INPUTS)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Система получает:
a) Сумма в базовой валюте (обязательно)
- Тип: Decimal (10,2)
- Пример: 100.00
- Базовая валюта: USD (по умолчанию)
- Диапазон: 0.01 до 999,999,999.99 USD
b) Целевая валюта (обязательно)
- Тип: ISO 4217 code (3 буквы)
- Примеры: EUR, GBP, JPY, RUB, CNY, INR
- Валидация: Существует в справочнике валют
- Список поддерживаемых валют: 150+ (все основные)
c) Дата для исторического курса (опционально)
- Если не указана: используем сегодняшний курс
- Если указана: курс на эту дату
- Диапазон: не раньше 30 лет назад
d) Пользовательские настройки (из профиля)
- Валюта отображения (предпочтение пользователя)
- Локаль (для форматирования)
- Точность (количество знаков после запятой)
3. ПРОЦЕСС ОБРАБОТКИ
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
3.1 Валидация входных данных
✓ Сумма
- Не ноль: >= 0.01
- Не более: 999,999,999.99
- Правильный формат: decimal с макс 2 знаками
- ERROR: "Invalid amount format"
✓ Базовая валюта
- Формат: 3 символа, заглавные буквы
- Существует в справочнике валют
- Валидные примеры: USD, EUR, GBP
- Невалидные: US, DOLLAR, usd (неправильный формат)
- ERROR: "Currency not supported"
✓ Целевая валюта
- Такие же правила как базовая
- Не может быть уже базовая валюта (можно, но бесполезно)
- WARNING: "Source and target are same, no conversion needed"
✓ Дата (если указана)
- Формат: YYYY-MM-DD
- Не в будущем
- Не ранее 30 лет назад
- ERROR: "Date out of supported range"
3.2 Получение курса обмена
Источник курса:
- Первый выбор: Наша база данных (cached rates)
- Второй выбор: External API (если курс устарел)
- Третий выбор: Last known rate (если API недоступен)
Кэширование:
- Курсы кэшируются на 1 час
- Дневные курсы кэшируются на 30 дней
- Если запрос в кэше → return instantly
- Если запрос вне кэша → fetch from API
Обновление курсов:
- Ежедневно в 00:00 UTC
- Когда юзер запрашивает новый курс
- Если курс старше 1 часа → refresh
3.3 Калькуляция
Формула:
target_amount = source_amount * exchange_rate
Пример: 100 USD * 0.92 EUR/USD = 92.00 EUR
Точность:
- Вычисления: 8 знаков после запятой (внутренний расчёт)
- Отображение: 2 знака для большинства валют
- Исключение: JPY, KWD (0 знаков), BHD (3 знака)
Rounding:
- Используй banker's rounding (round half to even)
- Для денег это важно!
- Пример: 92.125 EUR → 92.12 EUR (not 92.13)
3.4 Форматирование вывода
На основе локали пользователя:
en_US: $92.00
(symbol before, period as decimal separator)
de_DE: 92,00 €
(symbol after, comma as decimal separator)
en_IN: ₹ 92.00
(symbol before, period as decimal separator)
fr_FR: 92,00 €
(symbol after, space before currency)
Форматирование с тысячами:
- 1000000.00 USD → $1,000,000.00 (en_US)
- 1000000.00 EUR → 1.000.000,00 € (de_DE)
- 1000000.00 INR → ₹ 10,00,000.00 (en_IN - Indian style)
4. ВЫХОДНЫЕ ДАННЫЕ (OUTPUTS)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Ответ содержит:
```json
{
"success": true,
"result": {
"original_amount": 100.00,
"original_currency": "USD",
"converted_amount": 92.00,
"target_currency": "EUR",
"exchange_rate": 0.92,
"rate_date": "2026-04-15",
"formatted": {
"original": "$100.00",
"converted": "€92.00",
"display_text": "100 USD = 92 EUR"
},
"metadata": {
"rate_source": "ECB",
"rate_timestamp": "2026-04-15T00:00:00Z",
"precision": 2
}
},
"error": null
}
- ГРАНИЧНЫЕ СЛУЧАИ (EDGE CASES) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
5.1 Одинаковые валюты Input: amount=100, from=USD, to=USD Output: converted_amount=100, exchange_rate=1.0 Behavior: Показать что conversion не требуется
5.2 Очень малые суммы Input: amount=0.01, from=USD, to=JPY (1 cent → ~1 yen, очень маленькая сумма) Output: converted_amount=1.00 JPY (может быть меньше 0.01) Behavior: Показать с максимальной точностью (0 знаков для JPY)
5.3 Очень большие суммы Input: amount=999999999.99, from=USD, to=EUR Output: converted_amount=919999999.99 EUR Behavior: Обрабатывать без overflow'а, validation пройдёт
5.4 Курс недоступен Причины:
- Парная валюта не поддерживается
- External API down
- Исторического курса на эту дату нет
Behavior:
- ERROR: "Exchange rate not available"
- Предложить альтернативу (через USD как intermediate)
- Показать last known rate с warning
5.5 Валюта снята с обращения Пример: Russian Ruble был временно запрещён в 2022 Behavior:
- Позволить конвертировать из архивной валюты
- Но блокировать конвертирование в архивную
- WARNING: "This currency is no longer in circulation"
5.6 Историческая дата Input: amount=100, to=EUR, date=2019-01-01 EUR был введён в 1999, но физические монеты в 2002 Output: Работать с курсом 2019-01-01 Behavior: Достать исторический курс из БД
5.7 Очень старая дата Input: date=1980-01-01 (40 лет назад, вне нашего диапазона) Output: ERROR: "Historical data not available before 1995" Behavior: Reject с message
- БИЗНЕС-ПРАВИЛА ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
6.1 Точность курсов
- Mid-market rate (не bid/ask spread)
- Updated daily at 00:00 UTC
- Source: ECB для EUR, Fed для USD, etc.
6.2 Комиссии
- Функция конвертирует по mid-market rate
- НЕ учитывает банковские комиссии
- Это responsibility банка/платёжного сервиса
- NOTE: Если нужны комиссии, это отдельное требование
6.3 Локализация
- Символ валюты на основе локали пользователя
- Если локаль не установлена: использовать ISO code (USD, EUR)
- Дата/время: UTC, но отображать в timezone пользователя
6.4 Безопасность
- Rates не критичны для безопасности
- НО: храни их в защищённой таблице
- Audit trail: логируй все запросы rates
- Rate API key: шифруй в переменных окружения
6.5 Производительность
- Convert API должен отвечать < 200ms
- Кэш should hit 99% случаев
- Background job обновляет rates, не блокируя users
- НЕФУНКЦИОНАЛЬНЫЕ ТРЕБОВАНИЯ (LINK) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- NFREQ-PERF-001: Response < 200ms (95-ile)
- NFREQ-AVAIL-001: 99.9% uptime
- NFREQ-SEC-001: Encrypt rate data at rest
- NFREQ-INT-001: Support 50+ currencies
- ACCEPTANCE CRITERIA ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✓ Конвертирование USD → EUR работает Given: 100 USD When: convert to EUR Then: show ~92 EUR (с текущим курсом)
✓ Форматирование соответствует локали Given: en_US locale, 1000 USD Then: display "$1,000.00" Given: de_DE locale, 1000 EUR Then: display "1.000,00 €"
✓ Кэш работает Given: First request at 10:00 for USD→EUR When: Second request at 10:01 for USD→EUR Then: Use cached rate (same as first)
✓ Историческая дата работает Given: date=2020-01-01 When: convert USD to EUR for that date Then: use 2020-01-01 rate (not today's)
✓ Ошибки обрабатываются правильно Given: invalid_currency=XXX When: try to convert Then: return error 400 with message
✓ Edge cases обработаны
- Same currency: return 1.0 rate
- Unavailable rate: return error or fallback
- Very small/large amounts: handle without overflow
- DEPENDENCIES ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- Currency Reference table (FREQ-REF-001)
- Exchange rate cache (Redis или in-memory)
- External rate provider API (ECB, Fixer, etc.)
- User locale preferences (from User profile)
- Logging service (for audit trail)
- RISKS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Risk: Rate API provider down Mitigation: Use cached rate (may be up to 1 hour old)
Risk: Rounding errors accumulate Mitigation: Use banker's rounding, audit transactions
Risk: User confused by rate Mitigation: Show rate date and source
- NOTES ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
- Этот requirement фокусируется на display, не на финансовых операциях
- Если есть реальные транзакции: нужен отдельный requirement
- Для платёжных операций: используй locked rate (фиксируется в момент платежа)
- Это требование применимо к e-commerce, travel, и financial applications
### Summary
Это полное функциональное требование включает:
- Четкие входные/выходные данные
- Валидацию
- Процесс обработки
- Граничные случаи
- Бизнес-правила
- Acceptance criteria
- Dependencies и risks
**Разработчик может реализовать это требование без вопросов.**
Это именно то, что System Analyst должен написать для того, чтобы проект был успешен.