This commit is contained in:
Alex Shevchuk
2025-08-18 17:12:04 +03:00
commit d84487d238
157 changed files with 160686 additions and 0 deletions

View File

@@ -0,0 +1,203 @@
package pgdb
import (
"context"
"database/sql"
"fmt"
"strings"
dberrors "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/errors"
dbtypes "git-molva.ru/Molva/molva-backend/services/api_gateway/internal/database/types"
"github.com/Masterminds/squirrel"
"github.com/google/uuid"
)
func (c *client) GetClientValidation(
ctx context.Context,
request *dbtypes.ClientValidationGetRequest,
) (*dbtypes.ClientValidationGetResponse, error) {
if request == nil {
return nil, fmt.Errorf("%w: request is nil", dberrors.ErrBadRequest)
}
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
userValidationTable = fmt.Sprintf("%s.%s", c.config.Schema, UserValidationTableName)
)
getUserValidation := psql.Select(
"status", "description",
).
From(userValidationTable).
Where(squirrel.Eq{"uid": request.UserId})
query, args, err := getUserValidation.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building 'get user validation' query: %v", dberrors.ErrInternal, err)
}
row := c.db.QueryRowContext(ctx, query, args...)
var result dbtypes.ClientValidation
if err := row.Scan(&result.Status, &result.Description); err != nil {
if err == sql.ErrNoRows {
return nil, dberrors.ErrNotFound
}
return nil, fmt.Errorf("%w: error scanning row for 'get user validation' query: %v", dberrors.ErrInternal, err)
}
return &dbtypes.ClientValidationGetResponse{
ClientValidation: &result,
}, nil
}
func (c *client) CreateUser(
ctx context.Context,
request *dbtypes.UserSaveRequest,
) (*dbtypes.UserSaveResponse, error) {
if request == nil {
return nil, fmt.Errorf("%w: request is nil", dberrors.ErrBadRequest)
}
tx, err := c.db.BeginTx(ctx, nil)
if err != nil {
return nil, fmt.Errorf("%w: error starting transaction: %v", dberrors.ErrInternal, err)
}
defer func() { _ = tx.Rollback() }()
result, err := c.createUser(ctx, tx, request)
if err != nil {
return nil, fmt.Errorf("error creating user: %w", err)
}
if err := c.createUserValidationTicket(ctx, tx, request); err != nil {
return nil, fmt.Errorf("error creating user validation ticket: %w", err)
}
resp, err := c.createCompany(ctx, tx, &dbtypes.CompanyCreateRequest{
OwnerId: request.Id,
Staff: []string{
request.Id,
},
})
if err != nil {
return nil, fmt.Errorf("error creating company: %w", err)
}
var ownerId string
switch request.Type {
case dbtypes.UserTypeAgent:
ownerId = request.Id
case dbtypes.UserTypeDistributor:
ownerId = resp.Id
default:
return nil, fmt.Errorf("%w: unknown user type: %v", dberrors.ErrBadRequest, request.Type)
}
balanceId := fmt.Sprintf("%sBAL", strings.ReplaceAll(uuid.NewString(), "-", ""))
if err := c.createBalance(ctx, tx, &dbtypes.BalanceCreateRequest{
Id: balanceId,
OwnerId: ownerId,
RawBalance: 0,
CleanBalance: 0,
}); err != nil {
return nil, fmt.Errorf("error creating balance: %w", err)
}
if err := tx.Commit(); err != nil {
return nil, fmt.Errorf("%w: error committing transaction: %w", dberrors.ErrInternal, err)
}
return result, nil
}
func (c *client) createUser(
ctx context.Context,
driver Driver,
request *dbtypes.UserSaveRequest,
) (*dbtypes.UserSaveResponse, error) {
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
userTable = fmt.Sprintf("%s.%s", c.config.Schema, UsersTableName)
)
saveUser := psql.Insert(userTable).
Columns(
"uid", "name", "phone", "email", "client_type_id",
).
Values(
request.Id, request.FullName, request.Phone, request.Email, request.Type,
)
query, args, err := saveUser.ToSql()
if err != nil {
return nil, fmt.Errorf("%w: error building 'save user' query: %v", dberrors.ErrInternal, err)
}
res, err := driver.ExecContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("%w: error executing 'save user' query: %v", dberrors.ErrInternal, err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return nil, fmt.Errorf("%w: error getting rows affected for 'save user' query: %v", dberrors.ErrInternal, err)
}
if rowsAffected == 0 {
return nil, dberrors.ErrInternal
}
return &dbtypes.UserSaveResponse{}, nil
}
func (c *client) createUserValidationTicket(
ctx context.Context,
driver Driver,
request *dbtypes.UserSaveRequest,
) error {
var (
psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
userValidationTable = fmt.Sprintf("%s.%s", c.config.Schema, UserValidationTableName)
)
// TODO: use normal uuid after DB reengineering
ticketId := fmt.Sprintf("%sVAL", strings.ReplaceAll(uuid.NewString(), "-", ""))
createUserValidation := psql.Insert(userValidationTable).
Columns(
"id", "uid", "status", "description", "last_update",
).
Values(
ticketId, request.Id, dbtypes.ClientValStatusNew, request.FullName, squirrel.Expr("CURRENT_TIMESTAMP"),
)
query, args, err := createUserValidation.ToSql()
if err != nil {
return fmt.Errorf("%w: error building 'create user validation' query: %v", dberrors.ErrInternal, err)
}
res, err := driver.ExecContext(ctx, query, args...)
if err != nil {
return fmt.Errorf("%w: error executing 'create user validation' query: %v", dberrors.ErrInternal, err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return fmt.Errorf("%w: error getting rows affected for 'create user validation' query: %v", dberrors.ErrInternal, err)
}
if rowsAffected == 0 {
return dberrors.ErrInternal
}
return nil
}