package repository import ( "context" "errors" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" "golang.org/x/crypto/bcrypt" ) type AdminRepository struct { pool *pgxpool.Pool } func NewAdminRepository(pool *pgxpool.Pool) *AdminRepository { return &AdminRepository{pool: pool} } func (r *AdminRepository) Upsert(ctx context.Context, email, password string) error { hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { return err } _, err = r.pool.Exec(ctx, ` INSERT INTO admins (email, password_hash) VALUES ($1, $2) ON CONFLICT (email) DO UPDATE SET password_hash = EXCLUDED.password_hash `, email, string(hash)) return err } func (r *AdminRepository) Authenticate(ctx context.Context, email, password string) (bool, error) { var hash string err := r.pool.QueryRow(ctx, ` SELECT password_hash FROM admins WHERE email = $1 `, email).Scan(&hash) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return false, nil } return false, err } return bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) == nil, nil }