feat: sync rcat data (#13628)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* RevenueCat support: public webhook endpoint, webhook handler/service,
nightly reconciliation and per-user sync; subscriptions now expose
provider and iapStore; new user-facing error for App Store/Play-managed
subscriptions.
* **Chores**
* Multi-provider subscription schema (Provider, IapStore); Stripe
credentials moved into payment.stripe (top-level apiKey/webhookKey
deprecated); new payment.revenuecat config and defaults added.
* **Tests**
  * Comprehensive RevenueCat integration test suite and snapshots.
* **Documentation**
  * Admin config descriptions updated with deprecation guidance.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
DarkSky
2025-09-23 16:52:23 +08:00
committed by GitHub
parent 75a6c79b2c
commit 762b702e46
31 changed files with 2059 additions and 33 deletions

View File

@@ -749,6 +749,16 @@ model Subscription {
stripeSubscriptionId String? @unique @map("stripe_subscription_id")
// stripe schedule id
stripeScheduleId String? @map("stripe_schedule_id") @db.VarChar
// subscription provider: stripe or revenuecat
provider Provider @default(stripe)
// iap store for revenuecat subscriptions
iapStore IapStore? @map("iap_store")
// revenuecat entitlement name like "Pro" / "AI"
rcEntitlement String? @map("rc_entitlement") @db.VarChar
// revenuecat product id like "app.affine.pro.Annual"
rcProductId String? @map("rc_product_id") @db.VarChar
// external reference, appstore originalTransactionId or play purchaseToken
rcExternalRef String? @map("rc_external_ref") @db.VarChar
// subscription.status, active/past_due/canceled/unpaid...
status String @db.VarChar(20)
// subscription.current_period_start
@@ -770,6 +780,16 @@ model Subscription {
@@map("subscriptions")
}
enum Provider {
stripe
revenuecat
}
enum IapStore {
app_store
play_store
}
model Invoice {
stripeInvoiceId String @id @map("stripe_invoice_id")
targetId String @map("target_id") @db.VarChar