chore: initial project scaffold with admin web, backend, desktop client, and deployment setup
Add monorepo structure for NexaVPN WireGuard control plane including: - .gitignore for node_modules, build artifacts, and environment files - README with project overview, monorepo layout, and quick start guide - Admin web UI with React, Vite, TypeScript, and nginx reverse proxy - API client with type definitions for users, devices, policies, gateways, and audit logs - Admin pages for dashboard, users, devices, policies, g
This commit is contained in:
64
backend/internal/user/repository.go
Normal file
64
backend/internal/user/repository.go
Normal file
@@ -0,0 +1,64 @@
|
||||
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, u.display_name, coalesce(u.email, ''), 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, username, display_name, coalesce(email, ''), 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.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
|
||||
}
|
||||
Reference in New Issue
Block a user