@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.
- package/README.md +211 -394
- package/package.json +3 -3
- 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/entities/SubscriptionStatus.ts +1 -1
- package/src/domain/errors/README.md +33 -287
- package/src/domain/value-objects/README.md +43 -179
- package/src/domains/README.md +50 -238
- package/src/domains/README.md.bak +274 -0
- package/src/domains/config/README.md +93 -383
- package/src/domains/config/domain/README.md +23 -376
- package/src/domains/config/domain/entities/README.md +34 -343
- 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/components/TransactionItem.tsx +1 -1
- 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/ActivationHandler.ts +1 -1
- package/src/infrastructure/services/README.md +95 -370
- package/src/infrastructure/services/SubscriptionService.ts +1 -1
- 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 +0 -76
- package/src/presentation/hooks/useDeductCredit.ts +1 -1
- 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/presentation/utils/subscriptionDateUtils.ts +1 -1
- package/src/revenuecat/README.md +99 -518
- package/src/revenuecat/application/README.md +35 -150
- package/src/revenuecat/application/ports/README.md +34 -162
- package/src/revenuecat/domain/README.md +42 -141
- package/src/revenuecat/domain/constants/README.md +34 -176
- package/src/revenuecat/domain/entities/README.md +34 -374
- package/src/revenuecat/domain/errors/README.md +47 -191
- package/src/revenuecat/domain/types/README.md +34 -366
- package/src/revenuecat/domain/value-objects/README.md +34 -434
- package/src/revenuecat/infrastructure/README.md +34 -43
- package/src/revenuecat/infrastructure/config/README.md +32 -23
- package/src/revenuecat/infrastructure/handlers/README.md +34 -211
- package/src/revenuecat/infrastructure/managers/README.md +34 -42
- package/src/revenuecat/infrastructure/services/README.md +35 -318
- package/src/revenuecat/infrastructure/utils/README.md +34 -375
- package/src/revenuecat/presentation/README.md +34 -176
- package/src/revenuecat/presentation/hooks/README.md +29 -35
- package/src/utils/README.md +38 -525
package/src/domain/README.md
CHANGED
|
@@ -2,401 +2,53 @@
|
|
|
2
2
|
|
|
3
3
|
Abonelik sisteminin temel domain logic'ini, entity'lerini ve value object'lerini içeren katman.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Location
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- **Value Objects**: Değer objelerini oluşturma
|
|
9
|
-
- **Domain Errors**: Domain-specific hataları tanımlama
|
|
10
|
-
- **Business Rules**: İş kurallarını encapsulate etme
|
|
7
|
+
`src/domain/`
|
|
11
8
|
|
|
12
|
-
##
|
|
9
|
+
## Strategy
|
|
13
10
|
|
|
14
|
-
|
|
15
|
-
domain/
|
|
16
|
-
├── entities/
|
|
17
|
-
│ └── SubscriptionStatus.ts # Abonelik durumu entity'si
|
|
18
|
-
├── value-objects/
|
|
19
|
-
│ └── SubscriptionConfig.ts # Konfigürasyon value object
|
|
20
|
-
└── errors/
|
|
21
|
-
├── SubscriptionError.ts # Abonelik hataları
|
|
22
|
-
└── InsufficientCreditsError.ts # Kredi yetersizlik hatası
|
|
23
|
-
```
|
|
11
|
+
Temel iş kavramlarını, iş kurallarını ve domain logic'ini encapsulate eden katman. Framework-agnostic ve tamamen iş mantığına odaklı.
|
|
24
12
|
|
|
25
|
-
##
|
|
13
|
+
## Restrictions
|
|
26
14
|
|
|
27
|
-
###
|
|
15
|
+
### REQUIRED
|
|
28
16
|
|
|
29
|
-
|
|
17
|
+
- MUST be framework-agnostic (no React, React Native dependencies)
|
|
18
|
+
- MUST encapsulate business rules within entities
|
|
19
|
+
- MUST validate all invariants on entity creation
|
|
20
|
+
- MUST use immutable objects
|
|
21
|
+
- MUST implement type guards for type safety
|
|
22
|
+
- MUST define domain-specific error types
|
|
30
23
|
|
|
31
|
-
|
|
32
|
-
import {
|
|
33
|
-
SubscriptionStatus,
|
|
34
|
-
SubscriptionStatusType,
|
|
35
|
-
createDefaultSubscriptionStatus,
|
|
36
|
-
isSubscriptionValid,
|
|
37
|
-
} from '@umituz/react-native-subscription';
|
|
24
|
+
### PROHIBITED
|
|
38
25
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
// isActive: false,
|
|
44
|
-
// isPremium: false,
|
|
45
|
-
// expirationDate: null,
|
|
46
|
-
// willRenew: false,
|
|
47
|
-
// }
|
|
26
|
+
- MUST NOT contain any framework or UI code
|
|
27
|
+
- MUST NOT have direct dependencies on infrastructure
|
|
28
|
+
- MUST NOT expose mutable state
|
|
29
|
+
- MUST NOT use generic error types
|
|
48
30
|
|
|
49
|
-
|
|
50
|
-
const premiumStatus: SubscriptionStatus = {
|
|
51
|
-
type: 'premium',
|
|
52
|
-
isActive: true,
|
|
53
|
-
isPremium: true,
|
|
54
|
-
expirationDate: '2025-12-31T23:59:59Z',
|
|
55
|
-
willRenew: true,
|
|
56
|
-
productId: 'com.app.premium.annual',
|
|
57
|
-
};
|
|
31
|
+
### CRITICAL
|
|
58
32
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
33
|
+
- Keep entities pure and framework-independent
|
|
34
|
+
- Validate all business rules on entity creation
|
|
35
|
+
- Make all objects immutable
|
|
36
|
+
- Encapsulate business logic within entities
|
|
37
|
+
- Use strong typing throughout
|
|
62
38
|
|
|
63
|
-
|
|
39
|
+
## AI Agent Guidelines
|
|
64
40
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
41
|
+
When working with domain layer:
|
|
42
|
+
1. Immutable Objects - entity'leri immutable olarak tasarlayın
|
|
43
|
+
2. Validation - entity creation'da validation yapın
|
|
44
|
+
3. Encapsulation - business logic'i entity içinde tutun
|
|
45
|
+
4. Type Safety - strong typing kullanın
|
|
46
|
+
5. Domain Events - önemli domain olaylarını event olarak yayınlayın
|
|
47
|
+
6. Error Handling - domain-specific hatalar tanımlayın
|
|
72
48
|
|
|
73
|
-
##
|
|
49
|
+
## Related Documentation
|
|
74
50
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
```typescript
|
|
80
|
-
import type { SubscriptionConfig } from '@umituz/react-native-subscription';
|
|
81
|
-
|
|
82
|
-
const config: SubscriptionConfig = {
|
|
83
|
-
revenueCatApiKey: 'your_api_key',
|
|
84
|
-
revenueCatEntitlementId: 'premium',
|
|
85
|
-
|
|
86
|
-
plans: {
|
|
87
|
-
monthly: monthlyPlan,
|
|
88
|
-
annual: annualPlan,
|
|
89
|
-
},
|
|
90
|
-
|
|
91
|
-
defaultPlan: 'monthly',
|
|
92
|
-
|
|
93
|
-
features: {
|
|
94
|
-
requireAuth: true,
|
|
95
|
-
allowRestore: true,
|
|
96
|
-
syncWithFirebase: true,
|
|
97
|
-
},
|
|
98
|
-
|
|
99
|
-
ui: {
|
|
100
|
-
showAnnualDiscount: true,
|
|
101
|
-
highlightPopularPlan: true,
|
|
102
|
-
},
|
|
103
|
-
|
|
104
|
-
// Optional callbacks
|
|
105
|
-
onStatusChanged: (userId, newStatus) => {
|
|
106
|
-
console.log(`Status changed for ${userId}:`, newStatus);
|
|
107
|
-
},
|
|
108
|
-
|
|
109
|
-
onError: (error) => {
|
|
110
|
-
console.error('Subscription error:', error);
|
|
111
|
-
},
|
|
112
|
-
};
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
## Domain Errors
|
|
116
|
-
|
|
117
|
-
### SubscriptionError
|
|
118
|
-
|
|
119
|
-
Abonelik işlemleri için hata sınıfı:
|
|
120
|
-
|
|
121
|
-
```typescript
|
|
122
|
-
import {
|
|
123
|
-
SubscriptionError,
|
|
124
|
-
SubscriptionValidationError,
|
|
125
|
-
SubscriptionRepositoryError,
|
|
126
|
-
} from '@umituz/react-native-subscription';
|
|
127
|
-
|
|
128
|
-
// Doğrulama hatası
|
|
129
|
-
throw new SubscriptionValidationError('Invalid user ID');
|
|
130
|
-
|
|
131
|
-
// Repository hatası
|
|
132
|
-
throw new SubscriptionRepositoryError('Database connection failed');
|
|
133
|
-
|
|
134
|
-
// Genel hata
|
|
135
|
-
throw new SubscriptionError('Subscription operation failed');
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
### InsufficientCreditsError
|
|
139
|
-
|
|
140
|
-
Kredi yetersizliği hatası:
|
|
141
|
-
|
|
142
|
-
```typescript
|
|
143
|
-
import {
|
|
144
|
-
InsufficientCreditsError,
|
|
145
|
-
type CreditErrorContext,
|
|
146
|
-
} from '@umituz/react-native-subscription';
|
|
147
|
-
|
|
148
|
-
const context: CreditErrorContext = {
|
|
149
|
-
required: 10,
|
|
150
|
-
available: 5,
|
|
151
|
-
featureId: 'ai_generation',
|
|
152
|
-
currency: 'USD',
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
throw new InsufficientCreditsError(
|
|
156
|
-
'Not enough credits',
|
|
157
|
-
context
|
|
158
|
-
);
|
|
159
|
-
|
|
160
|
-
// Hata yakalama
|
|
161
|
-
try {
|
|
162
|
-
await deductCredits(userId, 10);
|
|
163
|
-
} catch (error) {
|
|
164
|
-
if (error instanceof InsufficientCreditsError) {
|
|
165
|
-
console.log(`Required: ${error.context.required}`);
|
|
166
|
-
console.log(`Available: ${error.context.available}`);
|
|
167
|
-
// Paywall göster
|
|
168
|
-
showPaywall();
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
## Helper Functions
|
|
174
|
-
|
|
175
|
-
### SubscriptionStatus Helpers
|
|
176
|
-
|
|
177
|
-
```typescript
|
|
178
|
-
import {
|
|
179
|
-
createDefaultSubscriptionStatus,
|
|
180
|
-
isSubscriptionValid,
|
|
181
|
-
isSubscriptionActive,
|
|
182
|
-
isUserPremium,
|
|
183
|
-
getSubscriptionTier,
|
|
184
|
-
} from '@umituz/react-native-subscription';
|
|
185
|
-
|
|
186
|
-
// Varsayılan durum oluştur
|
|
187
|
-
const status = createDefaultSubscriptionStatus();
|
|
188
|
-
|
|
189
|
-
// Geçerlilik kontrolü
|
|
190
|
-
const isValid = isSubscriptionValid(status);
|
|
191
|
-
|
|
192
|
-
// Aktif kontrolü
|
|
193
|
-
const isActive = isSubscriptionActive(status);
|
|
194
|
-
|
|
195
|
-
// Premium kontrolü
|
|
196
|
-
const isPremium = isUserPremium(status);
|
|
197
|
-
|
|
198
|
-
// Tier bilgisi
|
|
199
|
-
const tier = getSubscriptionTier(status); // 'free', 'premium'
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
## Factory Functions
|
|
203
|
-
|
|
204
|
-
### Entity Factory
|
|
205
|
-
|
|
206
|
-
```typescript
|
|
207
|
-
import { SubscriptionStatus } from '@umituz/react-native-subscription';
|
|
208
|
-
|
|
209
|
-
// Factory method ile oluştur
|
|
210
|
-
const status = SubscriptionStatus.create({
|
|
211
|
-
type: 'premium',
|
|
212
|
-
isActive: true,
|
|
213
|
-
isPremium: true,
|
|
214
|
-
expirationDate: '2025-12-31T23:59:59Z',
|
|
215
|
-
willRenew: true,
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
// Validation içerir
|
|
219
|
-
try {
|
|
220
|
-
const invalid = SubscriptionStatus.create({
|
|
221
|
-
type: 'premium',
|
|
222
|
-
isActive: false, // Çelişki: premium ama aktif değil
|
|
223
|
-
isPremium: true,
|
|
224
|
-
});
|
|
225
|
-
} catch (error) {
|
|
226
|
-
console.error('Validation error:', error.message);
|
|
227
|
-
}
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
## Type Guards
|
|
231
|
-
|
|
232
|
-
Domain entities için type guard'lar:
|
|
233
|
-
|
|
234
|
-
```typescript
|
|
235
|
-
import {
|
|
236
|
-
isSubscriptionStatus,
|
|
237
|
-
isValidSubscriptionStatus,
|
|
238
|
-
} from '@umituz/react-native-subscription';
|
|
239
|
-
|
|
240
|
-
// Type guard
|
|
241
|
-
const obj = { type: 'premium', isActive: true, isPremium: true };
|
|
242
|
-
|
|
243
|
-
if (isSubscriptionStatus(obj)) {
|
|
244
|
-
// obj artık SubscriptionStatus tipinde
|
|
245
|
-
console.log(obj.type); // Type-safe!
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// Validasyon + type guard
|
|
249
|
-
if (isValidSubscriptionStatus(obj)) {
|
|
250
|
-
// Geçerli bir SubscriptionStatus
|
|
251
|
-
}
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
## Domain Rules
|
|
255
|
-
|
|
256
|
-
### Business Rule Examples
|
|
257
|
-
|
|
258
|
-
```typescript
|
|
259
|
-
import { SubscriptionStatus } from '@umituz/react-native-subscription';
|
|
260
|
-
|
|
261
|
-
class SubscriptionDomain {
|
|
262
|
-
// Kural: Premium kullanıcı her zaman aktif olmalı
|
|
263
|
-
static validatePremiumStatus(status: SubscriptionStatus): boolean {
|
|
264
|
-
if (status.isPremium && !status.isActive) {
|
|
265
|
-
throw new Error('Premium users must be active');
|
|
266
|
-
}
|
|
267
|
-
return true;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
// Kural: Abonelik tarihi geçmişse aktif olmamalı
|
|
271
|
-
static validateExpiration(status: SubscriptionStatus): boolean {
|
|
272
|
-
if (status.expirationDate) {
|
|
273
|
-
const isExpired = new Date(status.expirationDate) < new Date();
|
|
274
|
-
if (isExpired && status.isActive) {
|
|
275
|
-
throw new Error('Expired subscription cannot be active');
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
return true;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
// Kural: Lifetime aboneliklerin son kullanma tarihi olmamalı
|
|
282
|
-
static validateLifetime(status: SubscriptionStatus): boolean {
|
|
283
|
-
if (status.type === 'premium' && status.willRenew === false) {
|
|
284
|
-
if (status.expirationDate !== null) {
|
|
285
|
-
throw new Error('Lifetime subscriptions cannot have expiration date');
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
return true;
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
## Best Practices
|
|
294
|
-
|
|
295
|
-
1. **Immutable Objects**: Entity'leri immutable olarak tasarlayın
|
|
296
|
-
2. **Validation**: Entity creation'da validation yapın
|
|
297
|
-
3. **Encapsulation**: Business logic'i entity içinde tutun
|
|
298
|
-
4. **Type Safety**: Strong typing kullanın
|
|
299
|
-
5. **Domain Events**: Önemli domain olaylarını event olarak yayınlayın
|
|
300
|
-
6. **Error Handling**: Domain-specific hatalar tanımlayın
|
|
301
|
-
|
|
302
|
-
## Örnek: Domain Service
|
|
303
|
-
|
|
304
|
-
```typescript
|
|
305
|
-
import {
|
|
306
|
-
SubscriptionStatus,
|
|
307
|
-
SubscriptionError,
|
|
308
|
-
isSubscriptionValid,
|
|
309
|
-
} from '@umituz/react-native-subscription';
|
|
310
|
-
|
|
311
|
-
class SubscriptionDomainService {
|
|
312
|
-
// Abonelik aktifleştirme
|
|
313
|
-
activateSubscription(
|
|
314
|
-
currentStatus: SubscriptionStatus,
|
|
315
|
-
productId: string,
|
|
316
|
-
expiresAt: string
|
|
317
|
-
): SubscriptionStatus {
|
|
318
|
-
// Business rule: Zaten aktifse hata
|
|
319
|
-
if (currentStatus.isActive) {
|
|
320
|
-
throw new SubscriptionError('Subscription is already active');
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
// Yeni durum oluştur
|
|
324
|
-
const newStatus: SubscriptionStatus = {
|
|
325
|
-
type: 'premium',
|
|
326
|
-
isActive: true,
|
|
327
|
-
isPremium: true,
|
|
328
|
-
expirationDate: expiresAt,
|
|
329
|
-
willRenew: productId.includes('monthly') || productId.includes('annual'),
|
|
330
|
-
productId,
|
|
331
|
-
};
|
|
332
|
-
|
|
333
|
-
return newStatus;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
// Abonelik iptali
|
|
337
|
-
deactivateSubscription(
|
|
338
|
-
status: SubscriptionStatus
|
|
339
|
-
): SubscriptionStatus {
|
|
340
|
-
if (!status.isActive) {
|
|
341
|
-
throw new SubscriptionError('Subscription is not active');
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
return {
|
|
345
|
-
...status,
|
|
346
|
-
isActive: false,
|
|
347
|
-
willRenew: false,
|
|
348
|
-
};
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
// Abonelik yenileme
|
|
352
|
-
renewSubscription(
|
|
353
|
-
status: SubscriptionStatus,
|
|
354
|
-
newExpirationDate: string
|
|
355
|
-
): SubscriptionStatus {
|
|
356
|
-
if (!status.willRenew) {
|
|
357
|
-
throw new SubscriptionError('Subscription is set to not renew');
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
return {
|
|
361
|
-
...status,
|
|
362
|
-
expirationDate: newExpirationDate,
|
|
363
|
-
isActive: true,
|
|
364
|
-
};
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
## Testing
|
|
370
|
-
|
|
371
|
-
Domain entities test edilebilir olmalı:
|
|
372
|
-
|
|
373
|
-
```typescript
|
|
374
|
-
import { SubscriptionStatus, isSubscriptionValid } from '@umituz/react-native-subscription';
|
|
375
|
-
|
|
376
|
-
describe('SubscriptionStatus', () => {
|
|
377
|
-
it('should create valid premium status', () => {
|
|
378
|
-
const status = SubscriptionStatus.create({
|
|
379
|
-
type: 'premium',
|
|
380
|
-
isActive: true,
|
|
381
|
-
isPremium: true,
|
|
382
|
-
expirationDate: '2025-12-31T23:59:59Z',
|
|
383
|
-
willRenew: true,
|
|
384
|
-
});
|
|
385
|
-
|
|
386
|
-
expect(status.type).toBe('premium');
|
|
387
|
-
expect(status.isPremium).toBe(true);
|
|
388
|
-
});
|
|
389
|
-
|
|
390
|
-
it('should validate expiration', () => {
|
|
391
|
-
const expired = SubscriptionStatus.create({
|
|
392
|
-
type: 'premium',
|
|
393
|
-
isActive: true,
|
|
394
|
-
isPremium: true,
|
|
395
|
-
expirationDate: '2020-01-01T00:00:00Z',
|
|
396
|
-
willRenew: true,
|
|
397
|
-
});
|
|
398
|
-
|
|
399
|
-
expect(isSubscriptionValid(expired)).toBe(false);
|
|
400
|
-
});
|
|
401
|
-
});
|
|
402
|
-
```
|
|
51
|
+
- [Domain Entities](./entities/README.md)
|
|
52
|
+
- [Value Objects](./value-objects/README.md)
|
|
53
|
+
- [Domain Errors](./errors/README.md)
|
|
54
|
+
- [Application Layer](../application/README.md)
|
|
@@ -10,70 +10,14 @@ This directory contains constant definitions for subscription tiers, package per
|
|
|
10
10
|
|
|
11
11
|
### Subscription Tiers
|
|
12
12
|
|
|
13
|
-
```typescript
|
|
14
|
-
export const SUBSCRIPTION_TIERS = {
|
|
15
|
-
GUEST: 'guest',
|
|
16
|
-
FREE: 'free',
|
|
17
|
-
PREMIUM: 'premium',
|
|
18
|
-
} as const;
|
|
19
|
-
|
|
20
|
-
export type SubscriptionTier = typeof SUBSCRIPTION_TIERS[keyof typeof SUBSCRIPTION_TIERS];
|
|
21
|
-
```
|
|
22
|
-
|
|
23
13
|
### Package Periods
|
|
24
14
|
|
|
25
|
-
```typescript
|
|
26
|
-
export const PACKAGE_PERIODS = {
|
|
27
|
-
MONTHLY: 'monthly',
|
|
28
|
-
ANNUAL: 'annual',
|
|
29
|
-
LIFETIME: 'lifetime',
|
|
30
|
-
} as const;
|
|
31
|
-
|
|
32
|
-
export type PackagePeriod = typeof PACKAGE_PERIODS[keyof typeof PACKAGE_PERIODS];
|
|
33
|
-
```
|
|
34
|
-
|
|
35
15
|
### Error Codes
|
|
36
16
|
|
|
37
|
-
```typescript
|
|
38
|
-
export const ERROR_CODES = {
|
|
39
|
-
CREDITS_EXHAUSTED: 'CREDITS_EXHAUSTED',
|
|
40
|
-
USER_NOT_AUTHENTICATED: 'USER_NOT_AUTHENTICATED',
|
|
41
|
-
SUBSCRIPTION_EXPIRED: 'SUBSCRIPTION_EXPIRED',
|
|
42
|
-
INVALID_PACKAGE: 'INVALID_PACKAGE',
|
|
43
|
-
PURCHASE_FAILED: 'PURCHASE_FAILED',
|
|
44
|
-
DUPLICATE_PURCHASE: 'DUPLICATE_PURCHASE',
|
|
45
|
-
} as const;
|
|
46
|
-
```
|
|
47
|
-
|
|
48
17
|
### Credit Limits
|
|
49
18
|
|
|
50
|
-
```typescript
|
|
51
|
-
export const CREDIT_LIMITS = {
|
|
52
|
-
MAX_MONTHLY_CREDITS: 100,
|
|
53
|
-
MAX_BONUS_CREDITS: 1000,
|
|
54
|
-
MIN_CREDITS: 0,
|
|
55
|
-
} as const;
|
|
56
|
-
```
|
|
57
|
-
|
|
58
19
|
### Time Periods
|
|
59
20
|
|
|
60
|
-
```typescript
|
|
61
|
-
export const TIME_PERIODS = {
|
|
62
|
-
CREDIT_RESET_DAYS: 30,
|
|
63
|
-
EXPIRATION_WARNING_DAYS: 7,
|
|
64
|
-
EXPIRATION_CRITICAL_DAYS: 3,
|
|
65
|
-
} as const;
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
## Usage
|
|
69
|
-
|
|
70
|
-
```typescript
|
|
71
|
-
import { SUBSCRIPTION_TIERS, PACKAGE_PERIODS } from './constants';
|
|
72
|
-
|
|
73
|
-
const tier: SubscriptionTier = SUBSCRIPTION_TIERS.PREMIUM;
|
|
74
|
-
const period: PackagePeriod = PACKAGE_PERIODS.ANNUAL;
|
|
75
|
-
```
|
|
76
|
-
|
|
77
21
|
## Related
|
|
78
22
|
|
|
79
23
|
- [Domain README](../README.md)
|