@umituz/react-native-subscription 2.14.99 → 2.14.101

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 (98) hide show
  1. package/README.md +211 -394
  2. package/package.json +3 -3
  3. package/src/application/README.md +46 -225
  4. package/src/application/ports/README.md +42 -97
  5. package/src/domain/README.md +36 -384
  6. package/src/domain/constants/README.md +0 -56
  7. package/src/domain/entities/README.md +43 -169
  8. package/src/domain/entities/SubscriptionStatus.ts +1 -1
  9. package/src/domain/errors/README.md +33 -287
  10. package/src/domain/value-objects/README.md +43 -179
  11. package/src/domains/README.md +50 -238
  12. package/src/domains/README.md.bak +274 -0
  13. package/src/domains/config/README.md +93 -383
  14. package/src/domains/config/domain/README.md +23 -376
  15. package/src/domains/config/domain/entities/README.md +34 -343
  16. package/src/domains/paywall/README.md +99 -369
  17. package/src/domains/paywall/components/README.md +34 -178
  18. package/src/domains/paywall/entities/README.md +34 -193
  19. package/src/domains/paywall/hooks/README.md +34 -122
  20. package/src/domains/wallet/README.md +34 -275
  21. package/src/domains/wallet/README.md.bak +209 -0
  22. package/src/domains/wallet/domain/README.md +34 -101
  23. package/src/domains/wallet/domain/entities/README.md +34 -115
  24. package/src/domains/wallet/domain/errors/README.md +34 -151
  25. package/src/domains/wallet/infrastructure/README.md +34 -89
  26. package/src/domains/wallet/presentation/components/README.md +34 -224
  27. package/src/domains/wallet/presentation/components/TransactionItem.tsx +1 -1
  28. package/src/domains/wallet/presentation/hooks/README.md +34 -248
  29. package/src/infrastructure/README.md +37 -496
  30. package/src/infrastructure/mappers/README.md +0 -13
  31. package/src/infrastructure/repositories/README.md +74 -360
  32. package/src/infrastructure/services/ActivationHandler.ts +1 -1
  33. package/src/infrastructure/services/README.md +95 -370
  34. package/src/infrastructure/services/SubscriptionService.ts +1 -1
  35. package/src/presentation/README.md +123 -408
  36. package/src/presentation/README.md.bak +172 -0
  37. package/src/presentation/components/README.md +151 -179
  38. package/src/presentation/components/README.md.bak +217 -0
  39. package/src/presentation/components/details/CreditRow.md +65 -310
  40. package/src/presentation/components/details/DetailRow.md +63 -255
  41. package/src/presentation/components/details/PremiumDetailsCard.md +65 -238
  42. package/src/presentation/components/details/PremiumStatusBadge.md +64 -239
  43. package/src/presentation/components/details/README.md +97 -447
  44. package/src/presentation/components/feedback/PaywallFeedbackModal.md +63 -287
  45. package/src/presentation/components/feedback/README.md +97 -445
  46. package/src/presentation/components/paywall/PaywallModal.md +66 -416
  47. package/src/presentation/components/paywall/README.md +50 -186
  48. package/src/presentation/components/sections/README.md +97 -466
  49. package/src/presentation/components/sections/SubscriptionSection.md +92 -244
  50. package/src/presentation/hooks/README.md +154 -741
  51. package/src/presentation/hooks/useAuthAwarePurchase.md +58 -325
  52. package/src/presentation/hooks/useAuthGate.md +61 -375
  53. package/src/presentation/hooks/useAuthSubscriptionSync.md +66 -370
  54. package/src/presentation/hooks/useCreditChecker.md +73 -378
  55. package/src/presentation/hooks/useCredits.md +74 -313
  56. package/src/presentation/hooks/useCredits.md.bak +231 -0
  57. package/src/presentation/hooks/useCreditsGate.md +66 -318
  58. package/src/presentation/hooks/useDeductCredit.md +0 -76
  59. package/src/presentation/hooks/useDeductCredit.ts +1 -1
  60. package/src/presentation/hooks/useDevTestCallbacks.md +63 -394
  61. package/src/presentation/hooks/useFeatureGate.md +105 -150
  62. package/src/presentation/hooks/useFeatureGate.md.bak +284 -0
  63. package/src/presentation/hooks/useInitializeCredits.md +64 -430
  64. package/src/presentation/hooks/usePaywall.md +61 -306
  65. package/src/presentation/hooks/usePaywallOperations.md +64 -458
  66. package/src/presentation/hooks/usePaywallVisibility.md +67 -316
  67. package/src/presentation/hooks/usePremium.md +84 -226
  68. package/src/presentation/hooks/usePremiumGate.md +60 -395
  69. package/src/presentation/hooks/usePremiumWithCredits.md +64 -401
  70. package/src/presentation/hooks/useSubscription.md +66 -422
  71. package/src/presentation/hooks/useSubscriptionDetails.md +65 -410
  72. package/src/presentation/hooks/useSubscriptionGate.md +80 -164
  73. package/src/presentation/hooks/useSubscriptionSettingsConfig.md +66 -346
  74. package/src/presentation/hooks/useSubscriptionStatus.md +66 -396
  75. package/src/presentation/hooks/useUserTier.md +63 -328
  76. package/src/presentation/hooks/useUserTierWithRepository.md +64 -424
  77. package/src/presentation/screens/README.md +48 -190
  78. package/src/presentation/types/README.md +0 -16
  79. package/src/presentation/utils/README.md +0 -21
  80. package/src/presentation/utils/subscriptionDateUtils.ts +1 -1
  81. package/src/revenuecat/README.md +99 -518
  82. package/src/revenuecat/application/README.md +35 -150
  83. package/src/revenuecat/application/ports/README.md +34 -162
  84. package/src/revenuecat/domain/README.md +42 -141
  85. package/src/revenuecat/domain/constants/README.md +34 -176
  86. package/src/revenuecat/domain/entities/README.md +34 -374
  87. package/src/revenuecat/domain/errors/README.md +47 -191
  88. package/src/revenuecat/domain/types/README.md +34 -366
  89. package/src/revenuecat/domain/value-objects/README.md +34 -434
  90. package/src/revenuecat/infrastructure/README.md +34 -43
  91. package/src/revenuecat/infrastructure/config/README.md +32 -23
  92. package/src/revenuecat/infrastructure/handlers/README.md +34 -211
  93. package/src/revenuecat/infrastructure/managers/README.md +34 -42
  94. package/src/revenuecat/infrastructure/services/README.md +35 -318
  95. package/src/revenuecat/infrastructure/utils/README.md +34 -375
  96. package/src/revenuecat/presentation/README.md +34 -176
  97. package/src/revenuecat/presentation/hooks/README.md +29 -35
  98. package/src/utils/README.md +38 -525
