@umituz/react-native-subscription 2.27.65 → 2.27.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/package.json +3 -1
  2. package/src/domains/credits/application/CreditLimitCalculator.ts +17 -0
  3. package/src/domains/credits/application/CreditsInitializer.ts +85 -0
  4. package/src/domains/credits/application/DeductCreditsCommand.ts +52 -0
  5. package/src/domains/credits/application/PurchaseMetadataGenerator.ts +59 -0
  6. package/src/domains/credits/application/credit-strategies/CreditAllocationContext.ts +35 -0
  7. package/src/domains/credits/application/credit-strategies/ICreditStrategy.ts +18 -0
  8. package/src/domains/credits/application/credit-strategies/StandardPurchaseCreditStrategy.ts +16 -0
  9. package/src/domains/credits/application/credit-strategies/SyncCreditStrategy.ts +15 -0
  10. package/src/domains/credits/application/credit-strategies/TrialCreditStrategy.ts +18 -0
  11. package/src/{infrastructure/mappers → domains/credits/core}/CreditsMapper.ts +4 -4
  12. package/src/domains/credits/infrastructure/CreditsRepository.ts +102 -0
  13. package/src/{presentation/hooks → domains/credits/presentation}/useCredits.ts +21 -4
  14. package/src/domains/subscription/application/SubscriptionAuthListener.ts +26 -0
  15. package/src/domains/subscription/application/SubscriptionInitializer.ts +77 -0
  16. package/src/{infrastructure/services → domains/subscription/application}/SubscriptionInitializerTypes.ts +21 -1
  17. package/src/domains/subscription/application/SubscriptionSyncService.ts +71 -0
  18. package/src/domains/subscription/application/SubscriptionSyncUtils.ts +16 -0
  19. package/src/{revenuecat/domain/value-objects → domains/subscription/core}/RevenueCatConfig.ts +1 -1
  20. package/src/{domain/types → domains/subscription/core}/RevenueCatData.ts +1 -1
  21. package/src/{domain/entities → domains/subscription/core}/SubscriptionStatus.ts +13 -21
  22. package/src/domains/subscription/core/SubscriptionStatusHandlers.ts +51 -0
  23. package/src/domains/subscription/infrastructure/handlers/PackageHandler.ts +67 -0
  24. package/src/domains/subscription/infrastructure/handlers/PurchaseStatusResolver.ts +27 -0
  25. package/src/domains/subscription/infrastructure/managers/SubscriptionInternalState.ts +12 -0
  26. package/src/domains/subscription/infrastructure/managers/SubscriptionManager.ts +110 -0
  27. package/src/{presentation/hooks → domains/subscription/presentation}/usePremium.ts +7 -4
  28. package/src/domains/trial/application/TrialEligibilityService.ts +25 -0
  29. package/src/domains/trial/application/TrialService.ts +68 -0
  30. package/src/{infrastructure/services → domains/trial/core}/TrialTypes.ts +1 -1
  31. package/src/domains/trial/infrastructure/DeviceTrialRepository.ts +30 -0
  32. package/src/presentation/components/details/PremiumStatusBadge.tsx +2 -2
  33. package/src/presentation/hooks/index.ts +11 -11
  34. package/src/shared/infrastructure/SubscriptionEventBus.ts +51 -0
  35. package/src/utils/packageTypeDetector.ts +13 -18
  36. package/src/application/README.md +0 -50
  37. package/src/domain/entities/README.md +0 -50
  38. package/src/domain/entities/SubscriptionStatus.test.ts +0 -105
  39. package/src/domain/errors/README.md +0 -53
  40. package/src/domain/value-objects/README.md +0 -50
  41. package/src/infrastructure/README.md +0 -55
  42. package/src/infrastructure/mappers/README.md +0 -21
  43. package/src/infrastructure/models/README.md +0 -26
  44. package/src/infrastructure/repositories/CreditsRepository.ts +0 -132
  45. package/src/infrastructure/repositories/README.md +0 -99
  46. package/src/infrastructure/services/CreditsInitializer.ts +0 -170
  47. package/src/infrastructure/services/README.md +0 -99
  48. package/src/infrastructure/services/SubscriptionInitializer.ts +0 -176
  49. package/src/infrastructure/services/SubscriptionService.ts +0 -133
  50. package/src/infrastructure/services/TrialService.ts +0 -197
  51. package/src/infrastructure/services/app-service-helpers.ts +0 -111
  52. package/src/revenuecat/README.md +0 -104
  53. package/src/revenuecat/application/README.md +0 -43
  54. package/src/revenuecat/application/ports/IRevenueCatService.ts +0 -76
  55. package/src/revenuecat/application/ports/README.md +0 -41
  56. package/src/revenuecat/domain/README.md +0 -48
  57. package/src/revenuecat/domain/constants/README.md +0 -41
  58. package/src/revenuecat/domain/entities/README.md +0 -42
  59. package/src/revenuecat/domain/errors/README.md +0 -53
  60. package/src/revenuecat/domain/types/README.md +0 -41
  61. package/src/revenuecat/domain/value-objects/README.md +0 -41
  62. package/src/revenuecat/index.ts +0 -13
  63. package/src/revenuecat/infrastructure/handlers/PackageHandler.ts +0 -161
  64. package/src/revenuecat/infrastructure/managers/SubscriptionManager.ts +0 -165
  65. package/src/revenuecat/presentation/README.md +0 -42
  66. /package/src/{domain/entities → domains/credits/core}/Credits.ts +0 -0
  67. /package/src/{infrastructure/models → domains/credits/core}/UserCreditsDocument.ts +0 -0
  68. /package/src/{infrastructure/repositories → domains/credits/infrastructure}/CreditsRepositoryProvider.ts +0 -0
  69. /package/src/{presentation/hooks → domains/credits/presentation}/useDeductCredit.ts +0 -0
  70. /package/src/{revenuecat/domain/constants → domains/subscription/core}/RevenueCatConstants.ts +0 -0
  71. /package/src/{revenuecat/domain/errors → domains/subscription/core}/RevenueCatError.ts +0 -0
  72. /package/src/{revenuecat/domain/types → domains/subscription/core}/RevenueCatTypes.ts +0 -0
  73. /package/src/{domain/entities → domains/subscription/core}/SubscriptionConstants.ts +0 -0
  74. /package/src/{revenuecat → domains/subscription}/infrastructure/README.md +0 -0
  75. /package/src/{revenuecat → domains/subscription}/infrastructure/config/README.md +0 -0
  76. /package/src/{revenuecat → domains/subscription}/infrastructure/handlers/README.md +0 -0
  77. /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/README.md +0 -0
  78. /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/subscriptionQueryKeys.ts +0 -0
  79. /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/useCustomerInfo.ts +0 -0
  80. /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/useInitializeSubscription.ts +0 -0
  81. /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/usePaywallFlow.ts +0 -0
  82. /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/usePurchasePackage.ts +0 -0
  83. /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/useRestorePurchase.ts +0 -0
  84. /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/useRevenueCat.ts +0 -0
  85. /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/useRevenueCatTrialEligibility.ts +0 -0
  86. /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/useSubscriptionPackages.ts +0 -0
  87. /package/src/{revenuecat/presentation → domains/subscription/infrastructure}/hooks/useSubscriptionQueries.ts +0 -0
  88. /package/src/{revenuecat → domains/subscription}/infrastructure/managers/README.md +0 -0
  89. /package/src/{revenuecat → domains/subscription}/infrastructure/services/CustomerInfoListenerManager.ts +0 -0
  90. /package/src/{revenuecat → domains/subscription}/infrastructure/services/OfferingsFetcher.ts +0 -0
  91. /package/src/{revenuecat → domains/subscription}/infrastructure/services/PurchaseHandler.ts +0 -0
  92. /package/src/{revenuecat → domains/subscription}/infrastructure/services/README.md +0 -0
  93. /package/src/{revenuecat → domains/subscription}/infrastructure/services/RestoreHandler.ts +0 -0
  94. /package/src/{revenuecat → domains/subscription}/infrastructure/services/RevenueCatInitializer.ts +0 -0
  95. /package/src/{revenuecat → domains/subscription}/infrastructure/services/RevenueCatService.ts +0 -0
  96. /package/src/{revenuecat → domains/subscription}/infrastructure/services/ServiceStateManager.ts +0 -0
  97. /package/src/{revenuecat → domains/subscription}/infrastructure/utils/ApiKeyResolver.ts +0 -0
  98. /package/src/{revenuecat → domains/subscription}/infrastructure/utils/InitializationCache.ts +0 -0
  99. /package/src/{revenuecat → domains/subscription}/infrastructure/utils/PremiumStatusSyncer.ts +0 -0
  100. /package/src/{revenuecat → domains/subscription}/infrastructure/utils/README.md +0 -0
  101. /package/src/{revenuecat → domains/subscription}/infrastructure/utils/RenewalDetector.ts +0 -0
  102. /package/src/{revenuecat → domains/subscription}/infrastructure/utils/UserIdProvider.ts +0 -0
  103. /package/src/{presentation/hooks → domains/subscription/presentation}/useAuthAwarePurchase.ts +0 -0
  104. /package/src/{presentation/hooks → domains/subscription/presentation}/useAuthSubscriptionSync.ts +0 -0
  105. /package/src/{presentation/hooks → domains/subscription/presentation}/useFeatureGate.ts +0 -0
  106. /package/src/{presentation/hooks → domains/subscription/presentation}/usePaywallVisibility.ts +0 -0
  107. /package/src/{presentation/hooks → domains/subscription/presentation}/usePremiumGate.ts +0 -0
  108. /package/src/{presentation/hooks → domains/subscription/presentation}/useSavedPurchaseAutoExecution.ts +0 -0
  109. /package/src/{presentation/hooks → domains/subscription/presentation}/useSubscriptionSettingsConfig.ts +0 -0
  110. /package/src/{presentation/hooks → domains/subscription/presentation}/useSubscriptionSettingsConfig.utils.ts +0 -0
  111. /package/src/{presentation/hooks → domains/subscription/presentation}/useSubscriptionStatus.ts +0 -0
  112. /package/src/{infrastructure/services → shared/application}/ActivationHandler.ts +0 -0
  113. /package/src/{infrastructure/services → shared/application}/FeedbackService.ts +0 -0
  114. /package/src/{application → shared/application}/ports/ISubscriptionRepository.ts +0 -0
  115. /package/src/{application → shared/application}/ports/ISubscriptionService.ts +0 -0
  116. /package/src/{application → shared/application}/ports/README.md +0 -0
  117. /package/src/{domain/errors → shared/utils}/InsufficientCreditsError.ts +0 -0
  118. /package/src/{infrastructure → shared}/utils/Logger.ts +0 -0
  119. /package/src/{domain/value-objects → shared/utils}/Result.ts +0 -0
  120. /package/src/{domain/value-objects → shared/utils}/SubscriptionConfig.ts +0 -0
  121. /package/src/{domain/errors → shared/utils}/SubscriptionError.ts +0 -0
