feat(paycraft): production hardening — RLS/IDOR fixes, realtime, per-platform trials, SDK paywall + RevenueCat-style overview - #156
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (55)
📝 WalkthroughWalkthroughThe PR updates PayCraft SDK state handling and loading UI, adds multi-app dashboard onboarding and analytics, introduces platform-specific trials and live provider synchronization, stores provider account labels, updates the sample and documentation, and hardens webhook and database access controls. ChangesPayCraft platform and SDK
Dashboard workflows
Products and security
Estimated code review effort: 5 (Critical) | ~120 minutes Sequence Diagram(s)sequenceDiagram
participant ProductSyncPanel
participant SyncStatusDialog
participant ProductSyncRoute
participant SyncOrchestrator
participant SupabaseRealtime
ProductSyncPanel->>SyncStatusDialog: Open synchronization run
SyncStatusDialog->>SupabaseRealtime: Subscribe to sync_events
SyncStatusDialog->>ProductSyncRoute: Start provider synchronization
ProductSyncRoute->>SyncOrchestrator: Run providers with run ID
SyncOrchestrator->>SupabaseRealtime: Emit provider progress events
SupabaseRealtime-->>SyncStatusDialog: Deliver progress events
SyncOrchestrator->>SupabaseRealtime: Emit run_done event
sequenceDiagram
participant NewAppPage
participant AppsApi
participant OnboardingSetup
participant TenantSwitch
NewAppPage->>AppsApi: Load owned apps and provider metadata
NewAppPage->>OnboardingSetup: Create app with selected providers
OnboardingSetup->>OnboardingSetup: Create or reuse tenant and seed products
OnboardingSetup-->>NewAppPage: Return tenant and provisioning results
NewAppPage->>TenantSwitch: Switch to resulting tenant
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…wnership_guards.sql
…cpay-webhook/index.ts supabase/functions/flutterwave-webhook/index.ts
…telabs/paycraft/PayCraft.kt cmp-paycraft/src/commonMain/kotlin/com/mobilebytelabs/paycraft/core/PayCraftBillingManager.kt cmp-paycraft/src/commonMain/kotlin/com/mobilebytelabs/paycraft/network/PayCraftRealtime.kt
… dashboard/app/api/onboarding/setup/
…e.ts dashboard/app/api/products/[id]/sync/route.ts
…telabs/paycraft/PayCraft.kt dashboard/app/(dashboard)/apps/new/page.tsx dashboard/app/(marketing)/docs/page.tsx
…telabs/paycraft/PayCraft.kt sample/
…hboard/app/api/apps/route.ts
…hboard/app/api/apps/route.ts
…hboard/app/api/onboarding/setup/route.ts
…ge.tsx dashboard/app/(dashboard)/providers/stripe/page.tsx dashboard/app/api/apps/route.ts
…telabs/paycraft/ui/PayCraftPaywallComposable.kt cmp-paycraft/src/commonMain/kotlin/com/mobilebytelabs/paycraft/ui/PayCraftPremiumBanner.kt cmp-paycraft/src/commonTest/kotlin/com/mobilebytelabs/paycraft/ui/PayCraftPremiumBannerTest.kt
…shboard/app/api/products/[id]/sync/route.ts dashboard/app/api/products/sync-to-providers/route.ts
…shboard/components/dashboard/apps-matrix.tsx dashboard/components/sidebar.tsx
…cmp-paycraft/src/commonMain/kotlin/com/mobilebytelabs/paycraft/core/PayCraftBillingManager.kt
…telabs/paycraft/ui/PayCraftPremiumBannerTest.kt
baa839f
into
MobileByteLabs:dev
Summary
Production-readiness pass on the PayCraft platform (KMP SDK + Next.js dashboard + Supabase): closes cross-tenant data leaks and IDOR holes, makes webhooks fail-closed, ships realtime + per-platform trials end-to-end, fixes the SDK paywall loading state, and adds an account-wide app-matrix overview to the dashboard.
Changes
Security & data isolation (Supabase)
subscriptionscross-tenant leak;security_invoker+ REVOKE anon on the 5 analytics views; tenant-admin SELECT RLS onsubscriptions/webhook_logs; RLS on matviews + rate-limit table.auth.uid()admin check, backend allowed) ontenant_products_upsert/_delete+tenant_pricing_upsert/_bulk_upsert(closes product/pricing IDOR).sync_events+ guardedsync_event_emit(drives the live sync dialog).tenant_providers_set_account_label— non-secret per-provider account label.trial_per_platformJSONB + upsert threading + backfill (per-platform trials).Trials — per-platform + store sync
:deactivate) + App Store intro offer (delete); iOS durations map exactly to Apple's enum; macOS = universal purchase.SDK (cmp-paycraft)
/configproducts load (not just whilebillingState==Loading) — fixes the blank/no-shimmer cold-start window;PayCraftPremiumBanneris now premium-aware (shimmer while loading, collapse when premium).Mutex),refreshStatus(force), public headless accessors (billingManager,plans); Kotlin 2.4.0 + Compose 1.11.0 + coroutines 1.11.0 + Kermit 2.1.0.Dashboard — RevenueCat-style account overview
/dashboardis now the account landing: a metric hero of clickable cards (MRR · Active subs · Active trials · New subs) each with a sparkline + period delta + a 28D/3M/12M range selector driving a big area chart; the time-series is computed from realsubscriptionsrows (created_at / trial_* / status), never synthesized. Below: per-app matrix (click → switches active-app context via/api/apps/switchand opens the app), MRR-by-app breakdown, and account-wide activity. Sidebar "Home" → "Overview"./api/onboarding/setup— getUser auth, IP rate-limit, own-tenant provider inheritance); provider account labels + Google-Play SA-email auto-extract; live sync-status dialog with per-provider human messages; add-app "reuse existing providers" with per-provider checkboxes.Infra / docs
@tailwindcss/typography; marketing footer/docs pages; referencesample/app (both SDK modes); gradle catalog bump.Notable files
supabase/migrations/082-087_*.sqldashboard/lib/{stripe-route-helper,googleplay-product-sync,appstore-product-sync}.tsdashboard/app/(dashboard)/dashboard/page.tsx·dashboard/components/dashboard/{overview-metrics,apps-matrix}.tsx·dashboard/components/charts/apps-comparison-chart.tsx·dashboard/components/products/{product-form,sync-status-dialog}.tsxcmp-paycraft/.../ui/{PayCraftPaywallComposable,PayCraftPremiumBanner}.ktSummary by CodeRabbit
New Features
Bug Fixes