@@ -1,218 +1,41 @@
1
1
  # RevenueCat Infrastructure Handlers
2
2
 
3
+ ## Location
3
4
  Event handlers for RevenueCat lifecycle events.
4
5
 
5
- ## Overview
6
-
7
- This directory contains handler implementations for managing RevenueCat events including purchase callbacks, customer info changes, and error handling.
8
-
9
- ## Handlers
10
-
11
- ### PurchaseCompletedHandler
12
-
13
- Handles successful purchase completion.
14
-
15
- ```typescript
16
- class PurchaseCompletedHandler {
17
- async handle(result: PurchaseResult): Promise<void> {
18
- // 1. Extract transaction info
19
- const { customerInfo, transaction } = result;
20
-
21
- // 2. Update local subscription status
22
- await updateSubscriptionStatus(customerInfo);
23
-
24
- // 3. Handle credits allocation
25
- if (isPremiumPurchase(transaction)) {
26
- await allocatePremiumCredits(customerInfo.originalAppUserId);
27
- }
28
-
29
- // 4. Trigger success callbacks
30
- triggerSuccessCallbacks(result);
31
-
32
- // 5. Log purchase
33
- logPurchaseEvent(transaction);
34
- }
35
- }
36
- ```
37
-
38
- ### PurchaseErrorHandler
39
-
40
- Handles purchase errors.
41
-
42
- ```typescript
43
- class PurchaseErrorHandler {
44
- async handle(error: PurchasesError): Promise<void> {
45
- // 1. Categorize error
46
- const category = categorizeError(error);
47
-
48
- // 2. Show appropriate message
49
- showErrorMessage(category);
50
-
51
- // 3. Log error
52
- logPurchaseError(error);
53
-
54
- // 4. Trigger error callbacks
55
- triggerErrorCallbacks(error);
56
-
57
- // 5. Offer recovery options
58
- if (category === 'network') {
59
- offerRetry();
60
- }
61
- }
62
- }
63
- ```
64
-
65
- ### CustomerInfoChangedHandler
66
-
67
- Handles customer info changes.
68
-
69
- ```typescript
70
- class CustomerInfoChangedHandler {
71
- async handle(customerInfo: CustomerInfo): Promise<void> {
72
- // 1. Check for subscription changes
73
- const changes = detectSubscriptionChanges(customerInfo);
74
-
75
- // 2. Update local state
76
- await updateLocalState(customerInfo);
77
-
78
- // 3. Handle status changes
79
- if (changes.subscriptionChanged) {
80
- await handleSubscriptionChange(changes);
81
- }
82
-
83
- // 4. Trigger UI refresh
84
- triggerUIRefresh();
85
- }
86
- }
87
- ```
88
-
89
- ### EntitlementsChangedHandler
90
-
91
- Handles entitlement changes.
92
-
93
- ```typescript
94
- class EntitlementsChangedHandler {
95
- async handle(entitlements: EntitlementInfos): Promise<void> {
96
- // 1. Check premium status
97
- const premium = entitlements.premium;
98
-
99
- // 2. Update access controls
100
- if (premium?.isActive) {
101
- grantPremiumAccess();
102
- } else {
103
- revokePremiumAccess();
104
- }
105
-
106
- // 3. Handle new entitlements
107
- for (const [key, entitlement] of Object.entries(entitlements)) {
108
- if (entitlement.isActive) {
109
- await handleNewEntitlement(key, entitlement);
110
- }
111
- }
112
- }
113
- }
114
- ```
115
-
116
- ## Usage
117
-
118
- ### Setting Up Handlers
119
-
120
- ```typescript
121
- import { Purchases } from '@revenuecat/purchases-capacitor';
122
- import {
123
- PurchaseCompletedHandler,
124
- PurchaseErrorHandler,
125
- CustomerInfoChangedHandler,
126
- } from './handlers';
127
-
128
- // Set up customer info listener
129
- Purchases.addCustomerInfoUpdateListener((customerInfo) => {
130
- const handler = new CustomerInfoChangedHandler();
131
- handler.handle(customerInfo);
132
- });
133
-
134
- // Use in purchase flow
135
- async function purchasePackage(pkg: Package) {
136
- const completedHandler = new PurchaseCompletedHandler();
137
- const errorHandler = new PurchaseErrorHandler();
138
-
139
- try {
140
- const result = await Purchases.purchasePackage({ aPackage: pkg });
141
- await completedHandler.handle(result);
142
- } catch (error) {
143
- await errorHandler.handle(error);
144
- }
145
- }
146
- ```
147
-
148
- ### Custom Handlers
149
-
150
- ```typescript
151
- class CustomPurchaseHandler {
152
- constructor(
153
- private onSuccess: (result: PurchaseResult) => void,
154
- private onError: (error: PurchasesError) => void
155
- ) {}
156
-
157
- async handle(result: PurchaseResult | PurchasesError): Promise<void> {
158
- if (isPurchasesError(result)) {
159
- await this.onError(result);
160
- } else {
161
- await this.onSuccess(result);
162
- }
163
- }
164
- }
165
-
166
- // Usage
167
- const handler = new CustomPurchaseHandler(
168
- (result) => {
169
- Alert.alert('Success', 'Purchase completed!');
170
- navigation.navigate('Home');
171
- },
172
- (error) => {
173
- Alert.alert('Error', error.message);
174
- }
175
- );
176
- ```
177
-
178
- ## Error Categorization
179
-
180
- ```typescript
181
- function categorizeError(error: PurchasesError): ErrorCategory {
182
- switch (error.code) {
183
- case 'PURCHASE_CANCELLED':
184
- return 'cancelled';
185
- case 'NETWORK_ERROR':
186
- return 'network';
187
- case 'INVALID_CREDENTIALS_ERROR':
188
- return 'config';
189
- case 'PRODUCT_NOT_AVAILABLE_FOR_PURCHASE':
190
- return 'availability';
191
- default:
192
- return 'unknown';
193
- }
194
- }
195
-
196
- type ErrorCategory =
197
- | 'cancelled'
198
- | 'network'
199
- | 'config'
200
- | 'availability'
201
- | 'unknown';
202
- ```
203
-
204
- ## Best Practices
205
-
206
- 1. **Immutability**: Don't mutate incoming data
207
- 2. **Error Boundaries**: Handle errors gracefully
208
- 3. **Logging**: Log all events for debugging
209
- 4. **Callbacks**: Invoke registered callbacks appropriately
210
- 5. **Async Handling**: Use async/await for asynchronous operations
211
- 6. **Validation**: Validate incoming data before processing
212
- 7. **Recovery**: Provide recovery options when possible
213
-
214
- ## Related
215
-
6
+ ## Strategy
7
+ This directory contains handler implementations for managing RevenueCat events including purchase callbacks, customer info changes, and error handling with proper data validation and recovery.
8
+
9
+ ## Restrictions
10
+
11
+ ### REQUIRED
12
+ - Must handle all events gracefully
13
+ - Must validate incoming data before processing
14
+ - Must log all events for debugging
15
+ - Must invoke callbacks appropriately
16
+
17
+ ### PROHIBITED
18
+ - DO NOT mutate incoming event data
19
+ - DO NOT ignore event handling errors
20
+ - DO NOT skip callback invocation
21
+ - DO NOT process unvalidated data
22
+
23
+ ### CRITICAL SAFETY
24
+ - All incoming data MUST be validated
25
+ - All events MUST be logged for debugging
26
+ - All callbacks MUST be invoked appropriately
27
+ - Recovery options MUST be provided when possible
28
+
29
+ ## AI Agent Guidelines
30
+ 1. Never mutate incoming event data
31
+ 2. Handle all errors gracefully with proper boundaries
32
+ 3. Log all events for debugging and monitoring
33
+ 4. Invoke registered callbacks appropriately
34
+ 5. Use async/await for asynchronous operations
35
+ 6. Validate all incoming data before processing
36
+ 7. Provide recovery options when possible
37
+
38
+ ## Related Documentation
216
39
  - [RevenueCat Infrastructure](../README.md)
