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 } }