sno-quiz/backend/internal/repository/admin_repository.go
2025-09-17 22:22:14 +03:00

157 lines
3.5 KiB
Go

package repository
import (
"context"
"sno/internal/models"
"sno/internal/types"
"github.com/jackc/pgx/v5/pgxpool"
)
// AdminRepository handles database operations for admins
type AdminRepository interface {
GetByTelegramID(ctx context.Context, telegramID int64) (*models.Admin, error)
Create(ctx context.Context, admin *models.Admin) error
Update(ctx context.Context, admin *models.Admin) error
Delete(ctx context.Context, telegramID int64) error
ListAll(ctx context.Context) ([]*models.Admin, error)
GetUserRole(ctx context.Context, telegramID int64) (types.UserRole, error)
}
// adminRepository implements AdminRepository interface
type adminRepository struct {
db *pgxpool.Pool
}
// NewAdminRepository creates a new admin repository
func NewAdminRepository(db *pgxpool.Pool) AdminRepository {
return &adminRepository{db: db}
}
// GetByTelegramID retrieves an admin by Telegram ID
func (r *adminRepository) GetByTelegramID(ctx context.Context, telegramID int64) (*models.Admin, error) {
query := `
SELECT telegram_id, role, name, added_by, added_at
FROM admins
WHERE telegram_id = $1
`
var admin models.Admin
err := r.db.QueryRow(ctx, query, telegramID).Scan(
&admin.TelegramID,
&admin.Role,
&admin.Name,
&admin.AddedBy,
&admin.AddedAt,
)
if err != nil {
if err.Error() == "no rows in result set" {
return nil, nil // Admin not found
}
return nil, err
}
return &admin, nil
}
// Create creates a new admin record
func (r *adminRepository) Create(ctx context.Context, admin *models.Admin) error {
query := `
INSERT INTO admins (telegram_id, role, name, added_by)
VALUES ($1, $2, $3, $4)
RETURNING added_at
`
return r.db.QueryRow(ctx, query,
admin.TelegramID,
admin.Role,
admin.Name,
admin.AddedBy,
).Scan(&admin.AddedAt)
}
// Update updates an admin record
func (r *adminRepository) Update(ctx context.Context, admin *models.Admin) error {
query := `
UPDATE admins
SET role = $2, name = $3
WHERE telegram_id = $1
`
_, err := r.db.Exec(ctx, query,
admin.TelegramID,
admin.Role,
admin.Name,
)
return err
}
// Delete deletes an admin record
func (r *adminRepository) Delete(ctx context.Context, telegramID int64) error {
query := `DELETE FROM admins WHERE telegram_id = $1`
_, err := r.db.Exec(ctx, query, telegramID)
return err
}
// ListAll retrieves all admins
func (r *adminRepository) ListAll(ctx context.Context) ([]*models.Admin, error) {
query := `
SELECT telegram_id, role, name, added_by, added_at
FROM admins
ORDER BY added_at DESC
`
rows, err := r.db.Query(ctx, query)
if err != nil {
return nil, err
}
defer rows.Close()
var admins []*models.Admin
for rows.Next() {
var admin models.Admin
err := rows.Scan(
&admin.TelegramID,
&admin.Role,
&admin.Name,
&admin.AddedBy,
&admin.AddedAt,
)
if err != nil {
return nil, err
}
admins = append(admins, &admin)
}
return admins, nil
}
// GetUserRole retrieves user role from admins table
func (r *adminRepository) GetUserRole(ctx context.Context, telegramID int64) (types.UserRole, error) {
query := `
SELECT role
FROM admins
WHERE telegram_id = $1
`
var role models.AdminRole
err := r.db.QueryRow(ctx, query, telegramID).Scan(&role)
if err != nil {
if err.Error() == "no rows in result set" {
return types.RoleUser, nil // User is not an admin
}
return "", err
}
// Convert models.AdminRole to types.UserRole
switch role {
case models.RoleAdmin:
return types.RoleAdmin, nil
case models.RoleOperator:
return types.RoleOperator, nil
default:
return types.RoleUser, nil
}
}