217
40
  - [RevenueCat Services](../services/README.md)
218
41
  - [RevenueCat Errors](../../domain/errors/README.md)
@@ -1,49 +1,41 @@
1
1
  # RevenueCat Infrastructure Managers
2
2
 
3
+ ## Location
3
4
  Manager classes for coordinating RevenueCat operations.
4
5
 
5
- ## Overview
6
-
7
- This directory contains high-level manager classes that coordinate between different RevenueCat services and handle complex operations.
8
-
9
- ## Contents
10
-
11
- - **SubscriptionManager.ts** - Manages RevenueCat configuration and entitlement access
12
-
13
- ## SubscriptionManager
14
-
15
- Manages RevenueCat SDK configuration and provides access to entitlement IDs.
16
-
17
- ### Key Methods
18
-
19
- ```typescript
20
- class SubscriptionManager {
21
- static configure(config: RevenueCatConfig): void;
22
- static getEntitlementId(): string | null;
23
- static getOfferings(): Promise<Offerings>;
24
- }
25
- ```
26
-
27
- ### Usage
28
-
29
- ```typescript
30
- import { SubscriptionManager } from './managers/SubscriptionManager';
31
-
32
- // Configure at app startup
33
- SubscriptionManager.configure({
34
- apiKey: 'your_api_key',
35
- entitlementId: 'premium',
36
- });
37
-
38
- // Get entitlement ID
39
- const entitlementId = SubscriptionManager.getEntitlementId();
40
-
41
- // Get offerings
42
- const offerings = await SubscriptionManager.getOfferings();
43
- ```
44
-
45
- ## Related
46
-
6
+ ## Strategy
7
+ This directory contains high-level manager classes that coordinate between different RevenueCat services and handle complex operations like SDK configuration and entitlement access.
8
+
9
+ ## Restrictions
10
+
11
+ ### REQUIRED
12
+ - Must coordinate between services properly
13
+ - Must manage SDK configuration correctly
14
+ - Must provide access to entitlement IDs
15
+ - Must handle complex operations safely
16
+
17
+ ### PROHIBITED
18
+ - DO NOT bypass service coordination
19
+ - DO NOT misconfigure SDK
20
+ - DO NOT expose invalid entitlement IDs
21
+ - DO NOT oversimplify complex operations
22
+
23
+ ### CRITICAL SAFETY
24
+ - Service coordination MUST be correct
25
+ - SDK configuration MUST be valid
26
+ - Entitlement access MUST be safe
27
+ - Complex operations MUST be handled properly
28
+
29
+ ## AI Agent Guidelines
30
+ 1. Coordinate properly between RevenueCat services
31
+ 2. Manage SDK configuration with correct parameters
32
+ 3. Provide safe access to entitlement IDs
33
+ 4. Handle complex operations with proper error handling
34
+ 5. Test coordination logic thoroughly
35
+ 6. Document manager responsibilities clearly
36
+ 7. Maintain separation of concerns
37
+
38
+ ## Related Documentation
47
39
  - [Services](../services/README.md)
