@umituz/react-native-subscription 2.37.39 → 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 (131) hide show
  1. package/package.json +1 -1
  2. package/src/domains/credits/application/CreditLimitCalculator.ts +1 -9
  3. package/src/domains/credits/application/DeductCreditsCommand.ts +13 -6
  4. package/src/domains/credits/application/RefundCreditsCommand.ts +1 -5
  5. package/src/domains/credits/application/credit-strategies/TrialCreditStrategy.ts +1 -5
  6. package/src/domains/credits/application/creditDocumentHelpers.ts +2 -9
  7. package/src/domains/credits/core/Credits.ts +0 -23
  8. package/src/domains/credits/core/CreditsMapper.ts +0 -6
  9. package/src/domains/credits/core/UserCreditsDocument.ts +0 -12
  10. package/src/domains/credits/infrastructure/CreditsRepositoryManager.ts +0 -21
  11. package/src/domains/credits/infrastructure/operations/CreditsWriter.ts +2 -1
  12. package/src/domains/credits/presentation/deduct-credit/useDeductCredit.ts +2 -2
  13. package/src/domains/credits/presentation/useCredits.ts +10 -9
  14. package/src/domains/paywall/components/PaywallContainer.types.ts +0 -28
  15. package/src/domains/paywall/components/PaywallModal.styles.ts +0 -4
  16. package/src/domains/paywall/entities/types.ts +0 -5
  17. package/src/domains/paywall/hooks/usePaywallActions.ts +1 -15
  18. package/src/domains/revenuecat/core/errors/RevenueCatError.ts +0 -6
  19. package/src/domains/revenuecat/core/errors/RevenueCatErrorHandler.ts +0 -24
  20. package/src/domains/revenuecat/core/errors/RevenueCatErrorMessages.ts +0 -18
  21. package/src/domains/revenuecat/core/errors/index.ts +0 -4
  22. package/src/domains/revenuecat/core/types/RevenueCatConfig.ts +3 -7
  23. package/src/domains/revenuecat/core/types/RevenueCatData.ts +4 -9
  24. package/src/domains/revenuecat/core/types/RevenueCatTypes.ts +5 -65
  25. package/src/domains/revenuecat/core/types/index.ts +0 -4
  26. package/src/domains/revenuecat/infrastructure/services/UserSwitchMutex.ts +1 -24
  27. package/src/domains/subscription/application/SubscriptionAuthListener.ts +5 -21
  28. package/src/domains/subscription/application/SubscriptionInitializerTypes.ts +1 -5
  29. package/src/domains/subscription/application/SubscriptionSyncService.ts +11 -2
  30. package/src/domains/subscription/application/SubscriptionSyncUtils.ts +1 -1
  31. package/src/domains/subscription/application/initializer/BackgroundInitializer.ts +15 -2
  32. package/src/domains/subscription/application/initializer/ServiceConfigurator.ts +9 -2
  33. package/src/domains/subscription/constants/thresholds.ts +0 -9
  34. package/src/domains/subscription/core/SubscriptionConstants.ts +0 -4
  35. package/src/domains/subscription/core/SubscriptionStatus.ts +11 -21
  36. package/src/domains/subscription/core/SubscriptionStatusHandlers.ts +4 -7
  37. package/src/domains/subscription/infrastructure/handlers/PurchaseStatusResolver.ts +1 -1
  38. package/src/domains/subscription/infrastructure/hooks/subscriptionQueryKeys.ts +0 -13
  39. package/src/domains/subscription/infrastructure/hooks/usePurchasePackage.ts +0 -18
  40. package/src/domains/subscription/infrastructure/hooks/useRestorePurchase.ts +3 -17
  41. package/src/domains/subscription/infrastructure/hooks/useRevenueCatTrialEligibility.ts +0 -17
  42. package/src/domains/subscription/infrastructure/hooks/useSubscriptionPackages.ts +0 -19
  43. package/src/domains/subscription/infrastructure/hooks/useSubscriptionQueries.ts +0 -6
  44. package/src/domains/subscription/infrastructure/managers/subscriptionManagerUtils.ts +0 -17
  45. package/src/domains/subscription/infrastructure/state/initializationState.ts +0 -25
  46. package/src/domains/subscription/infrastructure/utils/InitializationCache.ts +0 -21
  47. package/src/domains/subscription/infrastructure/utils/PremiumStatusSyncer.ts +2 -7
  48. package/src/domains/subscription/infrastructure/utils/authPurchaseState.ts +0 -5
  49. package/src/domains/subscription/infrastructure/utils/renewal/PackageTierComparator.ts +1 -0
  50. package/src/domains/subscription/infrastructure/utils/trialEligibilityUtils.ts +0 -18
  51. package/src/domains/subscription/presentation/components/details/PremiumDetailsCard.styles.ts +0 -5
  52. package/src/domains/subscription/presentation/components/details/PremiumDetailsCardTypes.ts +0 -5
  53. package/src/domains/subscription/presentation/components/feedback/paywallFeedbackStyles.ts +0 -5
  54. package/src/domains/subscription/presentation/stores/index.ts +0 -4
  55. package/src/domains/subscription/presentation/stores/purchaseLoadingStore.ts +0 -13
  56. package/src/domains/subscription/presentation/useAuthAwarePurchase.ts +30 -21
  57. package/src/domains/subscription/presentation/usePaywallVisibility.ts +0 -9
  58. package/src/domains/subscription/presentation/useSubscriptionStatus.ts +8 -11
  59. package/src/domains/subscription/utils/authGuards.ts +3 -0
  60. package/src/domains/trial/application/TrialService.ts +0 -9
  61. package/src/domains/trial/core/TrialTypes.ts +0 -8
  62. package/src/domains/wallet/domain/mappers/TransactionMapper.ts +0 -5
  63. package/src/domains/wallet/domain/types/transaction.types.ts +0 -7
  64. package/src/domains/wallet/index.ts +0 -7
  65. package/src/domains/wallet/infrastructure/config/walletConfig.ts +0 -11
  66. package/src/domains/wallet/presentation/hooks/useTransactionHistory.ts +6 -3
  67. package/src/domains/wallet/presentation/hooks/useWallet.ts +0 -7
  68. package/src/domains/wallet/utils/transactionIconMap.ts +0 -10
  69. package/src/global.d.ts +0 -6
  70. package/src/index.ts +1 -4
  71. package/src/init/createSubscriptionInitModule.ts +12 -2
  72. package/src/init/index.ts +1 -5
  73. package/src/presentation/hooks/feedback/useFeedbackSubmit.ts +0 -11
  74. package/src/shared/application/FeedbackService.ts +3 -21
  75. package/src/shared/application/ports/ISubscriptionRepository.ts +0 -4
  76. package/src/shared/infrastructure/SubscriptionEventBus.ts +0 -13
  77. package/src/shared/infrastructure/firestore/collectionUtils.ts +1 -17
  78. package/src/shared/infrastructure/firestore/index.ts +0 -4
  79. package/src/shared/infrastructure/firestore/resultUtils.ts +0 -12
  80. package/src/shared/infrastructure/react-query/hooks/usePreviousUserCleanup.ts +0 -17
  81. package/src/shared/infrastructure/react-query/queryConfig.ts +0 -15
  82. package/src/shared/utils/BaseError.ts +0 -5
  83. package/src/shared/utils/Result.ts +0 -20
  84. package/src/shared/utils/dateConverter.ts +6 -46
  85. package/src/utils/appUtils.ts +0 -16
  86. package/src/utils/creditMapper.ts +0 -7
  87. package/src/utils/dateUtils.compare.ts +0 -24
  88. package/src/utils/dateUtils.core.ts +0 -39
  89. package/src/utils/dateUtils.format.ts +0 -41
  90. package/src/utils/dateUtils.math.ts +0 -41
  91. package/src/utils/dateUtils.ts +0 -5
  92. package/src/utils/packagePeriodUtils.ts +0 -20
  93. package/src/utils/packageTypeDetector.ts +1 -21
  94. package/src/utils/premiumStatusUtils.ts +1 -14
  95. package/src/utils/priceUtils.ts +0 -35
  96. package/src/utils/tierUtils.ts +1 -8
  97. package/src/utils/types.ts +1 -25
  98. package/src/utils/validation.ts +1 -7
  99. package/src/domains/README.md +0 -52
  100. package/src/domains/config/domain/README.md +0 -37
  101. package/src/domains/config/domain/entities/README.md +0 -41
  102. package/src/domains/paywall/README.md +0 -101
  103. package/src/domains/paywall/entities/README.md +0 -40
  104. package/src/domains/paywall/hooks/README.md +0 -41
  105. package/src/domains/subscription/application/syncConstants.ts +0 -1
  106. package/src/domains/subscription/infrastructure/README.md +0 -41
  107. package/src/domains/subscription/infrastructure/config/README.md +0 -49
  108. package/src/domains/subscription/infrastructure/handlers/README.md +0 -41
  109. package/src/domains/subscription/infrastructure/hooks/README.md +0 -50
  110. package/src/domains/subscription/infrastructure/managers/README.md +0 -41
  111. package/src/domains/subscription/infrastructure/services/README.md +0 -42
  112. package/src/domains/subscription/infrastructure/utils/README.md +0 -41
  113. package/src/domains/subscription/presentation/components/README.md +0 -155
  114. package/src/domains/subscription/presentation/components/details/CreditRow.md +0 -92
  115. package/src/domains/subscription/presentation/components/details/DetailRow.md +0 -91
  116. package/src/domains/subscription/presentation/components/details/PremiumDetailsCard.md +0 -93
  117. package/src/domains/subscription/presentation/components/details/PremiumStatusBadge.md +0 -91
  118. package/src/domains/subscription/presentation/components/details/README.md +0 -99
  119. package/src/domains/subscription/presentation/components/feedback/PaywallFeedbackModal.md +0 -90
  120. package/src/domains/subscription/presentation/components/feedback/README.md +0 -99
  121. package/src/domains/subscription/presentation/components/paywall/PaywallModal.md +0 -94
  122. package/src/domains/subscription/presentation/components/paywall/README.md +0 -54
  123. package/src/domains/subscription/presentation/components/sections/README.md +0 -99
  124. package/src/domains/subscription/presentation/components/sections/SubscriptionSection.md +0 -94
  125. package/src/domains/subscription/presentation/utils/README.md +0 -31
  126. package/src/domains/wallet/README.md +0 -51
  127. package/src/domains/wallet/domain/README.md +0 -41
  128. package/src/domains/wallet/infrastructure/README.md +0 -41
  129. package/src/domains/wallet/presentation/components/README.md +0 -41
  130. package/src/domains/wallet/presentation/hooks/README.md +0 -41
  131. package/src/shared/application/ports/README.md +0 -48
