← Назад к вопросам

Сформулируй функциональные требования для отображения суммы в иностранной валюте

2.0 Middle🔥 231 комментариев
#User Story и Use Case#Требования и их анализ

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Функциональные требования: отображение суммы в иностранной валюте

Требование 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

}

  1. ГРАНИЧНЫЕ СЛУЧАИ (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

  1. БИЗНЕС-ПРАВИЛА ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

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
  1. НЕФУНКЦИОНАЛЬНЫЕ ТРЕБОВАНИЯ (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
  1. 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
  1. 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)
  1. 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

  1. NOTES ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  • Этот requirement фокусируется на display, не на финансовых операциях
  • Если есть реальные транзакции: нужен отдельный requirement
  • Для платёжных операций: используй locked rate (фиксируется в момент платежа)
  • Это требование применимо к e-commerce, travel, и financial applications

### Summary

Это полное функциональное требование включает:
- Четкие входные/выходные данные
- Валидацию
- Процесс обработки
- Граничные случаи
- Бизнес-правила
- Acceptance criteria
- Dependencies и risks

**Разработчик может реализовать это требование без вопросов.**

Это именно то, что System Analyst должен написать для того, чтобы проект был успешен.