@@ -1,197 +0,0 @@
1
- /**
2
- * Trial Service - Device-based trial tracking to prevent abuse
3
- */
4
-
5
- import { doc, getDoc, setDoc, serverTimestamp, arrayUnion } from "firebase/firestore";
6
- import { getFirestore } from "@umituz/react-native-firebase";
7
- import { PersistentDeviceIdService } from "@umituz/react-native-design-system";
8
- import type { TrialEligibilityResult } from "./TrialTypes";
9
-
10
- export { TRIAL_CONFIG, type DeviceTrialRecord, type TrialEligibilityResult } from "./TrialTypes";
11
-
12
- const DEVICE_TRIALS_COLLECTION = "device_trials";
13
-
14
- /** Get persistent device ID */
15
- export async function getDeviceId(): Promise<string> {
16
- return PersistentDeviceIdService.getDeviceId();
17
- }
18
-
19
- /** Check if device is eligible for trial */
20
- export async function checkTrialEligibility(deviceId?: string): Promise<TrialEligibilityResult> {
21
- try {
22
- const effectiveDeviceId = deviceId || await getDeviceId();
23
- const db = getFirestore();
24
-
25
- if (!db) {
26
- if (__DEV__) {
27
- console.log("[TrialService] No Firestore instance");
28
- }
29
- return { eligible: true, deviceId: effectiveDeviceId };
30
- }
31
-
32
- const trialRef = doc(db, DEVICE_TRIALS_COLLECTION, effectiveDeviceId);
33
- const trialDoc = await getDoc(trialRef);
34
-
35
- if (!trialDoc.exists()) {
36
- if (__DEV__) {
37
- console.log("[TrialService] No trial record found, eligible");
38
- }
39
- return { eligible: true, deviceId: effectiveDeviceId };
40
- }
41
-
42
- const data = trialDoc.data();
43
- const hasUsedTrial = data?.hasUsedTrial === true;
44
- const trialInProgress = data?.trialInProgress === true;
45
-
46
- if (__DEV__) {
47
- console.log("[TrialService] Trial record found:", {
48
- deviceId: effectiveDeviceId.slice(0, 8),
49
- hasUsedTrial,
50
- trialInProgress,
51
- });
52
- }
53
-
54
- // Not eligible if trial was already used (converted or ended)
55
- // OR if trial is currently in progress
56
- if (hasUsedTrial || trialInProgress) {
57
- return {
58
- eligible: false,
59
- reason: "already_used",
60
- deviceId: effectiveDeviceId,
61
- };
62
- }
63
-
64
- return { eligible: true, deviceId: effectiveDeviceId };
65
- } catch (error) {
66
- if (__DEV__) {
67
- console.error("[TrialService] Eligibility check error:", error);
68
- }
69
- return { eligible: false, reason: "error" };
70
- }
71
- }
72
-
73
- /** Record trial start for a device */
74
- export async function recordTrialStart(userId: string, deviceId?: string): Promise<boolean> {
75
- try {
76
- const effectiveDeviceId = deviceId || await getDeviceId();
77
- const db = getFirestore();
78
-
79
- if (!db) {
80
- if (__DEV__) {
81
- console.log("[TrialService] No Firestore instance");
82
- }
83
- return false;
84
- }
85
-
86
- const trialRef = doc(db, DEVICE_TRIALS_COLLECTION, effectiveDeviceId);
87
-
88
- await setDoc(
89
- trialRef,
90
- {
91
- deviceId: effectiveDeviceId,
92
- trialInProgress: true,
93
- trialStartedAt: serverTimestamp(),
94
- lastUserId: userId,
95
- userIds: arrayUnion(userId),
96
- updatedAt: serverTimestamp(),
97
- },
98
- { merge: true }
99
- );
100
-
101
- // Also set createdAt if it's a new record
102
- const existingDoc = await getDoc(trialRef);
103
- if (!existingDoc.data()?.createdAt) {
104
- await setDoc(
105
- trialRef,
106
- { createdAt: serverTimestamp() },
107
- { merge: true }
108
- );
109
- }
110
-
111
- if (__DEV__) {
112
- console.log("[TrialService] Trial recorded:", {
113
- deviceId: effectiveDeviceId.slice(0, 8),
114
- userId: userId.slice(0, 8),
115
- });
116
- }
117
-
118
- return true;
119
- } catch (error) {
120
- if (__DEV__) {
121
- console.error("[TrialService] Record trial error:", error);
122
- }
123
- return false;
124
- }
125
- }
126
-
127
- /**
128
- * Record trial end (cancelled or expired)
129
- */
130
- export async function recordTrialEnd(deviceId?: string): Promise<boolean> {
131
- try {
132
- const effectiveDeviceId = deviceId || await getDeviceId();
133
- const db = getFirestore();
134
-
135
- if (!db) return false;
136
-
137
- const trialRef = doc(db, DEVICE_TRIALS_COLLECTION, effectiveDeviceId);
138
-
139
- await setDoc(
140
- trialRef,
141
- {
142
- hasUsedTrial: true,
143
- trialInProgress: false,
144
- trialEndedAt: serverTimestamp(),
145
- updatedAt: serverTimestamp(),
146
- },
147
- { merge: true }
148
- );
149
-
150
- if (__DEV__) {
151
- console.log("[TrialService] Trial end recorded - trial now consumed");
152
- }
153
-
154
- return true;
155
- } catch (error) {
156
- if (__DEV__) {
157
- console.error("[TrialService] Record trial end error:", error);
158
- }
159
- return false;
160
- }
161
- }
162
-
163
- /**
164
- * Record trial conversion to paid subscription
165
- */
166
- export async function recordTrialConversion(deviceId?: string): Promise<boolean> {
167
- try {
168
- const effectiveDeviceId = deviceId || await getDeviceId();
169
- const db = getFirestore();
170
-
171
- if (!db) return false;
172
-
173
- const trialRef = doc(db, DEVICE_TRIALS_COLLECTION, effectiveDeviceId);
174
-
175
- await setDoc(
176
- trialRef,
177
- {
178
- hasUsedTrial: true,
179
- trialInProgress: false,
180
- trialConvertedAt: serverTimestamp(),
181
- updatedAt: serverTimestamp(),
182
- },
183
- { merge: true }
184
- );
185
-
186
- if (__DEV__) {
187
- console.log("[TrialService] Trial conversion recorded - user converted to paid");
188
- }
189
-
190
- return true;
191
- } catch (error) {
192
- if (__DEV__) {
193
- console.error("[TrialService] Record conversion error:", error);
194
- }
195
- return false;
196
- }
197
- }
@@ -1,111 +0,0 @@
1
- /**
2
- * App Service Helpers
3
- * Creates ready-to-use service implementations for configureAppServices
4
- */
5
-
6
- import { getCreditsRepository } from "../repositories/CreditsRepositoryProvider";
7
- import { getRevenueCatService } from "../../revenuecat/infrastructure/services/RevenueCatService";
8
- import { getPremiumEntitlement } from "../../revenuecat/domain/types/RevenueCatTypes";
9
- import { creditsQueryKeys } from "../../presentation/hooks/useCredits";
10
- import { paywallControl } from "../../presentation/hooks/usePaywallVisibility";
11
- import {
12
- getGlobalQueryClient,
13
- hasGlobalQueryClient,
14
- } from "@umituz/react-native-design-system";
15
- import {
16
- useAuthStore,
17
- selectUserId,
18
- } from "@umituz/react-native-auth";
19
-
20
- export interface CreditServiceConfig {
21
- entitlementId: string;
22
- }
23
-
24
- export interface ICreditService {
25
- checkCredits: (cost: number) => Promise<boolean>;
26
- deductCredits: (cost: number) => Promise<void>;
27
- refundCredits: (amount: number, error?: unknown) => Promise<void>;
28
- calculateCost: (capability: string, metadata?: Record<string, unknown>) => number;
29
- }
30
-
31
- export interface IPaywallService {
32
- showPaywall: (requiredCredits: number) => void;
33
- }
34
-
35
- const checkPremiumStatus = async (entitlementId: string): Promise<boolean> => {
36
- try {
37
- const rcService = getRevenueCatService();
38
- if (!rcService) return false;
39
-
40
- const customerInfo = await rcService.getCustomerInfo();
41
- if (!customerInfo) return false;
42
-
43
- return !!getPremiumEntitlement(customerInfo, entitlementId);
44
- } catch {
45
- return false;
46
- }
47
- };
48
-
49
- /**
50
- * Creates a credit service implementation
51
- */
52
- export function createCreditService(config: CreditServiceConfig): ICreditService {
53
- const { entitlementId } = config;
54
-
55
- return {
56
- checkCredits: async (cost: number): Promise<boolean> => {
57
- const userId = selectUserId(useAuthStore.getState());
58
- if (!userId) return false;
59
-
60
- // Premium users bypass credit check
61
- if (await checkPremiumStatus(entitlementId)) return true;
62
-
63
- try {
64
- const repository = getCreditsRepository();
65
- const result = await repository.getCredits(userId);
66
- if (!result.success || !result.data) return false;
67
- return (result.data.credits ?? 0) >= cost;
68
- } catch {
69
- return false;
70
- }
71
- },
72
-
73
- deductCredits: async (cost: number): Promise<void> => {
74
- const userId = selectUserId(useAuthStore.getState());
75
- if (!userId) return;
76
-
77
- // Premium users don't consume credits
78
- if (await checkPremiumStatus(entitlementId)) return;
79
-
80
- try {
81
- const repository = getCreditsRepository();
82
- await repository.deductCredit(userId, cost);
83
-
84
- if (hasGlobalQueryClient()) {
85
- getGlobalQueryClient().invalidateQueries({
86
- queryKey: creditsQueryKeys.user(userId),
87
- });
88
- }
89
- } catch (error) {
90
- if (typeof __DEV__ !== "undefined" && __DEV__) {
91
- console.error("[CreditService] Deduct error:", error);
92
- }
93
- }
94
- },
95
-
96
- refundCredits: async (): Promise<void> => {
97
- // No-op for now
98
- },
99
-
100
- calculateCost: (): number => 1,
101
- };
102
- }
103
-
104
- /**
105
- * Creates a paywall service implementation
106
- */
107
- export function createPaywallService(): IPaywallService {
108
- return {
109
- showPaywall: () => paywallControl.open(),
110
- };
111
- }
@@ -1,104 +0,0 @@
1
- # RevenueCat Integration
2
-
3
- Comprehensive integration and API wrapper for subscription management with RevenueCat.
4
-
5
- ## Location
6
-
7
- - **Base Path**: `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-subscription/src/revenuecat/`
8
- - **Domain**: `src/revenuecat/domain/`
9
- - **Infrastructure**: `src/revenuecat/infrastructure/`
10
- - **Presentation**: `src/revenuecat/presentation/`
11
-
12
- ## Strategy
13
-
14
- ### RevenueCat SDK Integration
15
-
16
- Seamless RevenueCat SDK initialization and configuration.
17
-
18
- - **Automatic Initialization**: SDK startup and configuration
19
- - **User ID Management**: Auth system integration
20
- - **Purchase Flow**: Managed purchase operations
21
- - **Restore Operations**: Purchase restoration support
22
- - **Error Handling**: RevenueCat error management
23
-
24
- ### Hook Architecture
25
-
26
- React hooks for RevenueCat functionality.
27
-
28
- - **useRevenueCat**: Core RevenueCat access
29
- - **useCustomerInfo**: Subscription information tracking
30
- - **useInitializeSubscription**: Initialization status monitoring
31
- - **useSubscriptionPackages**: Package listing and selection
32
- - **usePaywallFlow**: Complete paywall flow management
33
- - **useRestorePurchase**: Purchase restoration
34
-
35
- ### State Management
36
-
37
- Customer info and subscription state tracking.
38
-
39
- - **Customer Info Tracking**: Real-time subscription updates
40
- - **Offerings Management**: Package offering configuration
41
- - **Purchase State**: Purchase operation states
42
- - **Error States**: Comprehensive error handling
43
-
44
- ### User ID Synchronization
45
-
46
- Auth system integration for user management.
47
-
48
- - **Auth Sync**: Automatic user ID synchronization
49
- - **Login/Logout**: User ID management on auth changes
50
- - **Anonymous Users**: Anonymous user support
51
- - **Migration**: User migration support
52
-
53
- ## Restrictions
54
-
55
- ### REQUIRED
56
-
57
- - **Initialization**: Must initialize before any operations
58
- - **User ID Sync**: Sync user IDs with auth system
59
- - **Error Handling**: All operations must handle errors
60
- - **Loading States**: Show appropriate loading indicators
61
-
62
- ### PROHIBITED
63
-
64
- - **Direct SDK Calls**: Use hooks instead of direct RevenueCat calls
65
- - **Missing User IDs**: Operations require valid user IDs
66
- - **Uninitialized Access**: Don't call methods before initialization
67
- - **Ignoring Errors**: All errors must be handled
68
-
69
- ### CRITICAL
70
-
71
- - **API Key Security**: Never expose API keys in client code
72
- - **User ID Consistency**: Maintain consistent user IDs
73
- - **Purchase Validation**: Validate all purchase results
74
- - **Entitlement Check**: Always verify entitlements
75
-
76
- ## AI Agent Guidelines
77
-
78
- ### When Modifying RevenueCat Integration
79
-
80
- 1. **SDK Version**: Check RevenueCat SDK version compatibility
81
- 2. **Type Definitions**: Update TypeScript types
82
- 3. **Error Handling**: Maintain comprehensive error handling
83
- 4. **Testing**: Test with different subscription states
84
-
85
- ### When Adding New Hooks
86
-
87
- 1. **Hook Pattern**: Follow existing hook patterns
88
- 2. **State Management**: Proper state management
89
- 3. **Error Handling**: Comprehensive error handling
90
- 4. **Documentation**: Document hook usage and return values
91
-
92
- ### When Fixing RevenueCat Bugs
93
-
94
- 1. **SDK Integration**: Check RevenueCat SDK integration
95
- 2. **State Updates**: Verify state update mechanisms
96
- 3. **User ID**: Verify user ID consistency
97
- 4. **Purchase Flow**: Test complete purchase flows
98
-
99
- ## Related Documentation
100
-
101
- - [Paywall Domain](/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-subscription/src/domains/paywall/README.md)
102
- - [Config Domain](/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-subscription/src/domains/config/README.md)
103
- - [Infrastructure Layer](/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-subscription/src/infrastructure/README.md)
104
- - [Application Layer](/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-subscription/src/application/README.md)
@@ -1,43 +0,0 @@
1
- # RevenueCat Application Layer
2
-
3
- ## Location
4
- Application layer for RevenueCat integration, containing use cases and orchestration logic.
5
-
6
- ## Strategy
7
- This directory contains use cases and application-level operations for managing RevenueCat subscriptions and purchases with proper error handling and state synchronization.
8
-
9
- ## Restrictions
10
-
11
- ### REQUIRED
12
- - Must handle RevenueCat errors gracefully
13
- - Must provide user ID when available
14
- - Must use entitlements instead of product IDs
15
- - Must keep local state synchronized
16
-
17
- ### PROHIBITED
18
- - DO NOT ignore RevenueCat errors
19
- - DO NOT skip user ID provision
20
- - DO NOT use product IDs directly
21
- - DO NOT allow state desynchronization
22
-
23
- ### CRITICAL SAFETY
24
- - All errors MUST be handled gracefully
25
- - User IDs MUST be provided when available
26
- - Entitlements MUST be used for flexibility
27
- - Local state MUST stay synchronized
28
-
29
- ## AI Agent Guidelines
30
- 1. Always handle RevenueCat errors with proper recovery
31
- 2. Provide user ID when available for better tracking
32
- 3. Use entitlements instead of product IDs for flexibility
33
- 4. Check if offerings are available before purchasing
34
- 5. Validate customer info after purchases
35
- 6. Keep local state synchronized with RevenueCat
36
- 7. Handle network timeouts appropriately
37
- 8. Log all RevenueCat operations for debugging
38
-
39
- ## Related Documentation
40
- - [RevenueCat Integration](../README.md)
41
- - [RevenueCat Domain](../domain/README.md)
42
- - [RevenueCat Infrastructure](../infrastructure/README.md)
43
- - [Application Ports](./ports/README.md)
@@ -1,76 +0,0 @@
1
- /**
2
- * RevenueCat Service Interface
3
- * Port for subscription operations
4
- */
5
-
6
- import type { PurchasesPackage, PurchasesOffering, CustomerInfo } from "react-native-purchases";
7
-
8
- export interface InitializeResult {
9
- success: boolean;
10
- offering: PurchasesOffering | null;
11
- isPremium: boolean;
12
- }
13
-
14
- export interface PurchaseResult {
15
- success: boolean;
16
- isPremium: boolean;
17
- customerInfo?: CustomerInfo;
18
- isConsumable?: boolean;
19
- productId?: string;
20
- }
21
-
22
- export interface RestoreResult {
23
- success: boolean;
24
- isPremium: boolean;
25
- customerInfo?: CustomerInfo;
26
- }
27
-
28
- export interface IRevenueCatService {
29
- /**
30
- * Initialize RevenueCat SDK
31
- * @param userId User identifier
32
- * @param apiKey Optional API key (auto-resolved if not provided)
33
- */
34
- initialize(userId: string, apiKey?: string): Promise<InitializeResult>;
35
-
36
- /**
37
- * Fetch offerings from RevenueCat
38
- */
39
- fetchOfferings(): Promise<PurchasesOffering | null>;
40
-
41
- /**
42
- * Purchase a package
43
- */
44
- purchasePackage(pkg: PurchasesPackage, userId: string): Promise<PurchaseResult>;
45
-
46
- /**
47
- * Restore purchases
48
- */
49
- restorePurchases(userId: string): Promise<RestoreResult>;
50
-
51
- /**
52
- * Reset RevenueCat SDK (for logout)
53
- */
54
- reset(): Promise<void>;
55
-
56
- /**
57
- * Get current customer info
58
- */
59
- getCustomerInfo(): Promise<CustomerInfo | null>;
60
-
61
- /**
62
- * Get RevenueCat API key for current platform
63
- */
64
- getRevenueCatKey(): string | null;
65
-
66
- /**
67
- * Check if RevenueCat is initialized
68
- */
69
- isInitialized(): boolean;
70
-
71
- /**
72
- * Get current user ID
73
- */
74
- getCurrentUserId(): string | null;
75
- }
76
-
@@ -1,41 +0,0 @@
1
- # RevenueCat Application Ports
2
-
3
- ## Location
4
- Interface definitions for RevenueCat service layer.
5
-
6
- ## Strategy
7
- This directory defines the ports (interfaces) that the RevenueCat infrastructure must implement, following the Dependency Inversion Principle for testability and flexibility.
8
-
9
- ## Restrictions
10
-
11
- ### REQUIRED
12
- - Must define clear interfaces for all operations
13
- - Must support mocking for testing
14
- - Must enable implementation swapping
15
- - Must maintain contracts between layers
16
-
17
- ### PROHIBITED
18
- - DO NOT depend on concrete implementations
19
- - DO NOT create interfaces without clear purpose
20
- - DO NOT break interface contracts
21
- - DO NOT couple application to infrastructure
22
-
23
- ### CRITICAL SAFETY
24
- - All dependencies MUST be inverted
25
- - Interfaces MUST be clearly defined
26
- - Implementations MUST be swappable
27
- - Contracts MUST be maintained
28
-
29
- ## AI Agent Guidelines
30
- 1. Define clear interfaces for all RevenueCat operations
31
- 2. Design interfaces for easy mocking in tests
32
- 3. Enable implementation swapping when needed
33
- 4. Keep application layer decoupled from infrastructure
34
- 5. Maintain clear contracts between layers
35
- 6. Document interface behavior thoroughly
36
- 7. Test with mock implementations
37
-
38
- ## Related Documentation
39
- - [RevenueCat Application Layer](../README.md)
40
- - [RevenueCat Infrastructure](../infrastructure/README.md)
41
- - [RevenueCat Domain](../domain/README.md)
@@ -1,48 +0,0 @@
1
- # RevenueCat Domain
2
-
3
- Domain entities and types for RevenueCat integration.
4
-
5
- ## Location
6
-
7
- `src/revenuecat/domain/`
8
-
9
- ## Strategy
10
-
11
- Domain-specific entities representing RevenueCat concepts like entitlements, offerings, and packages, with proper type mapping and validation.
12
-
13
- ## Restrictions
14
-
15
- ### REQUIRED
16
-
17
- - MUST map RevenueCat types to domain types
18
- - MUST handle optional properties safely (null safety)
19
- - MUST validate RevenueCat data
20
- - MUST format prices and dates consistently
21
- - MUST use constants for identifiers
22
-
23
- ### PROHIBITED
24
-
25
- - MUST NOT expose RevenueCat implementation details to other layers
26
- - MUST NOT leak RevenueCat SDK types outside this module
27
- - MUST NOT assume all properties are present (null safety)
28
-
29
- ### CRITICAL
30
-
31
- - Always validate RevenueCat data before use
32
- - Handle all optional properties safely
33
- - Use constants for all identifiers
34
- - Maintain consistent formatting for prices and dates
35
-
36
- ## AI Agent Guidelines
37
-
38
- When working with RevenueCat domain:
39
- 1. Type Mapping - map RevenueCat types to domain types
40
- 2. Null Safety - handle optional properties safely
41
- 3. Validation - validate RevenueCat data
42
- 4. Formatting - format prices and dates consistently
43
- 5. Constants - use constants for identifiers
44
-
45
- ## Related Documentation
46
-
47
- - [RevenueCat README](../README.md)
48
- - [Subscription Manager](../../infrastructure/managers/README.md)
@@ -1,41 +0,0 @@
1
- # RevenueCat Domain Constants
2
-
3
- ## Location
4
- Constants used throughout the RevenueCat integration.
5
-
6
- ## Strategy
7
- This directory contains constant definitions for RevenueCat-specific values including entitlement IDs, error codes, and configuration defaults for maintainability and consistency.
8
-
9
- ## Restrictions
10
-
11
- ### REQUIRED
12
- - Must use constants for all RevenueCat-specific values
13
- - Must provide clear constant names
14
- - Must maintain consistency across codebase
15
- - Must document constant purposes
16
-
17
- ### PROHIBITED
18
- - DO NOT use magic strings or numbers
19
- - DO NOT duplicate constant definitions
20
- - DO NOT use hardcoded values
21
- - DO NOT create ambiguous constants
22
-
23
- ### CRITICAL SAFETY
24
- - All RevenueCat-specific values MUST use constants
25
- - Constants MUST be clearly named and documented
26
- - Constant values MUST be consistent
27
- - Entitlement IDs MUST match RevenueCat dashboard
28
-
29
- ## AI Agent Guidelines
30
- 1. Use constants for all RevenueCat-specific values
31
- 2. Provide clear, descriptive constant names
32
- 3. Maintain consistency across the codebase
33
- 4. Document the purpose of each constant
34
- 5. Organize constants by category (entitlements, offerings, errors)
35
- 6. Validate constants match RevenueCat dashboard configuration
36
- 7. Avoid magic strings and numbers throughout code
37
-
38
- ## Related Documentation
39
- - [RevenueCat Domain](../README.md)
40
- - [RevenueCat Errors](../errors/README.md)
41
- - [RevenueCat Entities](../entities/README.md)