@@ -1,11 +1,11 @@
1
1
  import { useQuery, useQueryClient } from "@umituz/react-native-design-system";
2
2
  import { useEffect, useSyncExternalStore } from "react";
3
- import { useAuthStore, selectUserId } from "@umituz/react-native-auth";
3
+ import { useAuthStore, selectUserId, selectIsAnonymous } from "@umituz/react-native-auth";
4
4
  import { SubscriptionManager } from "../infrastructure/managers/SubscriptionManager";
5
5
  import { initializationState } from "../infrastructure/state/initializationState";
6
6
  import { subscriptionEventBus, SUBSCRIPTION_EVENTS } from "../../../shared/infrastructure/SubscriptionEventBus";
7
7
  import { SubscriptionStatusResult } from "./useSubscriptionStatus.types";
8
- import { isAuthenticated } from "../utils/authGuards";
8
+ import { isRegisteredUser } from "../utils/authGuards";
9
9
  import { NO_CACHE_QUERY_CONFIG } from "../../../shared/infrastructure/react-query/queryConfig";
10
10
  import { usePreviousUserCleanup } from "../../../shared/infrastructure/react-query/hooks/usePreviousUserCleanup";
11
11
 
@@ -17,32 +17,30 @@ export const subscriptionStatusQueryKeys = {
17
17
 
18
18
  export const useSubscriptionStatus = (): SubscriptionStatusResult => {
19
19
  const userId = useAuthStore(selectUserId);
20
+ const isAnonymous = useAuthStore(selectIsAnonymous);
20
21
  const queryClient = useQueryClient();
21
22
  const isConfigured = SubscriptionManager.isConfigured();
23
+ const isUserRegistered = isRegisteredUser(userId, isAnonymous);
22
24
 
23
- // Reactive initialization state - triggers re-render when BackgroundInitializer completes
24
25
  const initState = useSyncExternalStore(
25
26
  initializationState.subscribe,
26
27
  initializationState.getSnapshot,
27
28
  initializationState.getSnapshot,
28
29
  );
29
30
 
30
- // Check if initialized for this specific user (reactive)
31
31
  const isInitialized = userId
32
32
  ? initState.initialized && initState.userId === userId
33
33
  : false;
34
34
 
35
- const queryEnabled = isAuthenticated(userId) && isConfigured && isInitialized;
35
+ const queryEnabled = isUserRegistered && isConfigured && isInitialized;
36
36
 
37
37
  const { data, status, error, refetch } = useQuery({
38
38
  queryKey: subscriptionStatusQueryKeys.user(userId),
39
39
  queryFn: async () => {
40
- if (!isAuthenticated(userId)) {
40
+ if (!isUserRegistered) {
41
41
  return null;
42
42
  }
43
43
 
44
- // No side effects - just check premium status
45
- // Initialization is handled by BackgroundInitializer
46
44
  try {
47
45
  const result = await SubscriptionManager.checkPremiumStatus();
48
46
  return result;
@@ -54,11 +52,10 @@ export const useSubscriptionStatus = (): SubscriptionStatusResult => {
54
52
  ...NO_CACHE_QUERY_CONFIG,
55
53
  });
56
54
 
57
- // Clean up previous user's cache on logout/user switch
58
55
  usePreviousUserCleanup(userId, queryClient, subscriptionStatusQueryKeys.user);
59
56
 
60
57
  useEffect(() => {
61
- if (!isAuthenticated(userId)) return undefined;
58
+ if (!isUserRegistered) return undefined;
62
59
 
63
60
  const unsubscribe = subscriptionEventBus.on(
64
61
  SUBSCRIPTION_EVENTS.PREMIUM_STATUS_CHANGED,
@@ -72,7 +69,7 @@ export const useSubscriptionStatus = (): SubscriptionStatusResult => {
72
69
  );
73
70
 
74
71
  return unsubscribe;
75
- }, [userId, queryClient]);
72
+ }, [userId, isUserRegistered, queryClient]);
76
73
 
77
74
  const isLoading = status === "pending";
78
75
 
@@ -4,3 +4,6 @@ export function isAuthenticated(userId: string | null | undefined): userId is st
4
4
  return isDefined(userId) && userId.length > 0;
5
5
  }
6
6
 
7
+ export function isRegisteredUser(userId: string | null | undefined, isAnonymous: boolean): userId is string {
8
+ return isAuthenticated(userId) && !isAnonymous;
9
+ }
@@ -1,7 +1,3 @@
1
- /**
2
- * Trial Service - Facade for device-based trial tracking
3
- */
4
-
5
1
  import { arrayUnion, type FieldValue } from "firebase/firestore";
6
2
  import { serverTimestamp } from "@umituz/react-native-firebase";
7
3
  import { PersistentDeviceIdService } from "@umituz/react-native-design-system";
@@ -10,7 +6,6 @@ import { TrialEligibilityService } from "./TrialEligibilityService";
10
6
  import type { TrialEligibilityResult } from "../core/TrialTypes";
11
7
  export type { TrialEligibilityResult };
12
8
 
13
- // Type for Firestore write operations with FieldValue
14
9
  interface TrialRecordWrite {
15
10
  deviceId?: string;
16
11
  hasUsedTrial?: boolean;
@@ -26,10 +21,6 @@ const repository = new DeviceTrialRepository();
26
21
 
27
22
  export const getDeviceId = () => PersistentDeviceIdService.getDeviceId();
28
23
 
29
- /**
30
- * Ensures a valid device ID is available
31
- * Uses provided deviceId if non-empty, otherwise fetches from PersistentDeviceIdService
32
- */
33
24
  async function ensureDeviceId(deviceId?: string): Promise<string> {
34
25
  return (deviceId && deviceId.length > 0) ? deviceId : await getDeviceId();
35
26
  }
@@ -1,15 +1,8 @@
1
- /**
2
- * Trial Types and Constants
3
- * Device-based trial tracking types
4
- */
5
-
6
- /** Trial constants */
7
1
  export const TRIAL_CONFIG = {
8
2
  DURATION_DAYS: 3,
9
3
  CREDITS: 0,
10
4
  } as const;
11
5
 
12
- /** Device trial record in Firestore */
13
6
  export interface DeviceTrialRecord {
14
7
  deviceId: string;
15
8
  hasUsedTrial: boolean;
@@ -23,7 +16,6 @@ export interface DeviceTrialRecord {
23
16
  updatedAt: Date;
24
17
  }
25
18
 
26
- /** Trial eligibility result */
27
19
  export interface TrialEligibilityResult {
28
20
  eligible: boolean;
29
21
  reason?: "already_used" | "device_not_found" | "error" | "user_already_used";
@@ -1,8 +1,3 @@
1
- /**
2
- * Transaction Mapper
3
- * Maps Firestore data to CreditLog entity
4
- */
5
-
6
1
  import type { QueryDocumentSnapshot, DocumentData } from "firebase/firestore";
7
2
  import type { CreditLog } from "../types/transaction.types";
8
3
 
@@ -1,10 +1,3 @@
1
- /**
2
- * Transaction Types
3
- *
4
- * Types for credit transaction history and logs.
5
- * Generic types for use across hundreds of apps.
6
- */
7
-
8
1
  export type TransactionReason =
9
2
  | "purchase"
10
3
  | "usage"
@@ -1,10 +1,3 @@
1
- /**
2
- * Wallet Domain
3
- *
4
- * Public API for wallet functionality.
5
- */
6
-
7
- // Screens
8
1
  export {
9
2
  WalletScreen,
10
3
  } from "./presentation/screens/WalletScreen";
@@ -1,13 +1,5 @@
1
- /**
2
- * Wallet Configuration
3
- *
4
- * Global configuration for wallet feature.
5
- * Set once at app init, used by WalletScreen automatically.
6
- */
7
-
8
1
  import type { WalletScreenTranslations } from "../../presentation/screens/WalletScreen.types";
9
2
 
10
-
11
3
  interface WalletConfiguration {
12
4
  translations: WalletScreenTranslations;
13
5
  transactionCollection: string;
@@ -41,9 +33,6 @@ const DEFAULT_CONFIG: WalletConfiguration = {
41
33
 
42
34
  let walletConfig: WalletConfiguration = { ...DEFAULT_CONFIG };
43
35
 
44
- /**
45
- * Get current wallet configuration
46
- */
47
36
  export function getWalletConfig(): WalletConfiguration {
48
37
  return walletConfig;
49
38
  }
@@ -1,6 +1,6 @@
1
1
  import { useQuery } from "@umituz/react-native-design-system";
2
2
  import { useMemo } from "react";
3
- import { useAuthStore, selectUserId } from "@umituz/react-native-auth";
3
+ import { useAuthStore, selectUserId, selectIsAnonymous } from "@umituz/react-native-auth";
4
4
  import { NO_CACHE_QUERY_CONFIG } from "../../../../shared/infrastructure/react-query/queryConfig";
5
5
  import type {
6
6
  CreditLog,
@@ -31,16 +31,19 @@ export function useTransactionHistory({
31
31
  limit = 50,
32
32
  }: UseTransactionHistoryParams): UseTransactionHistoryResult {
33
33
  const userId = useAuthStore(selectUserId);
34
+ const isAnonymous = useAuthStore(selectIsAnonymous);
34
35
 
35
36
  const repository = useMemo(
36
37
  () => new TransactionRepository(config),
37
38
  [config]
38
39
  );
39
40
 
41
+ const isUserRegistered = !!userId && !isAnonymous;
42
+
40
43
  const { data, isLoading, error, refetch } = useQuery({
41
44
  queryKey: [...transactionQueryKeys.user(userId ?? ""), limit],
42
45
  queryFn: async () => {
43
- if (!userId) return [];
46
+ if (!userId || isAnonymous) return [];
44
47
 
45
48
  const result = await repository.getTransactions({
46
49
  userId,
@@ -53,7 +56,7 @@ export function useTransactionHistory({
53
56
 
54
57
  return result.data ?? [];
55
58
  },
56
- enabled: !!userId,
59
+ enabled: isUserRegistered,
57
60
  ...NO_CACHE_QUERY_CONFIG,
58
61
  });
59
62
 
@@ -1,10 +1,3 @@
1
- /**
2
- * useWallet Hook
3
- *
4
- * Orchestration hook for wallet functionality.
5
- * Combines balance, transactions, and purchase state.
6
- */
7
-
8
1
  import { useCallback, useMemo } from "react";
9
2
  import { useCredits } from "../../../credits/presentation/useCredits";
10
3
  import {
@@ -1,8 +1,3 @@
1
- /**
2
- * Transaction Icon Mapping Utility
3
- * Maps transaction reasons to their corresponding icons
4
- */
5
-
6
1
  import type { TransactionReason } from "../domain/types/transaction.types";
7
2
 
8
3
  const ICON_MAP: Record<TransactionReason, string> = {
@@ -16,11 +11,6 @@ const ICON_MAP: Record<TransactionReason, string> = {
16
11
  expired: "clock",
17
12
  };
18
13
 
19
- /**
20
- * Get icon name for a transaction reason
21
- * @param reason - Transaction reason type
22
- * @returns Icon name for the transaction
23
- */
24
14
  export function getTransactionIcon(reason: TransactionReason): string {
25
15
  return ICON_MAP[reason] || "circle";
26
16
  }
package/src/global.d.ts CHANGED
@@ -1,11 +1,5 @@
1
- /**
2
- * Global type declarations for React Native environment
3
- */
4
-
5
- /** React Native development flag */
6
1
  declare const __DEV__: boolean;
7
2
 
8
- /** Extend NodeJS namespace for React Native compatibility */
9
3
  declare namespace NodeJS {
10
4
  interface Global {
11
5
  __DEV__: boolean;
package/src/index.ts CHANGED
@@ -1,7 +1,3 @@
1
- /**
2
- * React Native Subscription - Public API
3
- */
4
-
5
1
  // Domain Layer - Constants & Types
6
2
  export * from "./domains/subscription/core/SubscriptionConstants";
7
3
  export {
@@ -112,6 +108,7 @@ export type { PurchaseLoadingOverlayProps } from "./domains/subscription/present
112
108
  // Init Module Factory
113
109
  export {
114
110
  createSubscriptionInitModule,
111
+ cleanupSubscriptionModule,
115
112
  type SubscriptionInitModuleConfig,
116
113
  } from './init';
117
114
 
@@ -7,6 +7,15 @@ export interface SubscriptionInitModuleConfig extends Omit<SubscriptionInitConfi
7
7
  dependsOn?: string[];
8
8
  }
9
9
 
10
+ let subscriptionCleanup: (() => void) | null = null;
11
+
12
+ export function cleanupSubscriptionModule(): void {
13
+ if (subscriptionCleanup) {
14
+ subscriptionCleanup();
15
+ subscriptionCleanup = null;
16
+ }
17
+ }
18
+
10
19
  export function createSubscriptionInitModule(config: SubscriptionInitModuleConfig): InitModule {
11
20
  const { getApiKey, critical = false, dependsOn = ['auth'], ...subscriptionConfig } = config;
12
21
 
@@ -21,9 +30,10 @@ export function createSubscriptionInitModule(config: SubscriptionInitModuleConfi
21
30
  return true;
22
31
  }
23
32
 
24
- await initializeSubscription({ apiKey, ...subscriptionConfig });
33
+ subscriptionCleanup = await initializeSubscription({ apiKey, ...subscriptionConfig });
25
34
  return true;
26
- } catch {
35
+ } catch (error) {
36
+ console.error('[SubscriptionInitModule] Initialization failed:', error instanceof Error ? error.message : String(error));
27
37
  return false;
28
38
  }
29
39
  },
package/src/init/index.ts CHANGED
@@ -1,9 +1,5 @@
1
- /**
2
- * Subscription Init Module
3
- * Provides factory for creating app initialization modules
4
- */
5
-
6
1
  export {
7
2
  createSubscriptionInitModule,
3
+ cleanupSubscriptionModule,
8
4
  type SubscriptionInitModuleConfig,
9
5
  } from './createSubscriptionInitModule';
@@ -1,8 +1,3 @@
1
- /**
2
- * Feedback Submit Hooks
3
- * React hooks for submitting feedback to Firestore
4
- */
5
-
6
1
  import { useCallback } from "react";
7
2
  import { useAuth } from "@umituz/react-native-auth";
8
3
  import {
@@ -16,9 +11,6 @@ export interface UsePaywallFeedbackSubmitOptions {
16
11
  onComplete?: () => void;
17
12
  }
18
13
 
19
- /**
20
- * Hook for submitting paywall decline feedback
21
- */
22
14
  export function usePaywallFeedbackSubmit(
23
15
  options: UsePaywallFeedbackSubmitOptions = {}
24
16
  ) {
@@ -63,9 +55,6 @@ export interface UseSettingsFeedbackSubmitOptions {
63
55
  onError?: (error: Error) => void;
64
56
  }
65
57
 
66
- /**
67
- * Hook for submitting general settings feedback
68
- */
69
58
  export function useSettingsFeedbackSubmit(
70
59
  options: UseSettingsFeedbackSubmitOptions = {}
71
60
  ) {
@@ -1,11 +1,5 @@
1
- /**
2
- * Feedback Service
3
- * Handles feedback submission to Firestore
4
- * Feedback is stored under users/{userId}/feedback/{feedbackId}
5
- */
6
-
7
1
  import { collection, addDoc, doc } from "firebase/firestore";
8
- import { getFirestore } from "@umituz/react-native-firebase";
2
+ import { getFirestore, serverTimestamp } from "@umituz/react-native-firebase";
9
3
 
10
4
  interface FeedbackData {
11
5
  userId: string | null;
@@ -22,10 +16,6 @@ export interface FeedbackSubmitResult {
22
16
  error?: Error;
23
17
  }
24
18
 
25
- /**
26
- * Submit feedback to Firestore
27
- * Stores under users/{userId}/feedback
28
- */
29
19
  async function submitFeedback(
30
20
  data: FeedbackData
31
21
  ): Promise<FeedbackSubmitResult> {
@@ -40,8 +30,6 @@ async function submitFeedback(
40
30
  }
41
31
 
42
32
  try {
43
- const now = new Date().toISOString();
44
-
45
33
  const userDocRef = doc(db, "users", data.userId);
46
34
  const feedbackCollectionRef = collection(userDocRef, "feedback");
47
35
 
@@ -52,8 +40,8 @@ async function submitFeedback(
52
40
  description: data.description,
53
41
  rating: data.rating ?? null,
54
42
  status: data.status ?? "pending",
55
- createdAt: now,
56
- updatedAt: now,
43
+ createdAt: serverTimestamp(),
44
+ updatedAt: serverTimestamp(),
57
45
  });
58
46
 
59
47
  return { success: true };
@@ -65,9 +53,6 @@ async function submitFeedback(
65
53
  }
66
54
  }
67
55
 
68
- /**
69
- * Submit paywall decline feedback
70
- */
71
56
  export async function submitPaywallFeedback(
72
57
  userId: string | null,
73
58
  userEmail: string | null,
@@ -82,9 +67,6 @@ export async function submitPaywallFeedback(
82
67
  });
83
68
  }
84
69
 
85
- /**
86
- * Submit general settings feedback
87
- */
88
70
  export async function submitSettingsFeedback(
89
71
  userId: string | null,
90
72
  userEmail: string | null,
@@ -1,7 +1,3 @@
1
- /**
2
- * ISubscriptionRepository Interface
3
- */
4
-
5
1
  import { SubscriptionStatus } from '../../../domains/subscription/core/SubscriptionStatus';
6
2
 
7
3
  export interface ISubscriptionRepository {
@@ -1,9 +1,5 @@
1
1
  type EventCallback<T = unknown> = (data: T) => void;
2
2
 
3
- /**
4
- * Simple EventBus Implementation
5
- * Used to decouple services and provide an observer pattern for subscription events.
6
- */
7
3
  class SubscriptionEventBus {
8
4
  private static instance: SubscriptionEventBus;
9
5
  private listeners: Record<string, EventCallback<any>[]> = {};
@@ -23,13 +19,11 @@ class SubscriptionEventBus {
23
19
  }
24
20
  this.listeners[event].push(callback);
25
21
 
26
- // Return unsubscribe function
27
22
  return () => {
28
23
  const listeners = this.listeners[event];
29
24
  if (listeners) {
30
25
  this.listeners[event] = listeners.filter(l => l !== callback);
31
26
 
32
- // Clean up empty event arrays to prevent memory leak
33
27
  if (this.listeners[event].length === 0) {
34
28
  delete this.listeners[event];
35
29
  }
@@ -53,10 +47,6 @@ class SubscriptionEventBus {
53
47
  });
54
48
  }
55
49
 
56
- /**
57
- * Clear all listeners for a specific event or all events
58
- * Useful for cleanup during testing or app state reset
59
- */
60
50
  clear(event?: string): void {
61
51
  if (event) {
62
52
  delete this.listeners[event];
@@ -65,9 +55,6 @@ class SubscriptionEventBus {
65
55
  }
66
56
  }
67
57
 
68
- /**
69
- * Get listener count for debugging
70
- */
71
58
  getListenerCount(event?: string): number {
72
59
  if (event) {
73
60
  return this.listeners[event]?.length ?? 0;
@@ -1,8 +1,3 @@
1
- /**
2
- * Firestore Collection Utilities
3
- * Shared utilities for building Firestore collection and document references
4
- */
5
-
6
1
  import { collection, doc } from "firebase/firestore";
7
2
  import {
8
3
  getFirestore,
@@ -16,10 +11,6 @@ export interface CollectionConfig {
16
11
  useUserSubcollection: boolean;
17
12
  }
18
13
 
19
- /**
20
- * Build a collection reference based on configuration
21
- * Supports both root collections and user subcollections
22
- */
23
14
  export function buildCollectionRef(
24
15
  db: Firestore,
25
16
  userId: string,
@@ -31,10 +22,6 @@ export function buildCollectionRef(
31
22
  return collection(db, config.collectionName);
32
23
  }
33
24
 
34
- /**
35
- * Build a document reference based on configuration
36
- * Supports both root collections and user subcollections
37
- */
38
25
  export function buildDocRef(
39
26
  db: Firestore,
40
27
  userId: string,
@@ -44,12 +31,9 @@ export function buildDocRef(
44
31
  if (config.useUserSubcollection) {
45
32
  return doc(db, "users", userId, config.collectionName, docId);
46
33
  }
47
- return doc(db, config.collectionName, docId);
34
+ return doc(db, config.collectionName, userId);
48
35
  }
49
36
 
50
- /**
51
- * Get Firestore instance or throw error
52
- */
53
37
  export function requireFirestore(): Firestore {
54
38
  const db = getFirestore();
55
39
  if (!db) {
@@ -1,6 +1,2 @@
1
- /**
2
- * Firestore Infrastructure Utilities
3
- */
4
-
5
1
  export * from "./collectionUtils";
6
2
  export * from "./resultUtils";
@@ -1,8 +1,3 @@
1
- /**
2
- * Result Utilities
3
- * Shared helpers for working with Result pattern
4
- */
5
-
6
1
  import type { Result } from "../../utils/Result";
7
2
  import { failure } from "../../utils/Result";
8
3
 
@@ -11,9 +6,6 @@ interface ApiError {
11
6
  code: string;
12
7
  }
13
8
 
14
- /**
15
- * Create a standard error result
16
- */
17
9
  function createErrorResult(
18
10
  message: string,
19
11
  code: string = "UNKNOWN_ERROR"
@@ -21,12 +13,8 @@ function createErrorResult(
21
13
  return failure({ message, code });
22
14
  }
23
15
 
24
- /**
25
- * Map Error to ApiError result
26
- */
27
16
  export function mapErrorToResult<T>(error: unknown): Result<T, ApiError> {
28
17
  const message = error instanceof Error ? error.message : "An unknown error occurred";
29
18
  const code = error instanceof Error && "code" in error ? String(error.code) : "UNKNOWN_ERROR";
30
19
  return createErrorResult(message, code);
31
20
  }
32
-
@@ -1,23 +1,7 @@
1
- /**
2
- * User Cache Cleanup Hook
3
- * Automatically cleans up previous user's query cache when userId changes
4
- */
5
-
6
1
  import { useEffect, useRef } from "react";
7
2
  import type { QueryClient } from "@umituz/react-native-design-system";
8
3
  import { isAuthenticated } from "../../../../domains/subscription/utils/authGuards";
9
4
 
10
- /**
11
- * Cleans up previous user's cache when userId changes (logout or user switch)
12
- * Prevents data leakage between users
13
- *
14
- * @param userId - Current user ID
15
- * @param queryClient - TanStack Query client
16
- * @param queryKey - Query key factory function that takes userId
17
- *
18
- * @example
19
- * usePreviousUserCleanup(userId, queryClient, (id) => creditsQueryKeys.user(id));
20
- */
21
5
  export function usePreviousUserCleanup(
22
6
  userId: string | null | undefined,
23
7
  queryClient: QueryClient,
@@ -29,7 +13,6 @@ export function usePreviousUserCleanup(
29
13
  const prevUserId = prevUserIdRef.current;
30
14
  prevUserIdRef.current = userId;
31
15
 
32
- // Clear previous user's cache when userId changes (logout or user switch)
33
16
  if (prevUserId !== userId && isAuthenticated(prevUserId)) {
34
17
  queryClient.removeQueries({
35
18
  queryKey: queryKey(prevUserId),
@@ -1,18 +1,3 @@
1
- /**
2
- * Shared TanStack Query Configuration
3
- * Common query configurations to ensure consistency across hooks
4
- */
5
-
6
- /**
7
- * Configuration for queries that should never cache
8
- * Used for real-time sensitive data (subscriptions, credits, transactions)
9
- *
10
- * - gcTime: 0 - Don't keep unused data in memory
11
- * - staleTime: 0 - Always consider data stale
12
- * - refetchOnMount: "always" - Always refetch when component mounts
13
- * - refetchOnWindowFocus: "always" - Always refetch when window regains focus
14
- * - refetchOnReconnect: "always" - Always refetch when reconnecting
15
- */
16
1
  export const NO_CACHE_QUERY_CONFIG = {
17
2
  gcTime: 0,
18
3
  staleTime: 0,
@@ -1,8 +1,3 @@
1
- /**
2
- * Base Error Class
3
- * Common base error for all domain errors
4
- */
5
-
6
1
  export abstract class BaseError extends Error {
7
2
  public readonly code: string;
8
3
  public readonly cause?: Error;