@umituz/react-native-subscription 2.37.38 → 2.37.40

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 (141) hide show
  1. package/package.json +1 -1
  2. package/src/domains/credits/application/CreditLimitCalculator.ts +1 -9
  3. package/src/domains/credits/application/CreditsInitializer.ts +5 -20
  4. package/src/domains/credits/application/DeductCreditsCommand.ts +13 -6
  5. package/src/domains/credits/application/RefundCreditsCommand.ts +1 -5
  6. package/src/domains/credits/application/credit-strategies/CreditAllocationOrchestrator.ts +1 -9
  7. package/src/domains/credits/application/credit-strategies/ICreditStrategy.ts +1 -5
  8. package/src/domains/credits/application/credit-strategies/TrialCreditStrategy.ts +1 -5
  9. package/src/domains/credits/application/creditDocumentHelpers.ts +2 -9
  10. package/src/domains/credits/application/creditOperationUtils.ts +1 -43
  11. package/src/domains/credits/core/Credits.ts +0 -23
  12. package/src/domains/credits/core/CreditsConstants.ts +0 -11
  13. package/src/domains/credits/core/CreditsMapper.ts +0 -6
  14. package/src/domains/credits/core/UserCreditsDocument.ts +0 -12
  15. package/src/domains/credits/infrastructure/CreditsRepository.ts +6 -1
  16. package/src/domains/credits/infrastructure/CreditsRepositoryManager.ts +0 -21
  17. package/src/domains/credits/infrastructure/operations/CreditsWriter.ts +52 -1
  18. package/src/domains/credits/presentation/deduct-credit/useDeductCredit.ts +2 -2
  19. package/src/domains/credits/presentation/useCredits.ts +10 -9
  20. package/src/domains/paywall/components/PaywallContainer.types.ts +0 -28
  21. package/src/domains/paywall/components/PaywallModal.styles.ts +0 -4
  22. package/src/domains/paywall/entities/types.ts +0 -5
  23. package/src/domains/paywall/hooks/usePaywallActions.ts +1 -15
  24. package/src/domains/revenuecat/core/errors/RevenueCatError.ts +0 -6
  25. package/src/domains/revenuecat/core/errors/RevenueCatErrorHandler.ts +0 -24
  26. package/src/domains/revenuecat/core/errors/RevenueCatErrorMessages.ts +0 -18
  27. package/src/domains/revenuecat/core/errors/index.ts +0 -4
  28. package/src/domains/revenuecat/core/types/RevenueCatConfig.ts +3 -7
  29. package/src/domains/revenuecat/core/types/RevenueCatData.ts +4 -9
  30. package/src/domains/revenuecat/core/types/RevenueCatTypes.ts +5 -65
  31. package/src/domains/revenuecat/core/types/index.ts +0 -4
  32. package/src/domains/revenuecat/infrastructure/services/UserSwitchMutex.ts +1 -24
  33. package/src/domains/subscription/application/SubscriptionAuthListener.ts +5 -21
  34. package/src/domains/subscription/application/SubscriptionInitializerTypes.ts +1 -5
  35. package/src/domains/subscription/application/SubscriptionSyncProcessor.ts +0 -4
  36. package/src/domains/subscription/application/SubscriptionSyncService.ts +4 -8
  37. package/src/domains/subscription/application/SubscriptionSyncUtils.ts +1 -1
  38. package/src/domains/subscription/application/initializer/BackgroundInitializer.ts +15 -2
  39. package/src/domains/subscription/application/initializer/ServiceConfigurator.ts +9 -2
  40. package/src/domains/subscription/application/statusChangeHandlers.ts +14 -27
  41. package/src/domains/subscription/application/syncIdGenerators.ts +0 -4
  42. package/src/domains/subscription/constants/thresholds.ts +0 -9
  43. package/src/domains/subscription/core/SubscriptionConstants.ts +0 -4
  44. package/src/domains/subscription/core/SubscriptionStatus.ts +11 -21
  45. package/src/domains/subscription/core/SubscriptionStatusHandlers.ts +4 -7
  46. package/src/domains/subscription/infrastructure/handlers/PurchaseStatusResolver.ts +1 -1
  47. package/src/domains/subscription/infrastructure/hooks/subscriptionQueryKeys.ts +0 -13
  48. package/src/domains/subscription/infrastructure/hooks/usePurchasePackage.ts +0 -18
  49. package/src/domains/subscription/infrastructure/hooks/useRestorePurchase.ts +3 -17
  50. package/src/domains/subscription/infrastructure/hooks/useRevenueCatTrialEligibility.ts +0 -17
  51. package/src/domains/subscription/infrastructure/hooks/useSubscriptionPackages.ts +0 -19
  52. package/src/domains/subscription/infrastructure/hooks/useSubscriptionQueries.ts +0 -6
  53. package/src/domains/subscription/infrastructure/managers/subscriptionManagerUtils.ts +0 -17
  54. package/src/domains/subscription/infrastructure/state/initializationState.ts +0 -25
  55. package/src/domains/subscription/infrastructure/utils/InitializationCache.ts +0 -21
  56. package/src/domains/subscription/infrastructure/utils/PremiumStatusSyncer.ts +3 -17
  57. package/src/domains/subscription/infrastructure/utils/authPurchaseState.ts +0 -5
  58. package/src/domains/subscription/infrastructure/utils/renewal/PackageTierComparator.ts +1 -0
  59. package/src/domains/subscription/infrastructure/utils/trialEligibilityUtils.ts +0 -18
  60. package/src/domains/subscription/presentation/components/details/PremiumDetailsCard.styles.ts +0 -5
  61. package/src/domains/subscription/presentation/components/details/PremiumDetailsCardTypes.ts +0 -5
  62. package/src/domains/subscription/presentation/components/feedback/paywallFeedbackStyles.ts +0 -5
  63. package/src/domains/subscription/presentation/stores/index.ts +0 -4
  64. package/src/domains/subscription/presentation/stores/purchaseLoadingStore.ts +0 -13
  65. package/src/domains/subscription/presentation/useAuthAwarePurchase.ts +30 -21
  66. package/src/domains/subscription/presentation/usePaywallVisibility.ts +0 -9
  67. package/src/domains/subscription/presentation/useSubscriptionStatus.ts +8 -11
  68. package/src/domains/subscription/utils/authGuards.ts +3 -0
  69. package/src/domains/trial/application/TrialService.ts +0 -9
  70. package/src/domains/trial/core/TrialTypes.ts +0 -8
  71. package/src/domains/wallet/domain/mappers/TransactionMapper.ts +0 -5
  72. package/src/domains/wallet/domain/types/transaction.types.ts +0 -7
  73. package/src/domains/wallet/index.ts +0 -7
  74. package/src/domains/wallet/infrastructure/config/walletConfig.ts +0 -11
  75. package/src/domains/wallet/presentation/hooks/useTransactionHistory.ts +6 -3
  76. package/src/domains/wallet/presentation/hooks/useWallet.ts +0 -7
  77. package/src/domains/wallet/utils/transactionIconMap.ts +0 -10
  78. package/src/global.d.ts +0 -6
  79. package/src/index.ts +1 -4
  80. package/src/init/createSubscriptionInitModule.ts +12 -2
  81. package/src/init/index.ts +1 -5
  82. package/src/presentation/hooks/feedback/useFeedbackSubmit.ts +0 -11
  83. package/src/shared/application/FeedbackService.ts +3 -21
  84. package/src/shared/application/ports/ISubscriptionRepository.ts +0 -4
  85. package/src/shared/infrastructure/SubscriptionEventBus.ts +0 -13
  86. package/src/shared/infrastructure/firestore/collectionUtils.ts +1 -17
  87. package/src/shared/infrastructure/firestore/index.ts +0 -4
  88. package/src/shared/infrastructure/firestore/resultUtils.ts +0 -12
  89. package/src/shared/infrastructure/react-query/hooks/usePreviousUserCleanup.ts +0 -17
  90. package/src/shared/infrastructure/react-query/queryConfig.ts +0 -15
  91. package/src/shared/utils/BaseError.ts +0 -5
  92. package/src/shared/utils/Result.ts +0 -20
  93. package/src/shared/utils/dateConverter.ts +6 -46
  94. package/src/utils/appUtils.ts +0 -16
  95. package/src/utils/creditMapper.ts +0 -7
  96. package/src/utils/dateUtils.compare.ts +0 -24
  97. package/src/utils/dateUtils.core.ts +0 -39
  98. package/src/utils/dateUtils.format.ts +0 -41
  99. package/src/utils/dateUtils.math.ts +0 -41
  100. package/src/utils/dateUtils.ts +0 -5
  101. package/src/utils/packagePeriodUtils.ts +0 -20
  102. package/src/utils/packageTypeDetector.ts +1 -21
  103. package/src/utils/premiumStatusUtils.ts +1 -14
  104. package/src/utils/priceUtils.ts +0 -35
  105. package/src/utils/tierUtils.ts +1 -8
  106. package/src/utils/types.ts +1 -25
  107. package/src/utils/validation.ts +1 -7
  108. package/src/domains/README.md +0 -52
  109. package/src/domains/config/domain/README.md +0 -37
  110. package/src/domains/config/domain/entities/README.md +0 -41
  111. package/src/domains/credits/application/credit-strategies/SyncCreditStrategy.ts +0 -24
  112. package/src/domains/paywall/README.md +0 -101
  113. package/src/domains/paywall/entities/README.md +0 -40
  114. package/src/domains/paywall/hooks/README.md +0 -41
  115. package/src/domains/subscription/application/syncConstants.ts +0 -1
  116. package/src/domains/subscription/infrastructure/README.md +0 -41
  117. package/src/domains/subscription/infrastructure/config/README.md +0 -49
  118. package/src/domains/subscription/infrastructure/handlers/README.md +0 -41
  119. package/src/domains/subscription/infrastructure/hooks/README.md +0 -50
  120. package/src/domains/subscription/infrastructure/managers/README.md +0 -41
  121. package/src/domains/subscription/infrastructure/services/README.md +0 -42
  122. package/src/domains/subscription/infrastructure/utils/README.md +0 -41
  123. package/src/domains/subscription/presentation/components/README.md +0 -155
  124. package/src/domains/subscription/presentation/components/details/CreditRow.md +0 -92
  125. package/src/domains/subscription/presentation/components/details/DetailRow.md +0 -91
  126. package/src/domains/subscription/presentation/components/details/PremiumDetailsCard.md +0 -93
  127. package/src/domains/subscription/presentation/components/details/PremiumStatusBadge.md +0 -91
  128. package/src/domains/subscription/presentation/components/details/README.md +0 -99
  129. package/src/domains/subscription/presentation/components/feedback/PaywallFeedbackModal.md +0 -90
  130. package/src/domains/subscription/presentation/components/feedback/README.md +0 -99
  131. package/src/domains/subscription/presentation/components/paywall/PaywallModal.md +0 -94
  132. package/src/domains/subscription/presentation/components/paywall/README.md +0 -54
  133. package/src/domains/subscription/presentation/components/sections/README.md +0 -99
  134. package/src/domains/subscription/presentation/components/sections/SubscriptionSection.md +0 -94
  135. package/src/domains/subscription/presentation/utils/README.md +0 -31
  136. package/src/domains/wallet/README.md +0 -51
  137. package/src/domains/wallet/domain/README.md +0 -41
  138. package/src/domains/wallet/infrastructure/README.md +0 -41
  139. package/src/domains/wallet/presentation/components/README.md +0 -41
  140. package/src/domains/wallet/presentation/hooks/README.md +0 -41
  141. package/src/shared/application/ports/README.md +0 -48
