Add CancelReservationHandler (DELETE /api/bookings/reserve) to release authenticated user's active reservation. Register route in main.go. Add background goroutine for periodic reservation cleanup using CleanupOldReservations. Add idx_time_blockers_created_at index and extend anon cleanup to cover edit_request reservations in init-script.sql. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
36 lines
1.1 KiB
Go
36 lines
1.1 KiB
Go
package bookings
|
|
|
|
import (
|
|
"log"
|
|
"net/http"
|
|
|
|
"crussell/db"
|
|
"crussell/mw"
|
|
)
|
|
|
|
// CancelReservationHandler releases the authenticated user's active reservation
|
|
// by deleting their RESERVATION:user entries from time_blockers.
|
|
// It does NOT create a booking — it only releases the temporary slot hold.
|
|
//
|
|
// DELETE /api/bookings/reserve
|
|
func CancelReservationHandler(w http.ResponseWriter, r *http.Request) {
|
|
userID, ok := r.Context().Value(mw.UserIDKey).(string)
|
|
if !ok || userID == "" {
|
|
log.Printf("CancelReservationHandler: user ID not found in context")
|
|
http.Error(w, "Authentication required", http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
_, err := db.Conn.Exec(r.Context(), `
|
|
DELETE FROM time_blockers
|
|
WHERE created_by = $1 AND description LIKE 'RESERVATION:user:%'
|
|
`, userID)
|
|
if err != nil {
|
|
log.Printf("CancelReservationHandler: failed to delete reservation for user %s: %v", userID, err)
|
|
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
mw.RespondJSON(w, http.StatusOK, map[string]string{"status": "reservation cancelled"})
|
|
}
|