Files
NexaVPN/backend/internal/user/repository.go
nessi a197fb5bb6 fix: cast username and email to text in user repository queries
Add explicit ::text casts to username and email columns in List and Create queries to ensure proper type handling when scanning values from PostgreSQL. Update Create query to return role_id and role_name, adjusting Scan to match all returned fields.
2026-03-16 06:37:23 +01:00

72 lines
2.0 KiB
Go

package user
import (
"context"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgxpool"
)
type Repository interface {
List(ctx context.Context) ([]User, error)
Create(ctx context.Context, input CreateRequest, passwordHash string) (User, error)
SetActive(ctx context.Context, userID uuid.UUID, active bool) error
}
type PGRepository struct {
db *pgxpool.Pool
}
func NewPGRepository(db *pgxpool.Pool) *PGRepository {
return &PGRepository{db: db}
}
func (r *PGRepository) List(ctx context.Context) ([]User, error) {
rows, err := r.db.Query(ctx, `
select u.id, r.id, r.name, u.username::text, u.display_name, coalesce(u.email::text, ''), u.is_active
from users u
join roles r on r.id = u.role_id
where u.deleted_at is null
order by u.created_at desc
`)
if err != nil {
return nil, err
}
defer rows.Close()
var users []User
for rows.Next() {
var item User
if err := rows.Scan(&item.ID, &item.RoleID, &item.RoleName, &item.Username, &item.DisplayName, &item.Email, &item.IsActive); err != nil {
return nil, err
}
users = append(users, item)
}
return users, rows.Err()
}
func (r *PGRepository) Create(ctx context.Context, input CreateRequest, passwordHash string) (User, error) {
const query = `
insert into users (id, role_id, username, display_name, email, password_hash)
values ($1, (select id from roles where name = $2), $3, $4, nullif($5, ''), $6)
returning
id,
(select id from roles where name = $2),
$2,
username::text,
display_name,
coalesce(email::text, ''),
is_active
`
item := User{RoleName: input.Role}
err := r.db.QueryRow(ctx, query, uuid.New(), input.Role, input.Username, input.DisplayName, input.Email, passwordHash).
Scan(&item.ID, &item.RoleID, &item.RoleName, &item.Username, &item.DisplayName, &item.Email, &item.IsActive)
return item, err
}
func (r *PGRepository) SetActive(ctx context.Context, userID uuid.UUID, active bool) error {
_, err := r.db.Exec(ctx, `update users set is_active = $2, updated_at = now() where id = $1`, userID, active)
return err
}