@@ -1,13 +1,5 @@
1
- /**
2
- * Date Utilities - Formatting
3
- * Date display and formatting functions
4
- */
5
-
6
1
  import type { DateLike } from "./dateUtils.core";
7
2
 
8
- /**
9
- * Format date to locale string
10
- */
11
3
  export function formatLocale(
12
4
  date: DateLike,
13
5
  options?: Intl.DateTimeFormatOptions,
@@ -20,9 +12,6 @@ export function formatLocale(
20
12
  return d.toLocaleDateString(locale, options);
21
13
  }
22
14
 
23
- /**
24
- * Format date to relative time (e.g., "2 days ago", "in 3 hours")
25
- */
26
15
  export function formatRelative(date: DateLike, now: Date = new Date()): string {
27
16
  const target = new Date(date);
28
17
  if (isNaN(target.getTime())) {
@@ -49,37 +38,22 @@ export function formatRelative(date: DateLike, now: Date = new Date()): string {
49
38
  return rtf.format(diffSecs, "second");
50
39
  }
51
40
 
52
- /**
53
- * Format date to short date string (e.g., "1/1/2024")
54
- */
55
41
  export function formatShort(date: DateLike, locale: string = "en-US"): string {
56
42
  return formatLocale(date, { month: "numeric", day: "numeric", year: "numeric" }, locale);
57
43
  }
58
44
 
59
- /**
60
- * Format date to medium date string (e.g., "Jan 1, 2024")
61
- */
62
45
  export function formatMedium(date: DateLike, locale: string = "en-US"): string {
63
46
  return formatLocale(date, { month: "short", day: "numeric", year: "numeric" }, locale);
64
47
  }
65
48
 
66
- /**
67
- * Format date to long date string (e.g., "January 1, 2024")
68
- */
69
49
  export function formatLong(date: DateLike, locale: string = "en-US"): string {
70
50
  return formatLocale(date, { month: "long", day: "numeric", year: "numeric" }, locale);
71
51
  }
72
52
 
73
- /**
74
- * Format date to time string
75
- */
76
53
  export function formatTime(date: DateLike, locale: string = "en-US"): string {
77
54
  return formatLocale(date, { hour: "numeric", minute: "numeric" }, locale);
78
55
  }
79
56
 
80
- /**
81
- * Format date to date and time string
82
- */
83
57
  export function formatDateTime(date: DateLike, locale: string = "en-US"): string {
84
58
  return formatLocale(
85
59
  date,
@@ -88,9 +62,6 @@ export function formatDateTime(date: DateLike, locale: string = "en-US"): string
88
62
  );
89
63
  }
90
64
 
91
- /**
92
- * Convert milliseconds to human-readable duration
93
- */
94
65
  export function formatDuration(ms: number): string {
95
66
  const seconds = Math.floor(ms / 1000);
96
67
  const minutes = Math.floor(seconds / 60);
@@ -109,30 +80,18 @@ export function formatDuration(ms: number): string {
109
80
  return `${seconds}s`;
110
81
  }
111
82
 
112
- /**
113
- * Format date to weekday name (e.g., "Monday")
114
- */
115
83
  export function formatWeekday(date: DateLike, locale: string = "en-US"): string {
116
84
  return formatLocale(date, { weekday: "long" }, locale);
117
85
  }
118
86
 
119
- /**
120
- * Format date to short weekday name (e.g., "Mon")
121
- */
122
87
  export function formatWeekdayShort(date: DateLike, locale: string = "en-US"): string {
123
88
  return formatLocale(date, { weekday: "short" }, locale);
124
89
  }
125
90
 
126
- /**
127
- * Format date to month name (e.g., "January")
128
- */
129
91
  export function formatMonth(date: DateLike, locale: string = "en-US"): string {
130
92
  return formatLocale(date, { month: "long" }, locale);
131
93
  }
132
94
 
133
- /**
134
- * Format date to short month name (e.g., "Jan")
135
- */
136
95
  export function formatMonthShort(date: DateLike, locale: string = "en-US"): string {
137
96
  return formatLocale(date, { month: "short" }, locale);
138
97
  }
@@ -1,83 +1,51 @@
1
- /**
2
- * Date Utilities - Math Operations
3
- * Date arithmetic and manipulation functions
4
- */
5
-
6
1
  import type { DateLike } from "./dateUtils.core";
7
2
 
8
- /**
9
- * Add days to a date
10
- */
11
3
  export function addDays(date: DateLike, days: number): Date {
12
4
  const result = new Date(date);
13
5
  result.setDate(result.getDate() + days);
14
6
  return result;
15
7
  }
16
8
 
17
- /**
18
- * Add hours to a date
19
- */
20
9
  export function addHours(date: DateLike, hours: number): Date {
21
10
  const result = new Date(date);
22
11
  result.setHours(result.getHours() + hours);
23
12
  return result;
24
13
  }
25
14
 
26
- /**
27
- * Add minutes to a date
28
- */
29
15
  export function addMinutes(date: DateLike, minutes: number): Date {
30
16
  const result = new Date(date);
31
17
  result.setMinutes(result.getMinutes() + minutes);
32
18
  return result;
33
19
  }
34
20
 
35
- /**
36
- * Add months to a date
37
- */
38
21
  export function addMonths(date: DateLike, months: number): Date {
39
22
  const result = new Date(date);
40
23
  result.setMonth(result.getMonth() + months);
41
24
  return result;
42
25
  }
43
26
 
44
- /**
45
- * Add years to a date
46
- */
47
27
  export function addYears(date: DateLike, years: number): Date {
48
28
  const result = new Date(date);
49
29
  result.setFullYear(result.getFullYear() + years);
50
30
  return result;
51
31
  }
52
32
 
53
- /**
54
- * Subtract days from a date
55
- */
56
33
  export function subtractDays(date: DateLike, days: number): Date {
57
34
  return addDays(date, -days);
58
35
  }
59
36
 
60
- /**
61
- * Get start of day (midnight)
62
- */
63
37
  export function startOfDay(date: DateLike): Date {
64
38
  const d = new Date(date);
65
39
  d.setHours(0, 0, 0, 0);
66
40
  return d;
67
41
  }
68
42
 
69
- /**
70
- * Get end of day (23:59:59.999)
71
- */
72
43
  export function endOfDay(date: DateLike): Date {
73
44
  const d = new Date(date);
74
45
  d.setHours(23, 59, 59, 999);
75
46
  return d;
76
47
  }
77
48
 
78
- /**
79
- * Get start of week (Sunday)
80
- */
81
49
  export function startOfWeek(date: DateLike): Date {
82
50
  const d = new Date(date);
83
51
  const day = d.getDay();
@@ -85,9 +53,6 @@ export function startOfWeek(date: DateLike): Date {
85
53
  return new Date(d.setDate(diff));
86
54
  }
87
55
 
88
- /**
89
- * Get end of week (Saturday)
90
- */
91
56
  export function endOfWeek(date: DateLike): Date {
92
57
  const d = new Date(date);
93
58
  const day = d.getDay();
@@ -95,17 +60,11 @@ export function endOfWeek(date: DateLike): Date {
95
60
  return new Date(d.setDate(diff));
96
61
  }
97
62
 
98
- /**
99
- * Get start of month
100
- */
101
63
  export function startOfMonth(date: DateLike): Date {
102
64
  const d = new Date(date);
103
65
  return new Date(d.getFullYear(), d.getMonth(), 1);
104
66
  }
105
67
 
106
- /**
107
- * Get end of month
108
- */
109
68
  export function endOfMonth(date: DateLike): Date {
110
69
  const d = new Date(date);
111
70
  return new Date(d.getFullYear(), d.getMonth() + 1, 0);
@@ -1,8 +1,3 @@
1
- /**
2
- * Date Utilities
3
- * Re-exports all date utility modules
4
- */
5
-
6
1
  export type { DateLike } from "./dateUtils.core";
7
2
  export * from "./dateUtils.core";
8
3
  export * from "./dateUtils.compare";
@@ -1,13 +1,5 @@
1
- /**
2
- * Package Period Utilities
3
- * Helper functions for working with subscription periods
4
- */
5
-
6
1
  import type { PurchasesPackage } from "react-native-purchases";
7
2
 
8
- /**
9
- * Get period label from subscription period string
10
- */
11
3
  export const getPeriodLabel = (period: string | null | undefined): string => {
12
4
  if (!period) return "";
13
5
  if (period.includes("Y") || period.includes("year")) return "yearly";
@@ -17,33 +9,21 @@ export const getPeriodLabel = (period: string | null | undefined): string => {
17
9
  return "";
18
10
  };
19
11
 
20
- /**
21
- * Check if a package has a yearly subscription period
22
- */
23
12
  export const isYearlyPackage = (pkg: PurchasesPackage): boolean => {
24
13
  const period = pkg.product.subscriptionPeriod;
25
14
  return period?.includes("Y") || period?.includes("year") || false;
26
15
  };
27
16
 
28
- /**
29
- * Check if a package has a monthly subscription period
30
- */
31
17
  export const isMonthlyPackage = (pkg: PurchasesPackage): boolean => {
32
18
  const period = pkg.product.subscriptionPeriod;
33
19
  return period?.includes("M") || period?.includes("month") || false;
34
20
  };
35
21
 
36
- /**
37
- * Check if a package has a weekly subscription period
38
- */
39
22
  export const isWeeklyPackage = (pkg: PurchasesPackage): boolean => {
40
23
  const period = pkg.product.subscriptionPeriod;
41
24
  return period?.includes("W") || period?.includes("week") || false;
42
25
  };
43
26
 
44
- /**
45
- * Find the first yearly package in an array of packages
46
- */
47
27
  export const findYearlyPackage = (
48
28
  packages: PurchasesPackage[]
49
29
  ): PurchasesPackage | undefined => {
@@ -1,27 +1,12 @@
1
- /**
2
- * Package Type Detector
3
- * Detects subscription package type from RevenueCat package identifier
4
- */
5
-
6
1
  import { PACKAGE_TYPE, type PackageType } from "../domains/subscription/core/SubscriptionConstants";
7
2
 
8
3
  export type SubscriptionPackageType = PackageType;
9
4
 
10
- /**
11
- * Check if identifier is a credit package (consumable purchase)
12
- * Credit packages use a different system and don't need type detection
13
- */
14
5
  export function isCreditPackage(identifier: string): boolean {
15
6
  if (!identifier) return false;
16
- // Matches "credit" as a word or part of a common naming pattern
17
- // More strict to avoid false positives (e.g. "accredited")
18
7
  return /(?:^|[._-])credit(?:$|[._-])/i.test(identifier);
19
8
  }
20
9
 
21
- /**
22
- * Detect package type from product identifier
23
- * Supports common RevenueCat naming patterns with regex for better accuracy
24
- */
25
10
  export function detectPackageType(productIdentifier: string): SubscriptionPackageType {
26
11
  if (!productIdentifier) {
27
12
  return PACKAGE_TYPE.UNKNOWN;
@@ -29,27 +14,22 @@ export function detectPackageType(productIdentifier: string): SubscriptionPackag
29
14
 
30
15
  const normalized = productIdentifier.toLowerCase();
31
16
 
32
- // Skip credit packages silently - they use creditPackageConfig instead
33
17
  if (isCreditPackage(normalized)) {
34
18
  return PACKAGE_TYPE.UNKNOWN;
35
19
  }
36
20
 
37
- // Weekly detection: matches "weekly" or "week" as distinct parts of the ID
38
21
  if (/\bweekly?\b|_week_|-week-|\.week\./i.test(normalized)) {
39
22
  return PACKAGE_TYPE.WEEKLY;
40
23
  }
41
24
 
42
- // Monthly detection: matches "monthly" or "month"
43
25
  if (/\bmonthly?\b|_month_|-month-|\.month\./i.test(normalized)) {
44
26
  return PACKAGE_TYPE.MONTHLY;
45
27
  }
46
28
 
47
- // Yearly detection: matches "yearly", "year", or "annual"
48
29
  if (/\byearly?\b|_year_|-year-|\.year\.|annual/i.test(normalized)) {
49
30
  return PACKAGE_TYPE.YEARLY;
50
31
  }
51
-
52
- // Lifetime detection: matches "lifetime"
32
+
53
33
  if (/\blifetime\b|_lifetime_|-lifetime-|\.lifetime\./i.test(normalized)) {
54
34
  return PACKAGE_TYPE.LIFETIME;
55
35
  }
@@ -1,27 +1,14 @@
1
- /**
2
- * Premium Status Utilities
3
- *
4
- * Core premium status determination logic
5
- */
6
-
7
1
  import type { PremiumStatusFetcher } from './types';
8
2
 
9
-
10
- /**
11
- * Get isPremium value with centralized logic
12
- */
13
3
  export function getIsPremium(
14
4
  isAnonymous: boolean,
15
5
  userId: string | null,
16
6
  isPremiumOrFetcher: boolean | PremiumStatusFetcher,
17
7
  ): Promise<boolean> {
18
- // Anonymous users NEVER have premium
19
8
  if (isAnonymous || userId === null) return Promise.resolve(false);
20
9
 
21
- // Sync mode: return the provided isPremium value
22
10
  if (typeof isPremiumOrFetcher === 'boolean') return Promise.resolve(isPremiumOrFetcher);
23
11
 
24
- // Async mode: fetch premium status
25
12
  return (async () => {
26
13
  try {
27
14
  return await isPremiumOrFetcher.isPremium(userId!);
@@ -31,4 +18,4 @@ export function getIsPremium(
31
18
  );
32
19
  }
33
20
  })();
34
- }
21
+ }
@@ -1,14 +1,3 @@
1
- /**
2
- * Price Formatting Utilities
3
- * Apple App Store Guideline 3.1.2 Compliance
4
- */
5
-
6
- /**
7
- * Format price for display
8
- * @param price - Price value
9
- * @param currencyCode - Currency code (e.g., 'USD', 'EUR')
10
- * @returns Formatted price string
11
- */
12
1
  export function formatPrice(price: number, currencyCode: string): string {
13
2
  try {
14
3
  return new Intl.NumberFormat('en-US', {
@@ -28,35 +17,11 @@ const PERIOD_SUFFIX_MAP: Record<string, string> = {
28
17
  yearly: '/year',
29
18
  };
30
19
 
31
- /**
32
- * Extract billing period suffix from package identifier
33
- * Apple App Store Guideline 3.1.2 Compliance:
34
- * - Displays billing frequency clearly and conspicuously
35
- * - Format: /week, /month, /year
36
- *
37
- * @param identifier - RevenueCat package identifier (e.g., "$rc_weekly", "$rc_monthly", "$rc_annual")
38
- * @returns Billing period suffix (e.g., "/week", "/month", "/year") or empty string
39
- */
40
20
  export function getBillingPeriodSuffix(identifier: string): string {
41
21
  const packageType = detectPackageType(identifier);
42
22
  return PERIOD_SUFFIX_MAP[packageType] ?? '';
43
23
  }
44
24
 
45
- /**
46
- * Format price with billing period
47
- * Apple App Store Guideline 3.1.2 Compliance:
48
- * - Combines price with billing frequency for clear display
49
- * - Format: $2.99/week, $14.99/month, $39.99/year
50
- *
51
- * RevenueCat Best Practice:
52
- * - Follows recommended price_per_period format
53
- * - Clear and conspicuous billing frequency display
54
- *
55
- * @param price - Price value
56
- * @param currencyCode - Currency code (e.g., 'USD', 'EUR')
57
- * @param identifier - RevenueCat package identifier
58
- * @returns Formatted price with billing period (e.g., "$2.99/week")
59
- */
60
25
  export function formatPriceWithPeriod(
61
26
  price: number,
62
27
  currencyCode: string,
@@ -1,12 +1,5 @@
1
- /**
2
- * User Tier Core Utilities
3
- *
4
- * Core logic for determining user tier and premium status
5
- */
6
-
7
1
  import { USER_TIER, type UserTierInfo } from './types';
8
2
 
9
-
10
3
  export function getUserTierInfo(
11
4
  isAnonymous: boolean,
12
5
  userId: string | null,
@@ -38,4 +31,4 @@ export function checkPremiumAccess(
38
31
  ): boolean {
39
32
  if (isAnonymous || userId === null) return false;
40
33
  return isPremium;
41
- }
34
+ }
@@ -1,40 +1,16 @@
1
- /**
2
- * User Tier Types
3
- *
4
- * Type definitions for user tier system
5
- */
6
-
7
1
  import { USER_TIER, type UserTierType } from '../domains/subscription/core/SubscriptionConstants';
8
2
 
9
3
  export type UserTier = UserTierType;
10
4
  export { USER_TIER };
11
5
 
12
6
  export interface UserTierInfo {
13
- /** User tier classification */
14
7
  tier: UserTier;
15
-
16
- /** Whether user has premium access */
17
8
  isPremium: boolean;
18
-
19
- /** Whether user is anonymous (not authenticated) */
20
9
  isAnonymous: boolean;
21
-
22
- /** Whether user is authenticated */
23
10
  isAuthenticated: boolean;
24
-
25
- /** User ID (null for anonymous users) */
26
11
  userId: string | null;
27
12
  }
28
13
 
29
- /**
30
- * Premium status fetcher interface
31
- * Apps should implement this to provide premium status from their database
32
- */
33
14
  export interface PremiumStatusFetcher {
34
- /**
35
- * Check if user has active premium subscription
36
- * @param userId - User ID (never null, this is only called for authenticated users)
37
- * @returns Promise<boolean> - Whether user has premium subscription
38
- */
39
15
  isPremium(userId: string): Promise<boolean>;
40
- }
16
+ }
@@ -1,9 +1,3 @@
1
- /**
2
- * User Tier Validation Utilities
3
- *
4
- * Type guards and validation functions for user tier system
5
- */
6
-
7
1
  import { USER_TIER, type UserTier, type UserTierInfo } from './types';
8
2
 
9
3
  export function isValidUserTier(value: unknown): value is UserTier {
@@ -20,4 +14,4 @@ export function isUserTierInfo(value: unknown): value is UserTierInfo {
20
14
  typeof obj.isAuthenticated === 'boolean' &&
21
15
  (obj.userId === null || typeof obj.userId === 'string')
22
16
  );
23
- }
17
+ }
@@ -1,52 +0,0 @@
1
- # Domains
2
-
3
- Specialized domain modules implementing specific business logic and features.
4
-
5
- ## Location
6
-
7
- `src/domains/`
8
-
9
- ## Strategy
10
-
11
- Implements Domain-Driven Design (DDD) principles with self-contained domains. Each domain includes domain layer (business logic, entities, value objects), infrastructure layer (external integrations, repositories), and presentation layer (domain-specific hooks and components).
12
-
13
- ## Restrictions
14
-
15
- ### REQUIRED
16
-
17
- - Domains MUST NOT directly depend on each other
18
- - MUST use well-defined interfaces between layers
19
- - MUST depend on abstractions, not concretions (Dependency Inversion)
20
- - All domains MUST be testable in isolation
21
-
22
- ### PROHIBITED
23
-
24
- - MUST NOT share domain logic between domains (use shared kernel if needed)
25
- - MUST NOT create circular dependencies between domains
26
- - MUST NOT bypass domain layer from presentation
27
- - MUST NOT expose infrastructure details to other domains
28
-
29
- ### CRITICAL
30
-
31
- - Always validate invariants at domain boundaries
32
- - Always implement domain errors for business rule violations
33
- - Never allow inconsistent domain state
34
- - Must implement proper transaction boundaries
35
- - Always sanitize inputs from external sources
36
-
37
- ## AI Agent Guidelines
38
-
39
- When working with domains:
40
- 1. Always respect domain boundaries
41
- 2. Always use dependency inversion
42
- 3. Always implement domain-specific errors
43
- 4. Always validate invariants at boundaries
44
- 5. Never create circular dependencies
45
-
46
- ## Related Documentation
47
-
48
- - [Wallet Domain](wallet/README.md)
49
- - [Paywall Domain](paywall/README.md)
50
- - [Config Domain](config/README.md)
51
- - [Domain Layer](../domain/README.md)
52
- - [Infrastructure](../infrastructure/README.md)
@@ -1,37 +0,0 @@
1
- # Config Domain
2
-
3
- ## Location
4
- Domain layer for configuration management.
5
-
6
- ## Strategy
7
- This directory contains the business logic and domain models for subscription and feature configuration.
8
-
9
- ## Restrictions
10
-
11
- ### REQUIRED
12
- - Must use entities for domain models
13
- - Must validate in constructor
14
- - Must keep entities immutable
15
-
16
- ### PROHIBITED
17
- - DO NOT bypass entity validation
18
- - DO NOT mutate entities after creation
19
- - DO NOT leak domain logic to application layer
20
-
21
- ### CRITICAL SAFETY
22
- - All business rules MUST be enforced in entities
23
- - Validation failures MUST fail fast
24
- - Type safety MUST be maintained at compile time
25
-
26
- ## AI Agent Guidelines
27
- 1. When creating new configurations, use existing entities
28
- 2. Always validate configuration data through entity constructors
29
- 3. Encapsulate business logic within domain entities
30
- 4. Implement proper equality methods for value objects
31
- 5. Provide formatting methods for display purposes
32
- 6. Maintain strict type safety with TypeScript
33
-
34
- ## Related Documentation
35
- - [Config Domain](../../README.md)
36
- - [Config Entities](./entities/README.md)
37
- - [Config Value Objects](./value-objects/README.md)
@@ -1,41 +0,0 @@
1
- # Config Domain Entities
2
-
3
- ## Location
4
- Domain entities for configuration management.
5
-
6
- ## Strategy
7
- This directory contains entity classes representing configuration concepts like packages, features, and paywalls with strict validation and immutability.
8
-
9
- ## Restrictions
10
-
11
- ### REQUIRED
12
- - Must validate all configuration in constructor
13
- - Must treat entities as immutable
14
- - Must provide clear error messages
15
- - Must use TypeScript strict mode
16
-
17
- ### PROHIBITED
18
- - DO NOT modify entities after creation
19
- - DO NOT bypass validation logic
20
- - DO NOT expose mutable internal state
21
- - DO NOT allow invalid configuration
22
-
23
- ### CRITICAL SAFETY
24
- - All validation MUST happen in constructor
25
- - Entities MUST fail fast on invalid input
26
- - Error messages MUST be descriptive
27
- - Factory functions MUST provide valid defaults
28
-
29
- ## AI Agent Guidelines
30
- 1. Always validate configuration data in entity constructors
31
- 2. Treat all entities as immutable values
32
- 3. Keep business logic encapsulated within entities
33
- 4. Provide factory functions for common configurations
34
- 5. Test validation logic thoroughly
35
- 6. Use TypeScript strict types for all properties
36
- 7. Return descriptive error messages for validation failures
37
-
38
- ## Related Documentation
39
- - [Config Domain](../README.md)
40
- - [Config Value Objects](../value-objects/README.md)
41
- - [Config Utils](../../utils/README.md)
@@ -1,24 +0,0 @@
1
- import { ICreditStrategy, type CreditAllocationParams } from "./ICreditStrategy";
2
-
3
- /**
4
- * Strategy for status synchronization (app open, auth state changes).
5
- * ONLY preserves existing credits. NEVER allocates new credits.
6
- * New credits are ONLY allocated by purchase and renewal flows.
7
- */
8
- export class SyncCreditStrategy implements ICreditStrategy {
9
- canHandle(params: CreditAllocationParams): boolean {
10
- return params.isStatusSync;
11
- }
12
-
13
- execute(params: CreditAllocationParams): number {
14
- // Status sync only preserves existing credits, never allocates new ones
15
- const existingCredits = params.existingData?.credits;
16
- if (typeof existingCredits === 'number' && existingCredits >= 0) {
17
- return existingCredits;
18
- }
19
-
20
- // No existing credits = no document = return 0
21
- // Credits are only allocated through purchase/renewal flows
22
- return 0;
23
- }
24
- }