Qa/onboarding auth gates#48
Open
aimerdoux wants to merge 8 commits into
Open
Conversation
…ation endpoints The wavex-os-server has no global auth hook; every route self-gates. Four mutating onboarding/control-plane endpoints had no assertBoard gate, making them callable by any unauthenticated client that can reach the port: - POST /api/system/pull-and-restart (git pull --ff-only + pnpm install + restart on REPO_ROOT — remote code-pull / RCE-adjacent) - POST /api/system/restart-processes (launchctl kickstart — control-plane DoS) - POST /api/system/discard-local-changes (git stash wipes working tree) - PUT /api/inference-allocation (swarm_pct=100 zeros Pool-A, strands the onboarding wizard a new customer is in front of) Adds the same assertBoard(authReq(req)) gate already used by activate.ts. In WAVEX_AUTH_MODE=dev the gate is a no-op (synthetic local board actor), so Mission Control and the onboarding wizard are unaffected; in production it requires a board actor. Verified: tsc --noEmit exit 0; 18/19 wavex-os-server test files green. The e2e-onboarding failures are pre-existing on main (no inference backend in sandbox) and unrelated to this change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…n flow Wires the full payment path that was missing and causing every booking_intent to auto-cancel before payment could complete (root cause from WAVAAAA-1194). Migration (20260603000002): - wavex_os.booking_intents staging table with status enum: pending | pending_payment | confirmed | cancelled - wavex_os_set_booking_intent_pending_payment() — freezes the 30-min cancel clock as soon as the user is redirected to Stripe - wavex_os_confirm_booking_intent() — atomic confirm + public.bookings insert, idempotent on replay - wavex_os_cancel_stale_booking_intents() — only cancels 'pending' (not 'pending_payment') intents older than N minutes - Additive columns on public.bookings: booking_intent_id FK, experience_id, experience_name, stripe_checkout_session_id, stripe_payment_intent_id Edge function create-booking-checkout-session: - Auth-gated POST: loads intent, creates Stripe checkout.session (mode:payment), calls set_pending_payment RPC, returns redirect URL - Reuses existing Stripe customer lookup/create pattern - Reuses existing Deno + STRIPE_SECRET_KEY_TEST_ENV env convention Edge function wavex-os-booking-webhook (--no-verify-jwt): - Handles checkout.session.completed: confirm intent via RPC, emit booking_confirmed Telegram event via wavex_os_emit_booking_confirmed_for_user - Handles checkout.session.expired: revert pending_payment → pending so stale-cancel clock can fire - Idempotency via existing wavex_os_record_webhook_event RPC - Signing secret: WAVEX_OS_BOOKING_WEBHOOK_SECRET (isolated from subscription webhook) Server job booking-intent-cleanup: - Runs every 5 min, calls wavex_os_cancel_stale_booking_intents with WAVEX_BOOKING_INTENT_TIMEOUT_MINUTES (default 30) - Wired into registerWavexOsRoutes alongside reengagement scheduler Co-Authored-By: Paperclip <noreply@paperclip.ing>
…ut function
wavex_os schema is not in the PostgREST exposed schema list, so
.schema("wavex_os").from("booking_intents") silently returned
intent_not_found on every call. All other wavex_os data access in
this codebase goes through public-schema security-definer RPCs;
this fix follows that pattern.
Added wavex_os_get_booking_intent(p_intent_id uuid) RPC and updated
create-booking-checkout-session edge function to call it instead.
Verified: smoke-test booking intent created, function returned
cs_test_* Stripe checkout URL, intent transitioned to pending_payment.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
…gram job (WAVAAAA-1197) Adds infrastructure to identify and re-notify users whose booking_intents were auto-cancelled before the Stripe checkout flow existed (bfeff1f). - Migration 20260603000003: wavex_os.abandoned_booking_recovery_nudges table (unique on intent_id to prevent double-sends), plus wavex_os_list_abandoned_booking_candidates() RPC (resolves chat_id from telegram_events, excludes already-confirmed users and already-nudged intents) and wavex_os_record_abandoned_booking_nudge() RPC. - Job abandoned-booking-recovery.ts: one-shot at server startup, defaults WAVEX_ABANDONED_BOOKING_DRY_RUN=true — logs recoverable count without sending. Set to "false" after CEO approval to activate live sends. - index.ts: wire one-shot fire-and-forget call at boot. Co-Authored-By: Paperclip <noreply@paperclip.ing>
Public-schema security-definer wrapper so the Telegram bot can create rows
in wavex_os.booking_intents via PostgREST (wavex_os schema not exposed).
Follows the same pattern as wavex_os_confirm_booking_intent.
Returns {id} for immediate use in create-booking-checkout-session.
Part of WAVAAAA-1203: wire Telegram bot to booking_intents + Stripe checkout.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Set WAVEX_ABANDONED_BOOKING_DRY_RUN=false (live sends enabled) - Set WAVEX_BOOKING_URL=https://t.me/TheGeniexbot?start=booking - Add POST /api/booking/recovery/run board-only route (idempotent re-trigger) - Register route in server index Job runs on next server startup and sends recovery Telegram messages to ~50 users with cancelled booking_intents who have a known chat_id. Idempotent: nudge log unique(intent_id) prevents double-sends. Closes WAVAAAA-1200 pending first booking_confirmed event. Co-Authored-By: Paperclip <noreply@paperclip.ing>
…DEFINER RPCs The wavex_os schema is intentionally not exposed via PostgREST (consistent with all other wavex_os tables). The POST /api/auth-events route was using direct REST calls with schema-qualified paths which silently 404'd — no auth events were ever persisted. Fix: four new SECURITY DEFINER RPCs in the public schema - wavex_os_record_auth_event (upsert, service_role) - wavex_os_get_unfired_auth_events (backfill read, service_role) - wavex_os_mark_auth_event_fired (backfill write, service_role) - wavex_os_count_campaign_signups (count endpoint, service_role) Migration 20260603000005 applied to the linked Supabase project. tools/backfill-resend-audience.mjs: dry-run verifies 0 unfired rows (expected — no events persisted before this fix). Live backfill runs once RESEND_API_KEY + RESEND_AUDIENCE_ID are in ~/.wavex-os/state/.env. Co-Authored-By: Paperclip <noreply@paperclip.ing>
…y sites The onboarding Pillar-1 URL fetch only followed HTTP redirects, so sites using a <meta http-equiv="refresh"> hop (e.g. parked domains, some real sites) returned an empty shell — the model then guessed the company from the domain name. Now: - follow ONE meta-refresh hop (resolve relative target, re-fetch); - mark pages with < 120 chars of readable text as FETCH FAILED (parked, empty, or JS-rendered) instead of feeding near-empty content to the model; - detect common parking-page fingerprints (IONOS/GoDaddy/Sedo/"defaultsite"/ "coming soon"/etc.) and fail them so the model says it couldn't read the site rather than inventing one. Verified live: apple.com → 820 chars real content; a parked IONOS domain → COULD_NOT_READ_SITE end-to-end through the Realtime onboarding worker. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.