refactor(backend): migrate from sql.ErrNoRows to pgx.ErrNoRows

Replace all database/sql.ErrNoRows checks with pgx.ErrNoRows across backend handlers.

Migration includes: jwt.go, local.go, admin_reserve.go, custom_services.go,
discount_campaigns.go, services.go, account.go, customer_relationship.go,
guest.go. Also removes unused test_helpers.go resetTestData function.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-06-20 16:58:08 +01:00
co-authored by Sisyphus
parent b03c4f6247
commit efd3ad5405
10 changed files with 24 additions and 26 deletions
+5 -3
View File
@@ -6,11 +6,13 @@ import (
"crussell/mw"
"database/sql"
"encoding/json"
"errors"
"net/http"
"strconv"
"time"
"github.com/go-chi/chi/v5"
"github.com/jackc/pgx/v5"
)
type CustomService struct {
@@ -268,7 +270,7 @@ func GetCustomService(w http.ResponseWriter, r *http.Request) {
SELECT id, name, description, price, duration_minutes, minimum_age_required, notes, created_at, created_by, usage_count, last_used_at
FROM custom_services WHERE id = $1
`, id).Scan(&cs.ID, &cs.Name, &desc, &cs.Price, &cs.DurationMinutes, &cs.MinimumAgeRequired, &notes, &cs.CreatedAt, &createdBy, &cs.UsageCount, &lastUsedAt)
if err == sql.ErrNoRows {
if errors.Is(err, pgx.ErrNoRows) {
http.Error(w, "Custom service not found", http.StatusNotFound)
return
}
@@ -386,7 +388,7 @@ func PromoteCustomService(w http.ResponseWriter, r *http.Request) {
SELECT name, description, price, duration_minutes, minimum_age_required, notes, created_by
FROM custom_services WHERE id = $1
`, id).Scan(&name, &desc, &price, &durationMinutes, &minimumAgeRequired, &notes, &createdBy)
if err == sql.ErrNoRows {
if errors.Is(err, pgx.ErrNoRows) {
http.Error(w, "Custom service not found", http.StatusNotFound)
return
}
@@ -454,7 +456,7 @@ func DeleteCustomService(w http.ResponseWriter, r *http.Request) {
var usageCount int
err := db.DB.QueryRow(r.Context(), `SELECT usage_count FROM custom_services WHERE id = $1`, id).Scan(&usageCount)
if err == sql.ErrNoRows {
if errors.Is(err, pgx.ErrNoRows) {
http.Error(w, "Custom service not found", http.StatusNotFound)
return
}
+2 -1
View File
@@ -6,6 +6,7 @@ import (
"crussell/mw"
"database/sql"
"encoding/json"
"errors"
"log"
"net/http"
"strconv"
@@ -666,7 +667,7 @@ func GetCampaignStats(w http.ResponseWriter, r *http.Request) {
&createdBy,
)
if err == sql.ErrNoRows {
if errors.Is(err, pgx.ErrNoRows) {
http.Error(w, "Campaign not found", http.StatusNotFound)
return
}
-9
View File
@@ -10,21 +10,12 @@ import (
"net/http"
"net/http/httptest"
"strings"
"testing"
"crussell/db"
"crussell/mw"
"crussell/testutils/testdb"
"github.com/go-chi/chi/v5"
)
// resetTestData truncates tables to clean up data between tests
func resetTestData(t *testing.T) {
t.Helper()
testdb.TruncateTables(t, db.DB)
}
// makeAdminRequest creates a request with admin context
// Note: Using 12-char IDs to match CHAR(12) columns in schema (e.g., created_by)
func makeAdminRequest(handler http.Handler, method, path string, body interface{}) *httptest.ResponseRecorder {