Refactor patch test system and add booking edit requests

- Replace patch_test_duration_hours on services with separate
  patch_tests table
- Add user_patch_tests table to track user patch test records
- Add booking edit request system: users can request time changes
- Add admin handlers to list, approve, and reject edit requests
- Add validation to prevent editing completed/cancelled bookings
- Add overlap and closed-day checks for booking edits
This commit is contained in:
2026-02-24 17:23:28 +00:00
parent 89d848ee72
commit f59595eeec
11 changed files with 906 additions and 255 deletions
+57 -9
View File
@@ -57,10 +57,10 @@ func CreateTestService(pool *pgxpool.Pool) (string, error) {
ctx := context.Background()
var serviceID string
err := pool.QueryRow(ctx, `
INSERT INTO services (name, description, price, duration_minutes, is_active, patch_test_duration_hours, minimum_age_required)
VALUES ($1, $2, $3, $4, $5, $6, $7)
INSERT INTO services (name, description, price, duration_minutes, is_active, minimum_age_required)
VALUES ($1, $2, $3, $4, $5, $6)
RETURNING id
`, "Test Service", "A test service for unit tests", 50.00, 60, true, 0, 16).Scan(&serviceID)
`, "Test Service", "A test service for unit tests", 50.00, 60, true, 16).Scan(&serviceID)
if err != nil {
return "", fmt.Errorf("failed to create service: %w", err)
@@ -69,20 +69,68 @@ func CreateTestService(pool *pgxpool.Pool) (string, error) {
return serviceID, nil
}
func CreateTestServiceWithPatchTest(pool *pgxpool.Pool) (string, error) {
// CreateTestServiceWithPatchTest creates a service and a patch test that links to it
// Returns serviceID, patchTestID
func CreateTestServiceWithPatchTest(pool *pgxpool.Pool) (string, string, error) {
ctx := context.Background()
// First create the service
var serviceID string
err := pool.QueryRow(ctx, `
INSERT INTO services (name, description, price, duration_minutes, is_active, patch_test_duration_hours, minimum_age_required)
VALUES ($1, $2, $3, $4, $5, $6, $7)
INSERT INTO services (name, description, price, duration_minutes, is_active, minimum_age_required)
VALUES ($1, $2, $3, $4, $5, $6)
RETURNING id
`, "Test Patch Test Service", "A test service requiring patch test", 75.00, 90, true, 48, 18).Scan(&serviceID)
`, "Test Patch Test Service", "A test service requiring patch test", 75.00, 90, true, 18).Scan(&serviceID)
if err != nil {
return "", fmt.Errorf("failed to create service: %w", err)
return "", "", fmt.Errorf("failed to create service: %w", err)
}
return serviceID, nil
// Now create a patch test that links to this service
var patchTestID string
err = pool.QueryRow(ctx, `
INSERT INTO patch_tests (name, description, notice_duration_hours, expiry_months, service_ids)
VALUES ($1, $2, $3, $4, $5)
RETURNING id
`, "Test Patch Test", "A patch test for testing", 24, 6, []string{serviceID}).Scan(&patchTestID)
if err != nil {
return "", "", fmt.Errorf("failed to create patch test: %w", err)
}
return serviceID, patchTestID, nil
}
// CreateTestPatchTest creates a patch test definition
func CreateTestPatchTest(pool *pgxpool.Pool, serviceIDs []string) (string, error) {
ctx := context.Background()
var patchTestID string
err := pool.QueryRow(ctx, `
INSERT INTO patch_tests (name, description, notice_duration_hours, expiry_months, service_ids)
VALUES ($1, $2, $3, $4, $5)
RETURNING id
`, "Test Patch Test", "A patch test for testing", 24, 6, serviceIDs).Scan(&patchTestID)
if err != nil {
return "", fmt.Errorf("failed to create patch test: %w", err)
}
return patchTestID, nil
}
// CreateUserPatchTest creates a user patch test record
func CreateUserPatchTest(pool *pgxpool.Pool, userID, patchTestID string, testedAt string) error {
ctx := context.Background()
_, err := pool.Exec(ctx, `
INSERT INTO user_patch_tests (user_id, patch_test_id, tested_at)
VALUES ($1, $2, $3)
`, userID, patchTestID, testedAt)
if err != nil {
return fmt.Errorf("failed to create user patch test: %w", err)
}
return nil
}
func CreateTestBooking(pool *pgxpool.Pool, userID, serviceID string) (string, error) {
+5 -2
View File
@@ -76,7 +76,9 @@ func Migrate(t *testing.T, pool *pgxpool.Pool) {
"booking_services",
"payments",
"bookings",
"user_service_patch_tests",
"user_patch_tests",
"patch_tests",
"booking_edit_requests",
"services",
"verification_codes",
"user_social_logins",
@@ -196,7 +198,8 @@ func TruncateTables(t *testing.T, pool *pgxpool.Pool) {
"booking_services",
"payments",
"bookings",
"user_service_patch_tests",
"user_patch_tests",
"patch_tests",
"services",
"admin_notifications",
"user_referrals",