Skip to content

feat(paycraft): production hardening — RLS/IDOR fixes, realtime, per-platform trials, SDK paywall + RevenueCat-style overview - #156

Merged
mobilebytesenseicommunity merged 21 commits into
MobileByteLabs:devfrom
therajanmaurya:session-PayCraft-20260824174141684
Aug 26, 2026
Merged

feat(paycraft): production hardening — RLS/IDOR fixes, realtime, per-platform trials, SDK paywall + RevenueCat-style overview#156
mobilebytesenseicommunity merged 21 commits into
MobileByteLabs:devfrom
therajanmaurya:session-PayCraft-20260824174141684

Conversation

@therajanmaurya

@therajanmaurya therajanmaurya commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

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)

  • 082 RLS hardening — closed a LIVE anon-readable subscriptions cross-tenant leak; security_invoker + REVOKE anon on the 5 analytics views; tenant-admin SELECT RLS on subscriptions/webhook_logs; RLS on matviews + rate-limit table.
  • 083 / 084 — tenant-ownership guards (auth.uid() admin check, backend allowed) on tenant_products_upsert/_delete + tenant_pricing_upsert/_bulk_upsert (closes product/pricing IDOR).
  • 085 sync_events + guarded sync_event_emit (drives the live sync dialog).
  • 086 tenant_providers_set_account_label — non-secret per-provider account label.
  • 087 trial_per_platform JSONB + upsert threading + backfill (per-platform trials).
  • 7 provider webhooks (midtrans/paddle/paypal/paystack/flutterwave/btcpay/lemonsqueezy) flipped fail-open → fail-closed (missing secret → 500, bad sig → 401).

Trials — per-platform + store sync

  • Product form: single trial input → master toggle + per-platform preset dropdowns (Android/iOS/Web/Desktop); web & desktop share the web-checkout trial.
  • Sync resolves each provider's own platform value; disable now tears down the Play free-trial offer (:deactivate) + App Store intro offer (delete); iOS durations map exactly to Apple's enum; macOS = universal purchase.

