Operational recovery procedures. Keep this file up to date when infrastructure changes.
When to use: A booking_request row was accidentally deleted or corrupted.
PITR window: 7 days (free plan) · 30 days (Pro plan).
Steps:
- Go to Supabase Dashboard → Database → Backups
- Use "Point in Time Recovery" to restore to a timestamp before the deletion
- PITR restores the entire database — it is destructive. If you only need one row, either:
- Restore to a separate project, export the row, then re-insert it manually
- Or query the Supabase support team for row-level recovery assistance
- After restore, re-apply any migrations that ran after the target timestamp
Alternative (if the booking ID is known): Re-insert the row manually via the Supabase SQL editor using data from the audit_log (details JSONB on booking_created entry).
When to use: A customer lost their magic link email and needs a new one.
Steps:
Option A — via artist dashboard:
- Log in as the artist
- Go to Bookings → Requests → open the booking
- Use the "Send reconfirmation" button (available for approved bookings) — this refreshes the token and emails the customer
Option B — via Supabase SQL editor (if the booking is in a status that doesn't allow reconfirmation):
-- Generate a new token and update the hash
-- Replace {booking_id} and {new_hash} with real values
UPDATE booking_requests
SET customer_token_hash = '{new_hash}', updated_at = now()
WHERE id = '{booking_id}';Then send the magic link manually: https://inklee.app/request/{raw_token}
Note: The token is 32 random bytes hex-encoded. The hash is SHA-256 of the raw token.
- Go to
https://inklee.app/forgot-password - Enter the artist's email — a reset link will be sent
- If the email is not arriving, check Resend logs at resend.com/emails
- If the email domain is bouncing, fix in Resend → Domains and retry
- If the artist has a recovery code: go to
https://inklee.app/login, then/auth/mfa, then "Use a recovery code" - If all recovery codes are lost: go to Supabase Dashboard → Authentication → Users, find the user, and use the admin panel to disable MFA (unenroll the TOTP factor)
- After regaining access, the artist should re-enable 2FA from Settings → Account
- User accounts cannot be restored via the dashboard once deleted
- If detected within 7 days: use PITR to restore the auth.users row and the profiles row
- Advise the artist to re-sign-up with the same email if PITR is not feasible — bookings are linked by artist_id so historical data cannot be reconnected automatically
Unreconciled deposits (deposit_pending, due date >7 days past, not paid) are flagged automatically in:
- Admin dashboard (
/admin) → Booking integrity section - audit_log — rows with
action = 'deposit_unreconciled'written by the daily cleanup cron
Manual action:
- Open the booking in the dashboard
- Contact the customer to confirm payment status
- If paid outside Stripe: click "Mark deposit received" manually
- If abandoned: reject the booking to free the slot
If the server log shows:
[stripe] WARNING: test-mode key detected in production environment
- Log into Stripe Dashboard
- Switch to Live mode
- Get the live-mode
sk_live_*secret key andpk_live_*publishable key - Update in Vercel: Project Settings → Environment Variables
STRIPE_SECRET_KEY→sk_live_*NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY→pk_live_*
- Create a new webhook endpoint in Stripe Live mode pointing to
https://inklee.app/api/stripe/webhook - Update
STRIPE_WEBHOOK_SECRETin Vercel with the live-mode webhook signing secret - Redeploy