@umituz/react-native-subscription 2.14.98 → 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.
- package/README.md +211 -395
- package/package.json +1 -1
- package/src/application/README.md +46 -225
- package/src/application/ports/README.md +42 -97
- package/src/domain/README.md +36 -384
- package/src/domain/constants/README.md +0 -56
- package/src/domain/entities/README.md +43 -169
- package/src/domain/errors/README.md +33 -287
- package/src/domain/value-objects/README.md +43 -179
- package/src/domains/README.md +52 -0
- package/src/domains/README.md.bak +274 -0
- package/src/domains/config/README.md +93 -383
- package/src/domains/config/domain/README.md +37 -0
- package/src/domains/config/domain/entities/README.md +41 -0
- package/src/domains/paywall/README.md +99 -369
- package/src/domains/paywall/components/README.md +34 -178
- package/src/domains/paywall/entities/README.md +34 -193
- package/src/domains/paywall/hooks/README.md +34 -122
- package/src/domains/wallet/README.md +34 -275
- package/src/domains/wallet/README.md.bak +209 -0
- package/src/domains/wallet/domain/README.md +34 -101
- package/src/domains/wallet/domain/entities/README.md +34 -115
- package/src/domains/wallet/domain/errors/README.md +34 -151
- package/src/domains/wallet/infrastructure/README.md +34 -89
- package/src/domains/wallet/presentation/components/README.md +34 -224
- package/src/domains/wallet/presentation/hooks/README.md +34 -248
- package/src/infrastructure/README.md +37 -496
- package/src/infrastructure/mappers/README.md +0 -13
- package/src/infrastructure/repositories/README.md +74 -360
- package/src/infrastructure/services/README.md +95 -370
- package/src/presentation/README.md +123 -408
- package/src/presentation/README.md.bak +172 -0
- package/src/presentation/components/README.md +151 -179
- package/src/presentation/components/README.md.bak +217 -0
- package/src/presentation/components/details/CreditRow.md +65 -310
- package/src/presentation/components/details/DetailRow.md +63 -255
- package/src/presentation/components/details/PremiumDetailsCard.md +65 -238
- package/src/presentation/components/details/PremiumStatusBadge.md +64 -239
- package/src/presentation/components/details/README.md +97 -447
- package/src/presentation/components/feedback/PaywallFeedbackModal.md +63 -287
- package/src/presentation/components/feedback/README.md +97 -445
- package/src/presentation/components/paywall/PaywallModal.md +66 -416
- package/src/presentation/components/paywall/README.md +50 -186
- package/src/presentation/components/sections/README.md +97 -466
- package/src/presentation/components/sections/SubscriptionSection.md +92 -244
- package/src/presentation/hooks/README.md +154 -741
- package/src/presentation/hooks/useAuthAwarePurchase.md +58 -325
- package/src/presentation/hooks/useAuthGate.md +61 -375
- package/src/presentation/hooks/useAuthSubscriptionSync.md +66 -370
- package/src/presentation/hooks/useCreditChecker.md +73 -378
- package/src/presentation/hooks/useCredits.md +74 -313
- package/src/presentation/hooks/useCredits.md.bak +231 -0
- package/src/presentation/hooks/useCreditsGate.md +66 -318
- package/src/presentation/hooks/useDeductCredit.md +96 -156
- package/src/presentation/hooks/useDevTestCallbacks.md +63 -394
- package/src/presentation/hooks/useFeatureGate.md +105 -150
- package/src/presentation/hooks/useFeatureGate.md.bak +284 -0
- package/src/presentation/hooks/useInitializeCredits.md +64 -430
- package/src/presentation/hooks/usePaywall.md +61 -306
- package/src/presentation/hooks/usePaywallOperations.md +64 -458
- package/src/presentation/hooks/usePaywallVisibility.md +67 -316
- package/src/presentation/hooks/usePremium.md +84 -226
- package/src/presentation/hooks/usePremiumGate.md +60 -395
- package/src/presentation/hooks/usePremiumWithCredits.md +64 -401
- package/src/presentation/hooks/useSubscription.md +66 -422
- package/src/presentation/hooks/useSubscriptionDetails.md +65 -410
- package/src/presentation/hooks/useSubscriptionGate.md +80 -164
- package/src/presentation/hooks/useSubscriptionSettingsConfig.md +66 -346
- package/src/presentation/hooks/useSubscriptionStatus.md +66 -396
- package/src/presentation/hooks/useUserTier.md +63 -328
- package/src/presentation/hooks/useUserTierWithRepository.md +64 -424
- package/src/presentation/screens/README.md +48 -190
- package/src/presentation/types/README.md +0 -16
- package/src/presentation/utils/README.md +0 -21
- package/src/revenuecat/README.md +99 -518
- package/src/revenuecat/application/README.md +43 -0
- package/src/revenuecat/application/ports/README.md +41 -0
- package/src/revenuecat/domain/README.md +42 -141
- package/src/revenuecat/domain/constants/README.md +41 -0
- package/src/revenuecat/domain/entities/README.md +42 -0
- package/src/revenuecat/domain/errors/README.md +47 -191
- package/src/revenuecat/domain/types/README.md +41 -0
- package/src/revenuecat/domain/value-objects/README.md +41 -0
- package/src/revenuecat/infrastructure/README.md +41 -0
- package/src/revenuecat/infrastructure/config/README.md +32 -23
- package/src/revenuecat/infrastructure/handlers/README.md +41 -0
- package/src/revenuecat/infrastructure/managers/README.md +34 -42
- package/src/revenuecat/infrastructure/services/README.md +42 -0
- package/src/revenuecat/infrastructure/utils/README.md +41 -0
- package/src/revenuecat/presentation/README.md +42 -0
- package/src/revenuecat/presentation/hooks/README.md +29 -35
- package/src/utils/README.md +38 -525
|
@@ -2,373 +2,98 @@
|
|
|
2
2
|
|
|
3
3
|
Service implementations in the infrastructure layer.
|
|
4
4
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
// Try cache first
|
|
101
|
-
const cached = await this.cache.get(userId);
|
|
102
|
-
if (cached) return cached;
|
|
103
|
-
|
|
104
|
-
// Fetch from repository
|
|
105
|
-
const status = await this.repository.getSubscriptionStatus(userId);
|
|
106
|
-
|
|
107
|
-
// Update cache
|
|
108
|
-
if (status) {
|
|
109
|
-
await this.cache.set(userId, status, { ttl: 300000 });
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return status;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
async activateSubscription(
|
|
116
|
-
userId: string,
|
|
117
|
-
productId: string,
|
|
118
|
-
expiresAt: string | null
|
|
119
|
-
): Promise<SubscriptionStatus> {
|
|
120
|
-
// Business logic
|
|
121
|
-
const current = await this.getStatus(userId);
|
|
122
|
-
if (current?.isActive) {
|
|
123
|
-
throw new SubscriptionOperationError(
|
|
124
|
-
'User already has an active subscription'
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Activate
|
|
129
|
-
const status = await this.repository.saveSubscriptionStatus(userId, {
|
|
130
|
-
type: 'premium',
|
|
131
|
-
isActive: true,
|
|
132
|
-
isPremium: true,
|
|
133
|
-
expirationDate: expiresAt,
|
|
134
|
-
willRenew: expiresAt !== null,
|
|
135
|
-
productId,
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
return status;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
async deactivateSubscription(userId: string): Promise<SubscriptionStatus> {
|
|
142
|
-
const status = await this.getStatus(userId);
|
|
143
|
-
if (!status?.isActive) {
|
|
144
|
-
throw new SubscriptionOperationError('Subscription is not active');
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
const deactivated = {
|
|
148
|
-
...status,
|
|
149
|
-
isActive: false,
|
|
150
|
-
willRenew: false,
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
await this.repository.saveSubscriptionStatus(userId, deactivated);
|
|
154
|
-
return deactivated;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
async isPremium(userId: string): Promise<boolean> {
|
|
158
|
-
const status = await this.getStatus(userId);
|
|
159
|
-
return status?.isPremium ?? false;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
## Advanced Features
|
|
165
|
-
|
|
166
|
-
### Retry Logic
|
|
167
|
-
|
|
168
|
-
```typescript
|
|
169
|
-
class SubscriptionServiceWithRetry {
|
|
170
|
-
async getStatus(userId: string): Promise<SubscriptionStatus | null> {
|
|
171
|
-
return this.retryOperation(
|
|
172
|
-
() => this.repository.getSubscriptionStatus(userId),
|
|
173
|
-
{
|
|
174
|
-
maxRetries: 3,
|
|
175
|
-
delay: 1000,
|
|
176
|
-
backoff: 'exponential',
|
|
177
|
-
}
|
|
178
|
-
);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
private async retryOperation<T>(
|
|
182
|
-
operation: () => Promise<T>,
|
|
183
|
-
options: RetryOptions
|
|
184
|
-
): Promise<T> {
|
|
185
|
-
let lastError;
|
|
186
|
-
|
|
187
|
-
for (let attempt = 0; attempt < options.maxRetries; attempt++) {
|
|
188
|
-
try {
|
|
189
|
-
return await operation();
|
|
190
|
-
} catch (error) {
|
|
191
|
-
lastError = error;
|
|
192
|
-
|
|
193
|
-
if (attempt < options.maxRetries - 1) {
|
|
194
|
-
const delay = options.backoff === 'exponential'
|
|
195
|
-
? Math.pow(2, attempt) * options.delay
|
|
196
|
-
: options.delay;
|
|
197
|
-
|
|
198
|
-
await sleep(delay);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
throw lastError;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
### Circuit Breaker
|
|
209
|
-
|
|
210
|
-
```typescript
|
|
211
|
-
class CircuitBreaker {
|
|
212
|
-
private failures = 0;
|
|
213
|
-
private lastFailureTime: number | null = null;
|
|
214
|
-
private state: 'closed' | 'open' | 'half-open' = 'closed';
|
|
215
|
-
|
|
216
|
-
async execute<T>(operation: () => Promise<T>): Promise<T> {
|
|
217
|
-
if (this.state === 'open') {
|
|
218
|
-
if (this.shouldAttemptReset()) {
|
|
219
|
-
this.state = 'half-open';
|
|
220
|
-
} else {
|
|
221
|
-
throw new Error('Circuit breaker is open');
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
try {
|
|
226
|
-
const result = await operation();
|
|
227
|
-
this.onSuccess();
|
|
228
|
-
return result;
|
|
229
|
-
} catch (error) {
|
|
230
|
-
this.onFailure();
|
|
231
|
-
throw error;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
private onSuccess() {
|
|
236
|
-
this.failures = 0;
|
|
237
|
-
this.state = 'closed';
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
private onFailure() {
|
|
241
|
-
this.failures++;
|
|
242
|
-
this.lastFailureTime = Date.now();
|
|
243
|
-
|
|
244
|
-
if (this.failures >= 5) {
|
|
245
|
-
this.state = 'open';
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
private shouldAttemptReset(): boolean {
|
|
250
|
-
return (
|
|
251
|
-
this.lastFailureTime !== null &&
|
|
252
|
-
Date.now() - this.lastFailureTime > 60000 // 1 minute
|
|
253
|
-
);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
### Observability
|
|
259
|
-
|
|
260
|
-
```typescript
|
|
261
|
-
class ObservableSubscriptionService {
|
|
262
|
-
private eventEmitter = new EventEmitter();
|
|
263
|
-
|
|
264
|
-
async getStatus(userId: string): Promise<SubscriptionStatus | null> {
|
|
265
|
-
const startTime = Date.now();
|
|
266
|
-
|
|
267
|
-
try {
|
|
268
|
-
const status = await this.repository.getSubscriptionStatus(userId);
|
|
269
|
-
|
|
270
|
-
this.eventEmitter.emit('operation_success', {
|
|
271
|
-
operation: 'getStatus',
|
|
272
|
-
userId,
|
|
273
|
-
duration: Date.now() - startTime,
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
return status;
|
|
277
|
-
} catch (error) {
|
|
278
|
-
this.eventEmitter.emit('operation_error', {
|
|
279
|
-
operation: 'getStatus',
|
|
280
|
-
userId,
|
|
281
|
-
error: error.message,
|
|
282
|
-
duration: Date.now() - startTime,
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
throw error;
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
on(event: string, listener: (data: any) => void) {
|
|
290
|
-
this.eventEmitter.on(event, listener);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
off(event: string, listener: (data: any) => void) {
|
|
294
|
-
this.eventEmitter.off(event, listener);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
## Testing
|
|
300
|
-
|
|
301
|
-
### Unit Tests
|
|
302
|
-
|
|
303
|
-
```typescript
|
|
304
|
-
describe('SubscriptionService', () => {
|
|
305
|
-
let service: SubscriptionService;
|
|
306
|
-
let mockRepository: jest.Mocked<ISubscriptionRepository>;
|
|
307
|
-
|
|
308
|
-
beforeEach(() => {
|
|
309
|
-
mockRepository = {
|
|
310
|
-
getSubscriptionStatus: jest.fn(),
|
|
311
|
-
saveSubscriptionStatus: jest.fn(),
|
|
312
|
-
deleteSubscriptionStatus: jest.fn(),
|
|
313
|
-
isSubscriptionValid: jest.fn(),
|
|
314
|
-
};
|
|
315
|
-
|
|
316
|
-
service = new SubscriptionService({
|
|
317
|
-
repository: mockRepository,
|
|
318
|
-
});
|
|
319
|
-
});
|
|
320
|
-
|
|
321
|
-
it('should get subscription status', async () => {
|
|
322
|
-
const expectedStatus = { type: 'premium', isActive: true };
|
|
323
|
-
mockRepository.getSubscriptionStatus.mockResolvedValue(expectedStatus);
|
|
324
|
-
|
|
325
|
-
const status = await service.getStatus('user-123');
|
|
326
|
-
|
|
327
|
-
expect(status).toEqual(expectedStatus);
|
|
328
|
-
expect(mockRepository.getSubscriptionStatus).toHaveBeenCalledWith('user-123');
|
|
329
|
-
});
|
|
330
|
-
});
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
### Integration Tests
|
|
334
|
-
|
|
335
|
-
```typescript
|
|
336
|
-
describe('SubscriptionService Integration', () => {
|
|
337
|
-
let service: SubscriptionService;
|
|
338
|
-
let repository: FirebaseSubscriptionRepository;
|
|
339
|
-
|
|
340
|
-
beforeAll(async () => {
|
|
341
|
-
// Use test Firebase instance
|
|
342
|
-
const testDb = await initializeTestFirebase();
|
|
343
|
-
repository = new FirebaseSubscriptionRepository(testDb);
|
|
344
|
-
service = new SubscriptionService({ repository });
|
|
345
|
-
});
|
|
346
|
-
|
|
347
|
-
it('should activate subscription', async () => {
|
|
348
|
-
const status = await service.activateSubscription(
|
|
349
|
-
'user-123',
|
|
350
|
-
'premium_monthly',
|
|
351
|
-
'2025-12-31'
|
|
352
|
-
);
|
|
353
|
-
|
|
354
|
-
expect(status.type).toBe('premium');
|
|
355
|
-
expect(status.isActive).toBe(true);
|
|
356
|
-
});
|
|
357
|
-
});
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
## Best Practices
|
|
361
|
-
|
|
362
|
-
1. **Dependency Injection** - Accept dependencies via constructor
|
|
363
|
-
2. **Error Handling** - Handle and transform errors appropriately
|
|
364
|
-
3. **Logging** - Log important operations
|
|
365
|
-
4. **Caching** - Cache frequently accessed data
|
|
366
|
-
5. **Validation** - Validate inputs
|
|
367
|
-
6. **Type Safety** - Use TypeScript types
|
|
368
|
-
7. **Testing** - Write comprehensive tests
|
|
369
|
-
|
|
370
|
-
## Related
|
|
371
|
-
|
|
372
|
-
- [Application Layer](../../application/README.md)
|
|
373
|
-
- [Application Ports](../../application/ports/README.md)
|
|
374
|
-
- [Infrastructure Layer](../../README.md)
|
|
5
|
+
## Location
|
|
6
|
+
|
|
7
|
+
- **Base Path**: `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-subscription/src/infrastructure/services/`
|
|
8
|
+
- **Services**: `src/infrastructure/services/`
|
|
9
|
+
|
|
10
|
+
## Strategy
|
|
11
|
+
|
|
12
|
+
### Service Architecture
|
|
13
|
+
|
|
14
|
+
Business logic implementation for subscription operations.
|
|
15
|
+
|
|
16
|
+
- **SubscriptionService**: Main subscription management service
|
|
17
|
+
- **SubscriptionInitializer**: System initialization
|
|
18
|
+
- **Status Sync**: Automatic status synchronization
|
|
19
|
+
- **Error Handling**: Comprehensive error management
|
|
20
|
+
|
|
21
|
+
### Service Features
|
|
22
|
+
|
|
23
|
+
Core service capabilities.
|
|
24
|
+
|
|
25
|
+
- **Automatic Status Sync**: Real-time status updates
|
|
26
|
+
- **Error Handling**: Robust error management
|
|
27
|
+
- **Caching**: Performance optimization through caching
|
|
28
|
+
- **Event Handling**: Status change event callbacks
|
|
29
|
+
|
|
30
|
+
### Advanced Patterns
|
|
31
|
+
|
|
32
|
+
Enterprise-grade service patterns.
|
|
33
|
+
|
|
34
|
+
- **Retry Logic**: Automatic retry on failures
|
|
35
|
+
- **Circuit Breaker**: Fault tolerance patterns
|
|
36
|
+
- **Observability**: Event emission and tracking
|
|
37
|
+
- **Transaction Support**: Atomic operations
|
|
38
|
+
|
|
39
|
+
### Custom Services
|
|
40
|
+
|
|
41
|
+
Extensible service architecture.
|
|
42
|
+
|
|
43
|
+
- **Interface Implementation**: Custom service implementations
|
|
44
|
+
- **Dependency Injection**: Flexible dependency management
|
|
45
|
+
- **Testing Support**: Test-friendly design
|
|
46
|
+
- **Configuration**: Service-level configuration
|
|
47
|
+
|
|
48
|
+
## Restrictions
|
|
49
|
+
|
|
50
|
+
### REQUIRED
|
|
51
|
+
|
|
52
|
+
- **Dependency Injection**: Use constructor injection
|
|
53
|
+
- **Error Handling**: Handle all errors appropriately
|
|
54
|
+
- **Logging**: Log important operations
|
|
55
|
+
- **Validation**: Validate all inputs
|
|
56
|
+
|
|
57
|
+
### PROHIBITED
|
|
58
|
+
|
|
59
|
+
- **Direct Storage Access**: Access storage only through repositories
|
|
60
|
+
- **Missing Error Handling**: Never swallow errors
|
|
61
|
+
- **Hardcoded Values**: Use configuration
|
|
62
|
+
- **Circular Dependencies**: Avoid circular dependencies
|
|
63
|
+
|
|
64
|
+
### CRITICAL
|
|
65
|
+
|
|
66
|
+
- **Error Transformation**: Transform storage errors to domain errors
|
|
67
|
+
- **Performance**: Optimize with caching
|
|
68
|
+
- **Reliability**: Implement retry logic
|
|
69
|
+
- **Observability**: Track all operations
|
|
70
|
+
|
|
71
|
+
## AI Agent Guidelines
|
|
72
|
+
|
|
73
|
+
### When Modifying Services
|
|
74
|
+
|
|
75
|
+
1. **Interface Compliance**: Maintain interface contracts
|
|
76
|
+
2. **Error Handling**: Comprehensive error handling
|
|
77
|
+
3. **Logging**: Add logging for debugging
|
|
78
|
+
4. **Testing**: Write comprehensive tests
|
|
79
|
+
|
|
80
|
+
### When Creating Custom Services
|
|
81
|
+
|
|
82
|
+
1. **Interface Implementation**: Implement required interfaces
|
|
83
|
+
2. **Dependency Injection**: Inject dependencies via constructor
|
|
84
|
+
3. **Error Handling**: Transform errors appropriately
|
|
85
|
+
4. **Documentation**: Document behavior and contracts
|
|
86
|
+
|
|
87
|
+
### When Fixing Service Bugs
|
|
88
|
+
|
|
89
|
+
1. **Repository Integration**: Check repository calls
|
|
90
|
+
2. **Error Handling**: Verify error transformation
|
|
91
|
+
3. **Business Logic**: Check business rules
|
|
92
|
+
4. **Edge Cases**: Test boundary conditions
|
|
93
|
+
|
|
94
|
+
## Related Documentation
|
|
95
|
+
|
|
96
|
+
- [Infrastructure Repositories](/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-subscription/src/infrastructure/repositories/README.md)
|
|
97
|
+
- [Application Layer](/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-subscription/src/application/README.md)
|
|
98
|
+
- [Application Ports](/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-subscription/src/application/ports/README.md)
|
|
99
|
+
- [Infrastructure Layer](/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-subscription/src/infrastructure/README.md)
|