SDK (cmp-paycraft)

  • Paywall shows the skeleton until /config products load (not just while billingState==Loading) — fixes the blank/no-shimmer cold-start window; PayCraftPremiumBanner is now premium-aware (shimmer while loading, collapse when premium).
  • Realtime identity races fixed (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

  • /dashboard is 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 real subscriptions rows (created_at / trial_* / status), never synthesized. Below: per-app matrix (click → switches active-app context via /api/apps/switch and opens the app), MRR-by-app breakdown, and account-wide activity. Sidebar "Home" → "Overview".
  • Secured full-flow onboarding API (/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

  • docs-site → Cloudflare Workers Static Assets; @tailwindcss/typography; marketing footer/docs pages; reference sample/ app (both SDK modes); gradle catalog bump.

Notable files

  • supabase/migrations/082-087_*.sql
  • dashboard/lib/{stripe-route-helper,googleplay-product-sync,appstore-product-sync}.ts
  • dashboard/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}.tsx
  • cmp-paycraft/.../ui/{PayCraftPaywallComposable,PayCraftPremiumBanner}.kt

Summary by CodeRabbit

  • New Features

    • Added an account-wide dashboard with app comparisons, revenue, subscriber metrics, charts, and recent activity.
    • Added provider reuse during app creation and optional account labels for payment integrations.
    • Added platform-specific trial settings and live product-sync progress.
    • Added SDK integration documentation and a Kotlin Multiplatform sample app.
    • Added public access to billing plans and billing manager state for headless integrations.
  • Bug Fixes

    • Improved paywall loading states and premium banner behavior.
    • Improved realtime billing updates and subscription synchronization.
    • Webhook verification now rejects missing security configuration instead of bypassing validation.
    • Improved cleanup of disabled trial offers across supported stores.

@coderabbitai

coderabbitai Bot commented Aug 24, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 55542313-5712-4bab-a589-9d783297dd02

📥 Commits

Reviewing files that changed from the base of the PR and between 22a9275 and a912364.

📒 Files selected for processing (55)
  • .gitignore
  • build.gradle.kts
  • cmp-paycraft/build.gradle.kts
  • cmp-paycraft/src/commonMain/kotlin/com/mobilebytelabs/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
  • cmp-paycraft/src/commonMain/kotlin/com/mobilebytelabs/paycraft/presentation/PaywallTemplate.kt
  • cmp-paycraft/src/commonMain/kotlin/com/mobilebytelabs/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
  • dashboard/app/(dashboard)/apps/new/page.tsx
  • dashboard/app/(dashboard)/dashboard/page.tsx
  • dashboard/app/(dashboard)/providers/razorpay/page.tsx
  • dashboard/app/(dashboard)/providers/stripe/page.tsx
  • dashboard/app/(marketing)/docs/page.tsx
  • dashboard/app/(marketing)/docs/sdk-integration/page.tsx
  • dashboard/app/api/apps/route.ts
  • dashboard/app/api/onboarding/provision/route.ts
  • dashboard/app/api/onboarding/setup/route.ts
  • dashboard/app/api/products/[id]/route.ts
  • dashboard/app/api/products/[id]/sync/route.ts
  • dashboard/app/api/products/sync-to-providers/route.ts
  • dashboard/app/api/providers/app-store/keys/route.ts
  • dashboard/app/api/providers/cashfree/keys/route.ts
  • dashboard/app/api/providers/google-play/keys/route.ts
  • dashboard/app/api/providers/razorpay/keys/route.ts
  • dashboard/app/api/providers/stripe/keys/route.ts
  • dashboard/components/charts/apps-comparison-chart.tsx
  • dashboard/components/dashboard/apps-matrix.tsx
  • dashboard/components/dashboard/overview-metrics.tsx
  • dashboard/components/products/product-form.tsx
  • dashboard/components/products/product-sync-panel.tsx
  • dashboard/components/products/sync-status-dialog.tsx
  • dashboard/components/providers/app-store-keys-form.tsx
  • dashboard/components/providers/cashfree-keys-form.tsx
  • dashboard/components/providers/google-play-keys-form.tsx
  • dashboard/components/sidebar.tsx
  • dashboard/lib/appstore-product-sync.ts
  • dashboard/lib/googleplay-product-sync.ts
  • dashboard/lib/stripe-route-helper.ts
  • docs-site/wrangler.toml
  • gradle/libs.versions.toml
  • sample/README.md
  • sample/SampleApp.kt
  • supabase/functions/btcpay-webhook/index.ts
  • supabase/functions/flutterwave-webhook/index.ts
  • supabase/functions/lemonsqueezy-webhook/index.ts
  • supabase/functions/midtrans-webhook/index.ts
  • supabase/functions/paddle-webhook/index.ts
  • supabase/functions/paypal-webhook/index.ts
  • supabase/functions/paystack-webhook/index.ts
  • supabase/migrations/082_rls_security_hardening.sql
  • supabase/migrations/083_rpc_tenant_ownership_guards.sql
  • supabase/migrations/084_rpc_guard_allow_backend.sql
  • supabase/migrations/085_sync_events.sql

📝 Walkthrough

Walkthrough

The 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.

Changes

PayCraft platform and SDK

Layer / File(s) Summary
Platform, sample, and integration documentation
.gitignore, build.gradle.kts, cmp-paycraft/build.gradle.kts, gradle/libs.versions.toml, sample/*, dashboard/app/(marketing)/docs/*, docs-site/wrangler.toml
Build and deployment configuration changed. The sample demonstrates drop-in and headless integrations. SDK integration documentation was added.
SDK state, realtime, and loading UI
cmp-paycraft/src/commonMain/kotlin/com/mobilebytelabs/paycraft/..., cmp-paycraft/src/commonTest/kotlin/com/mobilebytelabs/paycraft/ui/PayCraftPremiumBannerTest.kt
PayCraft exposes billing access and plans, refreshes realtime identity after account changes, serializes channel state, and renders loading-aware paywall and premium-banner states. Tests cover loading, free, premium, and null-manager states.

Dashboard workflows

Layer / File(s) Summary
App onboarding and provider account metadata
dashboard/app/(dashboard)/apps/new/page.tsx, dashboard/app/api/apps/route.ts, dashboard/app/api/onboarding/*, dashboard/app/api/providers/*, dashboard/app/(dashboard)/providers/*
App creation can reuse selected provider connections. Onboarding authentication is revalidated. Provider metadata and optional account labels are stored and returned without exposing secrets.
Cross-application dashboard overview
dashboard/app/(dashboard)/dashboard/page.tsx, dashboard/components/dashboard/*, dashboard/components/charts/*, dashboard/components/sidebar.tsx
The dashboard now aggregates account-level metrics, subscription history, app status, recent activity, MRR comparisons, and app matrix data. App switching and Overview navigation were added.

Products and security

Layer / File(s) Summary
Platform trials and live provider synchronization
dashboard/components/products/*, dashboard/app/api/products/*, dashboard/lib/*product-sync.ts, dashboard/lib/stripe-route-helper.ts, supabase/migrations/085_sync_events.sql
Products support platform-specific trials. Provider synchronization uses shared run IDs, emits realtime progress events, and cleans up disabled trial offers.
Webhook, database, and RPC security controls
supabase/functions/*-webhook/index.ts, supabase/migrations/082_*.sql, supabase/migrations/083_*.sql, supabase/migrations/084_*.sql
Webhook handlers fail closed when secrets or signatures are missing. Database views and tables receive tighter access policies. Product and pricing RPCs enforce tenant ownership while allowing trusted backend calls.

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
Loading
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
Loading
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…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
…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
…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
@therajanmaurya therajanmaurya changed the title Production Ready Product feat(paycraft): production hardening — RLS/IDOR fixes, realtime, per-platform trials, SDK paywall + account overview Aug 25, 2026
…shboard/components/dashboard/apps-matrix.tsx dashboard/components/sidebar.tsx
@therajanmaurya therajanmaurya changed the title feat(paycraft): production hardening — RLS/IDOR fixes, realtime, per-platform trials, SDK paywall + account overview feat(paycraft): production hardening — RLS/IDOR fixes, realtime, per-platform trials, SDK paywall + RevenueCat-style overview Aug 25, 2026
…cmp-paycraft/src/commonMain/kotlin/com/mobilebytelabs/paycraft/core/PayCraftBillingManager.kt
…telabs/paycraft/ui/PayCraftPremiumBannerTest.kt
@therajanmaurya
therajanmaurya marked this pull request as ready for review August 26, 2026 03:06
@mobilebytesenseicommunity
mobilebytesenseicommunity merged commit baa839f into MobileByteLabs:dev Aug 26, 2026
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants