@umituz/react-native-subscription 2.14.99 → 2.14.100

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 (92) hide show
  1. package/README.md +211 -394
  2. package/package.json +1 -1
  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/errors/README.md +33 -287
  9. package/src/domain/value-objects/README.md +43 -179
  10. package/src/domains/README.md +50 -238
  11. package/src/domains/README.md.bak +274 -0
  12. package/src/domains/config/README.md +93 -383
  13. package/src/domains/config/domain/README.md +23 -376
  14. package/src/domains/config/domain/entities/README.md +34 -343
  15. package/src/domains/paywall/README.md +99 -369
  16. package/src/domains/paywall/components/README.md +34 -178
  17. package/src/domains/paywall/entities/README.md +34 -193
  18. package/src/domains/paywall/hooks/README.md +34 -122
  19. package/src/domains/wallet/README.md +34 -275
  20. package/src/domains/wallet/README.md.bak +209 -0
  21. package/src/domains/wallet/domain/README.md +34 -101
  22. package/src/domains/wallet/domain/entities/README.md +34 -115
  23. package/src/domains/wallet/domain/errors/README.md +34 -151
  24. package/src/domains/wallet/infrastructure/README.md +34 -89
  25. package/src/domains/wallet/presentation/components/README.md +34 -224
  26. package/src/domains/wallet/presentation/hooks/README.md +34 -248
  27. package/src/infrastructure/README.md +37 -496
  28. package/src/infrastructure/mappers/README.md +0 -13
  29. package/src/infrastructure/repositories/README.md +74 -360
  30. package/src/infrastructure/services/README.md +95 -370
  31. package/src/presentation/README.md +123 -408
  32. package/src/presentation/README.md.bak +172 -0
  33. package/src/presentation/components/README.md +151 -179
  34. package/src/presentation/components/README.md.bak +217 -0
  35. package/src/presentation/components/details/CreditRow.md +65 -310
  36. package/src/presentation/components/details/DetailRow.md +63 -255
  37. package/src/presentation/components/details/PremiumDetailsCard.md +65 -238
  38. package/src/presentation/components/details/PremiumStatusBadge.md +64 -239
  39. package/src/presentation/components/details/README.md +97 -447
  40. package/src/presentation/components/feedback/PaywallFeedbackModal.md +63 -287
  41. package/src/presentation/components/feedback/README.md +97 -445
  42. package/src/presentation/components/paywall/PaywallModal.md +66 -416
  43. package/src/presentation/components/paywall/README.md +50 -186
  44. package/src/presentation/components/sections/README.md +97 -466
  45. package/src/presentation/components/sections/SubscriptionSection.md +92 -244
  46. package/src/presentation/hooks/README.md +154 -741
  47. package/src/presentation/hooks/useAuthAwarePurchase.md +58 -325
  48. package/src/presentation/hooks/useAuthGate.md +61 -375
  49. package/src/presentation/hooks/useAuthSubscriptionSync.md +66 -370
  50. package/src/presentation/hooks/useCreditChecker.md +73 -378
  51. package/src/presentation/hooks/useCredits.md +74 -313
  52. package/src/presentation/hooks/useCredits.md.bak +231 -0
  53. package/src/presentation/hooks/useCreditsGate.md +66 -318
  54. package/src/presentation/hooks/useDeductCredit.md +0 -76
  55. package/src/presentation/hooks/useDevTestCallbacks.md +63 -394
  56. package/src/presentation/hooks/useFeatureGate.md +105 -150
  57. package/src/presentation/hooks/useFeatureGate.md.bak +284 -0
  58. package/src/presentation/hooks/useInitializeCredits.md +64 -430
  59. package/src/presentation/hooks/usePaywall.md +61 -306
  60. package/src/presentation/hooks/usePaywallOperations.md +64 -458
  61. package/src/presentation/hooks/usePaywallVisibility.md +67 -316
  62. package/src/presentation/hooks/usePremium.md +84 -226
  63. package/src/presentation/hooks/usePremiumGate.md +60 -395
  64. package/src/presentation/hooks/usePremiumWithCredits.md +64 -401
  65. package/src/presentation/hooks/useSubscription.md +66 -422
  66. package/src/presentation/hooks/useSubscriptionDetails.md +65 -410
  67. package/src/presentation/hooks/useSubscriptionGate.md +80 -164
  68. package/src/presentation/hooks/useSubscriptionSettingsConfig.md +66 -346
  69. package/src/presentation/hooks/useSubscriptionStatus.md +66 -396
  70. package/src/presentation/hooks/useUserTier.md +63 -328
  71. package/src/presentation/hooks/useUserTierWithRepository.md +64 -424
  72. package/src/presentation/screens/README.md +48 -190
  73. package/src/presentation/types/README.md +0 -16
  74. package/src/presentation/utils/README.md +0 -21
  75. package/src/revenuecat/README.md +99 -518
  76. package/src/revenuecat/application/README.md +35 -150
  77. package/src/revenuecat/application/ports/README.md +34 -162
  78. package/src/revenuecat/domain/README.md +42 -141
  79. package/src/revenuecat/domain/constants/README.md +34 -176
  80. package/src/revenuecat/domain/entities/README.md +34 -374
  81. package/src/revenuecat/domain/errors/README.md +47 -191
  82. package/src/revenuecat/domain/types/README.md +34 -366
  83. package/src/revenuecat/domain/value-objects/README.md +34 -434
  84. package/src/revenuecat/infrastructure/README.md +34 -43
  85. package/src/revenuecat/infrastructure/config/README.md +32 -23
  86. package/src/revenuecat/infrastructure/handlers/README.md +34 -211
  87. package/src/revenuecat/infrastructure/managers/README.md +34 -42
  88. package/src/revenuecat/infrastructure/services/README.md +35 -318
  89. package/src/revenuecat/infrastructure/utils/README.md +34 -375
  90. package/src/revenuecat/presentation/README.md +34 -176
  91. package/src/revenuecat/presentation/hooks/README.md +29 -35
  92. 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)