Junior — Senior
Optimization and improvement of an existing service
livecode
Task condition
It is necessary to review the service code, identify problematic areas, and make corrections.
package service
import (
"context"
"encoding/json"
"io"
"net/http"
"strconv"
"github.com/jackc/pgx/v5"
)
// documentRepository is the repository for interacting with the database.
type documentRepository interface {
SavePDF(tx pgx.Tx, data []byte)
SetValueForUser(tx pgx.Tx, userID uint64, columnName string, flagValue any)
}
// pdfService is the interface of this service for external consumers.
type pdfService interface {
GenerateDocumentForUser(userID uint64) error
}
// Service is the structure-implementation of the service.
type Service struct {
conn pgx.Conn
docRepo documentRepository
}
/*
GenerateDocumentForUser creates a PDF document for the user and saves it to the database.
Marks the user with the flag pdf_generated – so as not to generate the file next time.
Does everything within a transaction.
*/
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{}
}