Войти Регистрация
Код-ревью

2. Начисление кешбэка по категориям

Средняя

Go · 52 строк

Обработчик получает операцию по карте и начисляет кешбэк по категории: не больше 3 000 ₽ за операцию и 5 000 ₽ в месяц. Процессинг повторяет запрос, если не получил ответ за 2 секунды.

Отметьте строки с ошибками.

В работе: Сервис лояльности: каждую покупку по карте процессинг присылает сюда.

Как проверяем Нажмите на строку с ошибкой и коротко напишите, что не так. Баг засчитан, если отмечена хотя бы одна его строка. Зачёт — найдено не меньше 60 % багов с учётом серьёзности (критичный весит 3, обычный 2, мелкий 1), а лишних отметок не больше, чем багов в коде. Пустые строки, скобки и комментарии лишними не считаем. Ответ один на подход: после него показываем разбор.
HTTPидемпотентностьdatabase/sqlденьги

Источник: Т‑Банк: секция Go, код-ревью с доработкой под бизнес-задачу. Условие пересказано своими словами.

Давали на собеседовании? Ответов пока мало — ваш поможет.
  1. package cashback
  2. import (
  3. "database/sql"
  4. "encoding/json"
  5. "log"
  6. "net/http"
  7. )
  8. type Handler struct {
  9. db *sql.DB
  10. }
  11. type accrueRequest struct {
  12. OperationID string `json:"operation_id"`
  13. ClientID string `json:"client_id"`
  14. Amount float64 `json:"amount"`
  15. Category string `json:"category"`
  16. }
  17. var rates = map[string]float64{"АЗС": 0.05, "Кафе": 0.03, "Аптеки": 0.05}
  18. func (h *Handler) Accrue(w http.ResponseWriter, r *http.Request) {
  19. var req accrueRequest
  20. if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
  21. w.WriteHeader(http.StatusInternalServerError)
  22. return
  23. }
  24. rate := rates[req.Category]
  25. cashback := req.Amount * rate
  26. if cashback > 3000 {
  27. cashback = 3000
  28. }
  29. rows, err := h.db.Query("SELECT sum(amount) FROM cashback WHERE client_id = $1 AND created_at >= date_trunc('month', now())", req.ClientID)
  30. if err != nil {
  31. http.Error(w, err.Error(), http.StatusInternalServerError)
  32. return
  33. }
  34. var monthTotal float64
  35. rows.Next()
  36. rows.Scan(&monthTotal)
  37. if monthTotal+cashback > 5000 {
  38. cashback = 5000 - monthTotal
  39. }
  40. _, err = h.db.Exec("INSERT INTO cashback(operation_id, client_id, amount) VALUES ($1, $2, $3)",
  41. req.OperationID, req.ClientID, cashback)
  42. if err != nil {
  43. log.Printf("cashback insert failed: %v", err)
  44. }
  45. w.WriteHeader(http.StatusOK)
  46. json.NewEncoder(w).Encode(map[string]float64{"cashback": cashback})
  47. }