Initial commit: Plataforma de Economía
Features: - React 18 + TypeScript frontend with Vite - Go + Gin backend API - PostgreSQL database - JWT authentication with refresh tokens - User management (admin panel) - Docker containerization - Progress tracking system - 4 economic modules structure Fixed: - Login with username or email - User creation without required email - Database nullable timestamps - API response field naming
This commit is contained in:
128
backend/internal/repository/user.go
Normal file
128
backend/internal/repository/user.go
Normal file
@@ -0,0 +1,128 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
"github.com/ren/econ/backend/internal/models"
|
||||
)
|
||||
|
||||
type UserRepository struct {
|
||||
db *pgxpool.Pool
|
||||
}
|
||||
|
||||
func NewUserRepository(db *pgxpool.Pool) *UserRepository {
|
||||
return &UserRepository{db: db}
|
||||
}
|
||||
|
||||
func (r *UserRepository) Create(ctx context.Context, user *models.Usuario) error {
|
||||
user.ID = uuid.New()
|
||||
user.CreadoEn = time.Now()
|
||||
user.Activo = true
|
||||
if user.Rol == "" {
|
||||
user.Rol = "estudiante"
|
||||
}
|
||||
|
||||
query := `
|
||||
INSERT INTO usuarios (id, email, username, password_hash, nombre, rol, creado_en, activo)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
||||
`
|
||||
_, err := r.db.Exec(ctx, query,
|
||||
user.ID, user.Email, user.Username, user.PasswordHash, user.Nombre, user.Rol, user.CreadoEn, user.Activo)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *UserRepository) GetByID(ctx context.Context, id uuid.UUID) (*models.Usuario, error) {
|
||||
query := `
|
||||
SELECT id, email, username, password_hash, nombre, rol, creado_en, ultimo_login, activo
|
||||
FROM usuarios WHERE id = $1
|
||||
`
|
||||
var user models.Usuario
|
||||
err := r.db.QueryRow(ctx, query, id).Scan(
|
||||
&user.ID, &user.Email, &user.Username, &user.PasswordHash, &user.Nombre,
|
||||
&user.Rol, &user.CreadoEn, &user.UltimoLogin, &user.Activo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
func (r *UserRepository) GetByEmail(ctx context.Context, email string) (*models.Usuario, error) {
|
||||
query := `
|
||||
SELECT id, email, username, password_hash, nombre, rol, creado_en, ultimo_login, activo
|
||||
FROM usuarios WHERE email = $1
|
||||
`
|
||||
var user models.Usuario
|
||||
err := r.db.QueryRow(ctx, query, email).Scan(
|
||||
&user.ID, &user.Email, &user.Username, &user.PasswordHash, &user.Nombre,
|
||||
&user.Rol, &user.CreadoEn, &user.UltimoLogin, &user.Activo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
func (r *UserRepository) GetByUsername(ctx context.Context, username string) (*models.Usuario, error) {
|
||||
query := `
|
||||
SELECT id, email, username, password_hash, nombre, rol, creado_en, ultimo_login, activo
|
||||
FROM usuarios WHERE username = $1
|
||||
`
|
||||
var user models.Usuario
|
||||
err := r.db.QueryRow(ctx, query, username).Scan(
|
||||
&user.ID, &user.Email, &user.Username, &user.PasswordHash, &user.Nombre,
|
||||
&user.Rol, &user.CreadoEn, &user.UltimoLogin, &user.Activo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &user, nil
|
||||
}
|
||||
|
||||
func (r *UserRepository) List(ctx context.Context) ([]models.Usuario, error) {
|
||||
query := `
|
||||
SELECT id, email, username, password_hash, nombre, rol, creado_en, ultimo_login, activo
|
||||
FROM usuarios ORDER BY creado_en DESC
|
||||
`
|
||||
rows, err := r.db.Query(ctx, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var users []models.Usuario
|
||||
for rows.Next() {
|
||||
var user models.Usuario
|
||||
err := rows.Scan(
|
||||
&user.ID, &user.Email, &user.Username, &user.PasswordHash, &user.Nombre,
|
||||
&user.Rol, &user.CreadoEn, &user.UltimoLogin, &user.Activo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
users = append(users, user)
|
||||
}
|
||||
return users, nil
|
||||
}
|
||||
|
||||
func (r *UserRepository) Update(ctx context.Context, user *models.Usuario) error {
|
||||
query := `
|
||||
UPDATE usuarios SET email = $2, nombre = $3, rol = $4, activo = $5
|
||||
WHERE id = $1
|
||||
`
|
||||
_, err := r.db.Exec(ctx, query,
|
||||
user.ID, user.Email, user.Nombre, user.Rol, user.Activo)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *UserRepository) Delete(ctx context.Context, id uuid.UUID) error {
|
||||
// Soft delete - set activo to false
|
||||
query := `UPDATE usuarios SET activo = false WHERE id = $1`
|
||||
_, err := r.db.Exec(ctx, query, id)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *UserRepository) UpdateLastLogin(ctx context.Context, id uuid.UUID) error {
|
||||
query := `UPDATE usuarios SET ultimo_login = $2 WHERE id = $1`
|
||||
_, err := r.db.Exec(ctx, query, id, time.Now())
|
||||
return err
|
||||
}
|
||||
Reference in New Issue
Block a user