48
40
  - [Config](../config/README.md)
49
41
  - [Domain](../../domain/README.md)
@@ -1,325 +1,42 @@
1
1
  # RevenueCat Infrastructure Services
2
2
 
3
+ ## Location
3
4
  Service implementations for RevenueCat operations.
4
5
 
5
- ## Overview
6
-
7
- This directory contains concrete implementations of RevenueCat interfaces, providing the actual integration with the RevenueCat SDK.
8
-
9
- ## Services
10
-
11
- ### RevenueCatServiceImpl
12
-
13
- Main service implementation for RevenueCat operations.
14
-
15
- ```typescript
16
- import { Purchases } from '@revenuecat/purchases-capacitor';
17
- import type { IRevenueCatService } from '../../application/ports/IRevenueCatService';
18
-
19
- class RevenueCatServiceImpl implements IRevenueCatService {
20
- // Configuration
21
- async configure(params: {
22
- apiKey: string;
23
- userId?: string;
24
- observerMode?: boolean;
25
- }): Promise<void> {
26
- await Purchases.configure({
27
- apiKey: params.apiKey,
28
- appUserID: params.userId,
29
- observerMode: params.observerMode ?? false,
30
- });
31
- }
32
-
33
- // Purchasing
34
- async purchasePackage(pkg: Package): Promise<PurchaseResult> {
35
- return await Purchases.purchasePackage({ aPackage: pkg });
36
- }
37
-
38
- async purchaseProduct(productId: string): Promise<PurchaseResult> {
39
- return await Purchases.purchaseProduct({ productIdentifier: productId });
40
- }
41
-
42
- async restorePurchases(): Promise<RestoreResult> {
43
- return await Purchases.restorePurchases();
44
- }
45
-
46
- // Customer Information
47
- async getCustomerInfo(): Promise<CustomerInfo> {
48
- return await Purchases.getCustomerInfo();
49
- }
50
-
51
- async getCustomerInfoUserId(): Promise<string | null> {
52
- const info = await this.getCustomerInfo();
53
- return info.originalAppUserId;
54
- }
55
-
56
- // Offerings
57
- async getOfferings(): Promise<Offerings> {
58
- return await Purchases.getOfferings();
59
- }
60
-
61
- async getCurrentOffering(): Promise<Offering | null> {
62
- const offerings = await this.getOfferings();
63
- return offerings.current;
64
- }
65
-
66
- // Entitlements
67
- async checkEntitlement(entitlementId: string): Promise<boolean> {
68
- const info = await this.getCustomerInfo();
69
- return info.entitlements[entitlementId]?.isActive ?? false;
70
- }
71
-
72
- async checkEntitlementInfo(
73
- entitlementId: string
74
- ): Promise<EntitlementInfo | null> {
75
- const info = await this.getCustomerInfo();
76
- return info.entitlements[entitlementId] ?? null;
77
- }
78
-
79
- // Subscriber Attributes
80
- async setAttributes(attributes: SubscriberAttributes): Promise<void> {
81
- await Purchases.setAttributes(attributes);
82
- }
83
-
84
- async setEmail(email: string): Promise<void> {
85
- await Purchases.setEmail(email);
86
- }
87
-
88
- async setPhoneNumber(phoneNumber: string): Promise<void> {
89
- await Purchases.setPhoneNumber(phoneNumber);
90
- }
91
-
92
- // Log Out
93
- async logOut(): Promise<void> {
94
- await Purchases.logOut();
95
- }
96
- }
97
- ```
98
-
99
- ### RevenueCatServiceProvider
100
-
101
- Provides the RevenueCat service instance.
102
-
103
- ```typescript
104
- class RevenueCatServiceProvider {
105
- private static instance: IRevenueCatService | null = null;
106
-
107
- static getInstance(): IRevenueCatService {
108
- if (!this.instance) {
109
- this.instance = new RevenueCatServiceImpl();
110
- }
111
- return this.instance;
112
- }
113
-
114
- static configure(config: {
115
- apiKey: string;
116
- userId?: string;
117
- observerMode?: boolean;
118
- }): IRevenueCatService {
119
- const service = this.getInstance();
120
- service.configure(config);
121
- return service;
122
- }
123
- }
124
- ```
125
-
126
- ## Usage
127
-
128
- ### Initializing the Service
129
-
130
- ```typescript
131
- import { RevenueCatServiceProvider } from './services/RevenueCatServiceProvider';
132
-
133
- // Configure RevenueCat
134
- const service = RevenueCatServiceProvider.configure({
135
- apiKey: 'your_api_key',
136
- userId: user?.uid,
137
- observerMode: false,
138
- });
139
- ```
140
-
141
- ### Making Purchases
142
-
143
- ```typescript
144
- import { RevenueCatServiceProvider } from './services/RevenueCatServiceProvider';
145
-
146
- async function purchasePremium(userId: string) {
147
- const service = RevenueCatServiceProvider.getInstance();
148
-
149
- // Get offerings
150
- const offerings = await service.getOfferings();
151
- const monthlyPackage = offerings.current?.monthly;
152
-
153
- if (!monthlyPackage) {
154
- throw new Error('No package available');
155
- }
156
-
157
- // Purchase
158
- const result = await service.purchasePackage(monthlyPackage);
159
-
160
- if (result.error) {
161
- throw new Error(result.error.message);
162
- }
163
-
164
- // Check entitlement
165
- const hasPremium = await service.checkEntitlement('premium');
166
- if (hasPremium) {
167
- console.log('Premium activated!');
168
- }
169
-
170
- return result;
171
- }
172
- ```
173
-
174
- ### Restoring Purchases
175
-
176
- ```typescript
177
- async function restorePurchases() {
178
- const service = RevenueCatServiceProvider.getInstance();
179
-
180
- try {
181
- const result = await service.restorePurchases();
182
-
183
- if (result.error) {
184
- throw new Error(result.error.message);
185
- }
186
-
187
- // Update local state
188
- await updateSubscriptionStatus(result.customerInfo);
189
-
190
- return result.customerInfo;
191
- } catch (error) {
192
- console.error('Restore failed:', error);
193
- throw error;
194
- }
195
- }
196
- ```
197
-
198
- ### Checking Entitlements
199
-
200
- ```typescript
201
- async function checkPremiumAccess(): Promise<boolean> {
202
- const service = RevenueCatServiceProvider.getInstance();
203
-
204
- try {
205
- const isActive = await service.checkEntitlement('premium');
206
-
207
- if (isActive) {
208
- const entitlement = await service.checkEntitlementInfo('premium');
209
- console.log('Premium details:', entitlement);
210
- }
211
-
212
- return isActive;
213
- } catch (error) {
214
- console.error('Failed to check entitlement:', error);
215
- return false;
216
- }
217
- }
218
- ```
219
-
220
- ### Setting Subscriber Attributes
221
-
222
- ```typescript
223
- async function updateUserAttributes(user: User) {
224
- const service = RevenueCatServiceProvider.getInstance();
225
-
226
- // Set email
227
- if (user.email) {
228
- await service.setEmail(user.email);
229
- }
230
-
231
- // Set phone number
232
- if (user.phoneNumber) {
233
- await service.setPhoneNumber(user.phoneNumber);
234
- }
235
-
236
- // Set custom attributes
237
- await service.setAttributes({
238
- $displayName: user.displayName,
239
- account_created_at: user.createdAt.toISOString(),
240
- subscription_tier: user.tier,
241
- });
242
- }
243
- ```
244
-
245
- ## Error Handling
246
-
247
- ### Wrapping Service Calls
248
-
249
- ```typescript
250
- class RevenueCatServiceWrapper {
251
- private service: IRevenueCatService;
252
-
253
- constructor() {
254
- this.service = RevenueCatServiceProvider.getInstance();
255
- }
256
-
257
- async safePurchase(
258
- pkg: Package
259
- ): Promise<PurchaseResult> {
260
- try {
261
- return await this.service.purchasePackage(pkg);
262
- } catch (error) {
263
- // Convert to domain error
264
- if (isPurchasesError(error)) {
265
- return {
266
- customerInfo: {} as CustomerInfo,
267
- error,
268
- };
269
- }
270
- throw error;
271
- }
272
- }
273
-
274
- async safeGetOfferings(): Promise<Offerings | null> {
275
- try {
276
- return await this.getOfferings();
277
- } catch (error) {
278
- console.error('Failed to get offerings:', error);
279
- return null;
280
- }
281
- }
282
- }
283
- ```
284
-
285
- ## Testing
286
-
287
- ### Mock Implementation
288
-
289
- ```typescript
290
- class MockRevenueCatService implements IRevenueCatService {
291
- async configure(): Promise<void> {
292
- console.log('Mock: Configure called');
293
- }
294
-
295
- async purchasePackage(pkg: Package): Promise<PurchaseResult> {
296
- console.log('Mock: Purchase package', pkg.identifier);
297
- return {
298
- customerInfo: mockCustomerInfo,
299
- transaction: mockTransaction,
300
- };
301
- }
302
-
303
- // ... other mock implementations
304
- }
305
-
306
- // Use in tests
307
- const mockService = new MockRevenueCatService();
308
- ```
309
-
310
- ## Best Practices
311
-
312
- 1. **Singleton**: Use singleton pattern for service instance
313
- 2. **Error Handling**: Wrap all service calls in try-catch
314
- 3. **Type Safety**: Use TypeScript types for all operations
315
- 4. **Logging**: Log all RevenueCat operations
316
- 5. **Caching**: Cache customer info and offerings appropriately
317
- 6. **Validation**: Validate parameters before calling SDK
318
- 7. **Configuration**: Configure service only once
319
- 8. **Testing**: Use mock implementations for testing
320
-
321
- ## Related
322
-
6
+ ## Strategy
7
+ This directory contains concrete implementations of RevenueCat interfaces, providing the actual integration with the RevenueCat SDK using singleton pattern with proper error handling and caching.
8
+
9
+ ## Restrictions
10
+
11
+ ### REQUIRED
12
+ - Must use singleton pattern for service instance
13
+ - Must wrap all service calls in try-catch
14
+ - Must use TypeScript types for all operations
15
+ - Must log all RevenueCat operations
16
+
17
+ ### PROHIBITED
18
+ - DO NOT create multiple service instances
19
+ - DO NOT skip error handling
20
+ - DO NOT bypass type safety
21
+ - DO NOT skip logging operations
22
+
23
+ ### CRITICAL SAFETY
24
+ - Service MUST be configured only once
25
+ - All calls MUST be wrapped in error handling
26
+ - All operations MUST be type-safe
27
+ - All operations MUST be logged
28
+
29
+ ## AI Agent Guidelines
30
+ 1. Use singleton pattern for service instance
31
+ 2. Wrap all service calls in try-catch blocks
32
+ 3. Use TypeScript types for all operations
33
+ 4. Log all RevenueCat operations for debugging
34
+ 5. Cache customer info and offerings appropriately
35
+ 6. Validate parameters before calling SDK
36
+ 7. Configure service only once at startup
37
+ 8. Use mock implementations for testing
38
+
39
+ ## Related Documentation
323
40
  - [RevenueCat Infrastructure](../README.md)
324
41
  - [RevenueCat Handlers](../handlers/README.md)
325
42
  - [RevenueCat Application Ports](../../application/ports/README.md)