feat(auth): implement user registration endpoint

This commit is contained in:
2025-06-14 21:46:27 +03:00
parent 795f220e90
commit 54ce479a6e
8 changed files with 278 additions and 6 deletions

View File

@@ -0,0 +1,30 @@
package database
import (
"database/sql"
"log"
"os"
_ "github.com/jackc/pgx/v5/stdlib" // Регистрируем pgx драйвер
)
// Connect устанавливает соединение с базой данных PostgreSQL
func Connect() *sql.DB {
connStr := os.Getenv("DATABASE_URL")
if connStr == "" {
log.Fatal("DATABASE_URL environment variable is not set")
}
db, err := sql.Open("pgx", connStr)
if err != nil {
log.Fatalf("Unable to connect to database: %v\n", err)
}
// Проверяем, что соединение действительно установлено
if err = db.Ping(); err != nil {
log.Fatalf("Unable to ping database: %v\n", err)
}
log.Println("Successfully connected to PostgreSQL!")
return db
}

View File

@@ -0,0 +1,59 @@
// File: backend/internal/database/user_repository.go
package database
import (
"context"
"database/sql"
"errors"
"gitea.mrixs.me/minecraft-platform/backend/internal/models"
)
var (
ErrUserExists = errors.New("user with this username or email already exists")
)
type UserRepository struct {
DB *sql.DB
}
// CreateUserTx создает нового пользователя и его профиль в рамках одной транзакции
func (r *UserRepository) CreateUserTx(ctx context.Context, user *models.User) error {
tx, err := r.DB.BeginTx(ctx, nil)
if err != nil {
return err
}
// Гарантируем откат транзакции в случае любой ошибки
defer tx.Rollback()
// Шаг 4 из ТЗ: Проверка уникальности
var exists bool
err = tx.QueryRowContext(ctx,
"SELECT EXISTS(SELECT 1 FROM users WHERE username = $1 OR email = $2)",
user.Username, user.Email).Scan(&exists)
if err != nil {
return err
}
if exists {
return ErrUserExists
}
// Шаг 7 из ТЗ: INSERT в таблицу users. Получаем ID нового пользователя.
var newUserID int
err = tx.QueryRowContext(ctx,
"INSERT INTO users (uuid, username, email, password_hash, role) VALUES ($1, $2, $3, $4, $5) RETURNING id",
user.UUID, user.Username, user.Email, user.PasswordHash, user.Role,
).Scan(&newUserID)
if err != nil {
return err
}
// Шаг 9 из ТЗ: INSERT в таблицу profiles
_, err = tx.ExecContext(ctx, "INSERT INTO profiles (user_id) VALUES ($1)", newUserID)
if err != nil {
return err
}
// Шаг 10 из ТЗ: Коммитим транзакцию
return tx.Commit()
}