Fix payment review round: till integrity, HTTP client tests, concurrency tests, card-selection consolidation
Addresses the payment review (all 10 blocking + 2 minor findings): Till money-integrity (CreateTillSale): - Add pg_advisory_lock on the idempotency key (concurrent same-key double-funding race) - Guard amount on pending-reuse retry (mirrors tip/gift-card guards) - Explicitly complete the row for cash/on_the_house pending-reuse - Reject method-switch on a live card-machine checkout (double-charge guard) - 3 regression tests (amount-mismatch, cash-completes-row, method-switch) BookingFlow: - Fetch saved cards at the deposit step (was dead code) - Charge the server-computed deposit_amount, not the client estimate HTTP client tests (was untested): doJSON error parsing, refund sentinel classification, payment/refund/card wire shapes, checkout polling states, list-refunds pagination + 20-page guard, sha256 card idempotency key Concurrency regression tests: real two-goroutine races for BuyGiftCard, tip, and booking-payment locks asserting exactly-one record each Frontend: - Fix CRIT-1: zero-saved-card users blocked (all flows now handle it) - Consolidate tip/deposit/Buy-Gift-Card card UI onto CardSelection - Explicit save-card consent checkbox (was silent/inconsistent) - Fix stale saved-card field names in BookingFlow (last4 -> last_4) - Unique instance ids (crypto.randomUUID) in CardSelection/SquareCardInput - UserPaymentModal: keep card form mounted on error + Try Again button Health/docs: /api/health reports square state (mock/ok, was not_implemented), close P1 backlog, correct stale webhook and env-var claims
This commit is contained in:
+10
-2
@@ -119,7 +119,11 @@ func initS3() {
|
||||
|
||||
func initSquare() {
|
||||
payments.SquareClient = square.NewClient()
|
||||
fmt.Println("Square client initialized (dev mock)")
|
||||
if env := os.Getenv("SQUARE_ENVIRONMENT"); env == "sandbox" || env == "production" {
|
||||
fmt.Printf("Square client initialized (%s, real API)\n", env)
|
||||
} else {
|
||||
fmt.Println("Square client initialized (dev mock)")
|
||||
}
|
||||
}
|
||||
|
||||
func healthCheckHandler(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -128,7 +132,7 @@ func healthCheckHandler(w http.ResponseWriter, r *http.Request) {
|
||||
"backend": "ok",
|
||||
"database": "ok",
|
||||
"s3_storage": "ok",
|
||||
"square_payments": "not_implemented",
|
||||
"square_payments": "ok",
|
||||
"frontend": "unknown",
|
||||
}
|
||||
|
||||
@@ -146,6 +150,10 @@ func healthCheckHandler(w http.ResponseWriter, r *http.Request) {
|
||||
services["s3_storage"] = "not_configured"
|
||||
}
|
||||
|
||||
if env := os.Getenv("SQUARE_ENVIRONMENT"); env == "" || env == "mock" {
|
||||
services["square_payments"] = "mock"
|
||||
}
|
||||
|
||||
if status == "degraded" {
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user