add service
All checks were successful
Deploy Smart Search Backend Test / deploy (push) Successful in 2m25s

This commit is contained in:
vallyenfail
2026-01-19 19:14:51 +03:00
parent 33b70d1ee4
commit ff08bb2254
11 changed files with 268 additions and 62 deletions

View File

@@ -64,4 +64,5 @@ type SupplierRepository interface {
type TokenUsageRepository interface {
Create(ctx context.Context, usage *model.TokenUsage) error
CreateTx(ctx context.Context, tx pgx.Tx, usage *model.TokenUsage) error
GetBalanceStatistics(ctx context.Context, userID int) (averageCost float64, history []*model.WriteOffHistory, err error)
}

View File

@@ -2,6 +2,7 @@ package repository
import (
"context"
"strconv"
"git.techease.ru/Smart-search/smart-search-back/internal/model"
errs "git.techease.ru/Smart-search/smart-search-back/pkg/errors"
@@ -49,3 +50,59 @@ func (r *tokenUsageRepository) createWithExecutor(ctx context.Context, exec DBTX
return nil
}
func (r *tokenUsageRepository) GetBalanceStatistics(ctx context.Context, userID int) (float64, []*model.WriteOffHistory, error) {
avgQuery := r.qb.Select("COALESCE(AVG(COALESCE(rtu.token_cost, 0)), 0)").
From("request_token_usage rtu").
Join("requests_for_suppliers rfs ON rtu.request_id = rfs.id").
Where(sq.Eq{"rfs.user_id": userID})
avgSQL, avgArgs, err := avgQuery.ToSql()
if err != nil {
return 0, nil, errs.NewInternalError(errs.DatabaseError, "failed to build average query", err)
}
var averageCost float64
if err := r.pool.QueryRow(ctx, avgSQL, avgArgs...).Scan(&averageCost); err != nil {
return 0, nil, errs.NewInternalError(errs.DatabaseError, "failed to get average cost", err)
}
historyQuery := r.qb.Select(
"rtu.id",
"TO_CHAR(rtu.created_at, 'DD-MM-YYYY')",
"COALESCE(rtu.token_cost, 0)",
).
From("request_token_usage rtu").
Join("requests_for_suppliers rfs ON rtu.request_id = rfs.id").
Where(sq.Eq{"rfs.user_id": userID}).
OrderBy("rtu.created_at DESC").
Limit(8)
historySQL, historyArgs, err := historyQuery.ToSql()
if err != nil {
return 0, nil, errs.NewInternalError(errs.DatabaseError, "failed to build history query", err)
}
rows, err := r.pool.Query(ctx, historySQL, historyArgs...)
if err != nil {
return 0, nil, errs.NewInternalError(errs.DatabaseError, "failed to get write-off history", err)
}
defer rows.Close()
var history []*model.WriteOffHistory
for rows.Next() {
var operationID int
var item model.WriteOffHistory
if err := rows.Scan(&operationID, &item.Data, &item.Amount); err != nil {
return 0, nil, errs.NewInternalError(errs.DatabaseError, "failed to scan write-off history", err)
}
item.OperationID = strconv.Itoa(operationID)
history = append(history, &item)
}
if err := rows.Err(); err != nil {
return 0, nil, errs.NewInternalError(errs.DatabaseError, "failed to iterate write-off history", err)
}
return averageCost, history, nil
}