mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-14 08:36:22 +08:00
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:
@@ -30,6 +30,9 @@ export interface Subscription {
|
||||
trialEnd: Date | null;
|
||||
nextBillAt: Date | null;
|
||||
canceledAt: Date | null;
|
||||
// read-only metadata for IAP integration
|
||||
provider?: string | null;
|
||||
iapStore?: string | null;
|
||||
}
|
||||
|
||||
export interface Invoice {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { randomUUID } from 'node:crypto';
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { PrismaClient, UserStripeCustomer } from '@prisma/client';
|
||||
import { pick } from 'lodash-es';
|
||||
import { PrismaClient, Provider, UserStripeCustomer } from '@prisma/client';
|
||||
import { omit, pick } from 'lodash-es';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { SubscriptionPlanNotFound, URLHelper } from '../../../base';
|
||||
@@ -132,8 +132,9 @@ export class SelfhostTeamSubscriptionManager extends SubscriptionManager {
|
||||
const [subscription] = await this.db.$transaction([
|
||||
this.db.subscription.create({
|
||||
data: {
|
||||
provider: Provider.stripe,
|
||||
targetId: key,
|
||||
...subscriptionData,
|
||||
...omit(subscriptionData, 'provider', 'iapStore'),
|
||||
},
|
||||
}),
|
||||
this.db.license.create({
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
EventBus,
|
||||
InternalServerError,
|
||||
InvalidCheckoutParameters,
|
||||
ManagedByAppStoreOrPlay,
|
||||
Mutex,
|
||||
OnEvent,
|
||||
SubscriptionAlreadyExists,
|
||||
@@ -103,6 +104,14 @@ export class UserSubscriptionManager extends SubscriptionManager {
|
||||
throw new InvalidCheckoutParameters();
|
||||
}
|
||||
|
||||
const active = await this.getActiveSubscription({
|
||||
plan: lookupKey.plan,
|
||||
userId: user.id,
|
||||
});
|
||||
if (active?.provider === 'revenuecat') {
|
||||
throw new ManagedByAppStoreOrPlay();
|
||||
}
|
||||
|
||||
const subscription = await this.getSubscription({
|
||||
plan: lookupKey.plan,
|
||||
userId: user.id,
|
||||
@@ -256,7 +265,7 @@ export class UserSubscriptionManager extends SubscriptionManager {
|
||||
]),
|
||||
create: {
|
||||
targetId: userId,
|
||||
...subscriptionData,
|
||||
...omit(subscriptionData, ['provider', 'iapStore']),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { PrismaClient, UserStripeCustomer } from '@prisma/client';
|
||||
import { PrismaClient, Provider, UserStripeCustomer } from '@prisma/client';
|
||||
import { omit, pick } from 'lodash-es';
|
||||
import { z } from 'zod';
|
||||
|
||||
@@ -157,6 +157,7 @@ export class WorkspaceSubscriptionManager extends SubscriptionManager {
|
||||
|
||||
return this.db.subscription.upsert({
|
||||
where: {
|
||||
provider: Provider.stripe,
|
||||
stripeSubscriptionId: stripeSubscription.id,
|
||||
},
|
||||
update: {
|
||||
@@ -171,7 +172,7 @@ export class WorkspaceSubscriptionManager extends SubscriptionManager {
|
||||
},
|
||||
create: {
|
||||
targetId: workspaceId,
|
||||
...subscriptionData,
|
||||
...omit(subscriptionData, 'provider', 'iapStore'),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user