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
@@ -108,6 +108,23 @@ export class SubscriptionType implements Partial<Subscription> {
@Field(() => Date)
updatedAt!: Date;
// read-only fields for display purpose
// provider: 'stripe' | 'revenuecat'
@Field(() => String, {
nullable: true,
description:
'Payment provider of this subscription. Read-only. One of: stripe | revenuecat',
})
provider?: string | null;
// iapStore: 'app_store' | 'play_store' | null when provider is stripe
@Field(() => String, {
nullable: true,
description:
'If provider is revenuecat, indicates underlying store. Read-only. One of: app_store | play_store',
})
iapStore?: string | null;
// deprecated fields
@Field(() => String, {
name: 'id',