Sobes.tech
Junior — Senior
67

Оптимизация и улучшение существующего сервиса

Task condition

Необходимо выполнить ревью кода сервиса, выявить проблемные места и внести исправления.

package service

import (
  "context"
  "encoding/json"
  "io"
  "net/http"
  "strconv"

  "github.com/jackc/pgx/v5"
)

// documentRepository репозиторий для взаимодействия с БД.
type documentRepository interface {
  SavePDF(tx pgx.Tx, data []byte)
  SetValueForUser(tx pgx.Tx, userID uint64, columnName string, flagValue any)
}

// pdfService интерфейс данного сервиса для использования внешними потребителями.
type pdfService interface {
  GenerateDocumentForUser(userID uint64) error
}

// Service структура-реализация сервиса.
type Service struct {
  conn     pgx.Conn
  docRepo  documentRepository
}
/*
GenerateDocumentForUser создаёт pdf-документ для пользователя и сохраняет в БД.
Помечает пользователя флагом pdf_generated – чтобы не генерировать файл в следующий раз.
Делает всё в рамках транзакции.
*/
func (s Service) GenerateDocumentForUser(userID uint64) error {
  ctx := context.Background()

  tx, err := s.conn.Begin(ctx)
  if err != nil {
    panic("cannot start tx!")
  }

  data, err := getDataFromExternalService(userID)
  if err != nil {
    return err
  }

  pdf := generatePDF(data)

  s.docRepo.SavePDF(tx, pdf)
  s.docRepo.SetValueForUser(tx, userID, "pdf_generated", true)

  return tx.Commit(ctx)
}
type data struct {
  Phone string `json:"phone"`
  INN   string `json:"inn"`
}

func getDataFromExternalService(userID uint64) (data, error) {
  var d data

  resp, err := http.Get("http://nalog.external.provider/info/" + strconv.Itoa(int(userID)))
  if err != nil {
    return d, err
  }

  bytes, _ := io.ReadAll(resp.Body)

  json.Unmarshal(bytes, &d)

  return d, nil
}

func generatePDF(data data) []byte {
  // external lib for creating pdf
  return []byte{}
}