@umituz/react-native-subscription 2.26.13 → 2.26.15

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 (39) hide show
  1. package/package.json +1 -1
  2. package/src/domains/paywall/components/PaywallModal.tsx +36 -13
  3. package/src/domains/paywall/components/PlanCard.tsx +16 -3
  4. package/src/domains/paywall/entities/types.ts +4 -0
  5. package/src/domains/paywall/hooks/usePaywallTranslations.ts +8 -0
  6. package/src/presentation/hooks/index.ts +0 -15
  7. package/src/presentation/hooks/useFeatureGate.ts +41 -116
  8. package/src/revenuecat/domain/types/RevenueCatTypes.ts +32 -0
  9. package/src/revenuecat/index.ts +1 -0
  10. package/src/revenuecat/presentation/hooks/useRevenueCatTrialEligibility.ts +179 -0
  11. package/src/presentation/hooks/useAuthAwarePurchase.md +0 -92
  12. package/src/presentation/hooks/useAuthAwarePurchase.ts +0 -138
  13. package/src/presentation/hooks/useAuthGate.md +0 -89
  14. package/src/presentation/hooks/useAuthGate.ts +0 -65
  15. package/src/presentation/hooks/useCreditChecker.md +0 -102
  16. package/src/presentation/hooks/useCreditChecker.ts +0 -41
  17. package/src/presentation/hooks/useCreditsGate.md +0 -94
  18. package/src/presentation/hooks/useCreditsGate.ts +0 -81
  19. package/src/presentation/hooks/useDevTestCallbacks.md +0 -91
  20. package/src/presentation/hooks/useDevTestCallbacks.ts +0 -142
  21. package/src/presentation/hooks/useInitializeCredits.md +0 -92
  22. package/src/presentation/hooks/useInitializeCredits.ts +0 -57
  23. package/src/presentation/hooks/usePremiumGate.md +0 -88
  24. package/src/presentation/hooks/usePremiumGate.ts +0 -116
  25. package/src/presentation/hooks/usePremiumWithCredits.md +0 -92
  26. package/src/presentation/hooks/usePremiumWithCredits.ts +0 -48
  27. package/src/presentation/hooks/useSubscription.md +0 -94
  28. package/src/presentation/hooks/useSubscription.ts +0 -119
  29. package/src/presentation/hooks/useSubscriptionDetails.md +0 -93
  30. package/src/presentation/hooks/useSubscriptionDetails.ts +0 -85
  31. package/src/presentation/hooks/useSubscriptionGate.md +0 -84
  32. package/src/presentation/hooks/useSubscriptionGate.ts +0 -67
  33. package/src/presentation/hooks/useSubscriptionStatus.md +0 -94
  34. package/src/presentation/hooks/useSubscriptionStatus.ts +0 -64
  35. package/src/presentation/hooks/useTrialEligibility.ts +0 -66
  36. package/src/presentation/hooks/useUserTier.md +0 -91
  37. package/src/presentation/hooks/useUserTier.ts +0 -78
  38. package/src/presentation/hooks/useUserTierWithRepository.md +0 -92
  39. package/src/presentation/hooks/useUserTierWithRepository.ts +0 -151
@@ -1,91 +0,0 @@
1
- # useDevTestCallbacks Hook
2
-
3
- **Development-only** hook for testing subscription renewal and credit operations.
4
-
5
- ## Location
6
-
7
- **Import Path**: `@umituz/react-native-subscription`
8
-
9
- **File**: `src/presentation/hooks/useDevTestCallbacks.ts`
10
-
11
- **Type**: Hook
12
-
13
- ## Strategy
14
-
15
- ### Development Testing Utilities
16
-
17
- 1. **Renewal Simulation**: Simulate subscription renewal with credit allocation
18
- 2. **Credits Inspection**: Display current credit balance and purchase date
19
- 3. **Duplicate Protection Testing**: Test that duplicate renewals are prevented
20
- 4. **Development Mode Guard**: Only available in `__DEV__` mode
21
- 5. **Production Safety**: Returns `undefined` in production builds
22
- 6. **Alert-Based Feedback**: Show test results in alert dialogs
23
-
24
- ### Integration Points
25
-
26
- - **useInitializeCredits**: For credit initialization testing
27
- - **Credits Repository**: `src/domains/wallet/infrastructure/repositories/CreditsRepository.ts`
28
- - **Development Tools**: For testing and debugging
29
- - **Alert API**: For displaying test results
30
-
31
- ## Restrictions
32
-
33
- ### REQUIRED
34
-
35
- - **Development Only**: MUST only use in `__DEV__` mode
36
- - **Guard Checks**: MUST check if hook returns undefined
37
- - **Visual Distinction**: SHOULD make dev tools visually distinct
38
- - **Documentation**: MUST document behavior for other developers
39
-
40
- ### PROHIBITED
41
-
42
- - **NEVER** use in production code paths
43
- - **NEVER** ship dev UI to production
44
- - **DO NOT** rely on dev tools for production features
45
- - **DO NOT** expose dev functionality to end users
46
-
47
- ### CRITICAL SAFETY
48
-
49
- - **ALWAYS** guard with `__DEV__` checks
50
- - **NEVER** call hook functions in production
51
- - **MUST** remove or disable before release
52
- - **ALWAYS** test that dev tools don't affect production
53
-
54
- ## AI Agent Guidelines
55
-
56
- ### When Implementing Development Testing
57
-
58
- 1. **Always** guard with `__DEV__` checks
59
- 2. **Always** check if hook returns undefined
60
- 3. **Always** make dev tools visually distinct
61
- 4. **Never** expose dev tools to production users
62
- 5. **Always** document development-only behavior
63
-
64
- ### Integration Checklist
65
-
66
- - [ ] Import from correct path: `@umituz/react-native-subscription`
67
- - [ ] Guard with `__DEV__` check
68
- - [ ] Check if hook returns undefined
69
- - [ ] Make dev UI visually distinct
70
- - [ ] Test renewal simulation
71
- - [ ] Test credits inspection
72
- - [ ] Test duplicate protection
73
- - [ ] Verify undefined returned in production
74
- - [ ] Remove or disable before release
75
-
76
- ### Common Patterns
77
-
78
- 1. **Dev Test Panel**: Dedicated screen for testing
79
- 2. **Settings Integration**: Add dev tools to settings screen
80
- 3. **Debug Menu**: Hidden menu for testing
81
- 4. **Flow Testing**: Test complete renewal flows
82
- 5. **Edge Case Testing**: Test duplicate handling and errors
83
-
84
- ## Related Documentation
85
-
86
- - **useCredits**: For accessing credits balance
87
- - **useInitializeCredits**: For credit initialization
88
- - **usePremiumWithCredits**: For premium + credits integration
89
- - **Credits README**: `src/domains/wallet/README.md`
90
- - **Renewal Testing Guide**: `src/docs/RENEWAL_TESTING.md`
91
- - **Development Tools**: `src/docs/DEV_TOOLS.md`
@@ -1,142 +0,0 @@
1
- /**
2
- * Dev Test Callbacks Hook
3
- * Provides test functions for subscription renewal testing
4
- * Only used in __DEV__ mode
5
- */
6
-
7
- import { useCallback } from "react";
8
- import { Alert } from "react-native";
9
- import { useAuth } from "@umituz/react-native-auth";
10
- import { getCreditsRepository } from "../../infrastructure/repositories/CreditsRepositoryProvider";
11
- import { useCredits } from "./useCredits";
12
- import type { DevTestActions } from "../screens/components/DevTestSection";
13
-
14
- export const useDevTestCallbacks = (): DevTestActions | undefined => {
15
- const { user } = useAuth();
16
- const { credits, refetch } = useCredits({ userId: user?.uid });
17
-
18
- const onTestRenewal = useCallback(async () => {
19
- if (!user?.uid) {
20
- Alert.alert("Error", "No user logged in");
21
- return;
22
- }
23
-
24
- try {
25
- const repository = getCreditsRepository();
26
- const renewalId = `dev_renewal_${Date.now()}`;
27
- const productId = "test_yearly_subscription";
28
-
29
- if (__DEV__) {
30
- console.log("🧪 [Dev Test] Simulating auto-renewal...", {
31
- userId: user.uid,
32
- renewalId,
33
- });
34
- }
35
-
36
- const result = await repository.initializeCredits(
37
- user.uid,
38
- renewalId,
39
- productId,
40
- );
41
-
42
- if (__DEV__) {
43
- console.log("✅ [Dev Test] Renewal completed:", {
44
- success: result.success,
45
- credits: result.data?.credits,
46
- });
47
- }
48
-
49
- await refetch();
50
-
51
- Alert.alert(
52
- "✅ Test Renewal Success",
53
- `Credits Updated!\n\nNew Balance: ${result.data?.credits || 0}\n\n(ACCUMULATE mode - credits added to existing)`,
54
- [{ text: "OK" }],
55
- );
56
- } catch (error) {
57
- if (__DEV__) {
58
- console.error("❌ [Dev Test] Renewal failed:", error);
59
- }
60
- Alert.alert(
61
- "Test Failed",
62
- error instanceof Error ? error.message : "Unknown error",
63
- );
64
- }
65
- }, [user?.uid, refetch]);
66
-
67
- const onCheckCredits = useCallback(() => {
68
- if (!credits) {
69
- Alert.alert("Credits", "No credits data available");
70
- return;
71
- }
72
-
73
- Alert.alert(
74
- "📊 Current Credits",
75
- `Credits: ${credits.credits}\n\nPurchased: ${credits.purchasedAt?.toLocaleDateString() || "N/A"}`,
76
- [{ text: "OK" }],
77
- );
78
- }, [credits]);
79
-
80
- const onTestDuplicate = useCallback(async () => {
81
- if (!user?.uid) {
82
- Alert.alert("Error", "No user logged in");
83
- return;
84
- }
85
-
86
- try {
87
- const repository = getCreditsRepository();
88
- const sameRenewalId = "dev_duplicate_test_12345";
89
-
90
- if (__DEV__) {
91
- console.log("🧪 [Dev Test] Testing duplicate protection...");
92
- }
93
-
94
- const result1 = await repository.initializeCredits(
95
- user.uid,
96
- sameRenewalId,
97
- "test_product",
98
- );
99
- if (__DEV__) {
100
- console.log("First call:", result1.data);
101
- }
102
-
103
- const result2 = await repository.initializeCredits(
104
- user.uid,
105
- sameRenewalId,
106
- "test_product",
107
- );
108
- if (__DEV__) {
109
- console.log("Second call:", result2.data);
110
- }
111
-
112
- await refetch();
113
-
114
- const duplicateProtectionWorks =
115
- result2.data?.credits === result1.data?.credits;
116
-
117
- Alert.alert(
118
- "Duplicate Test",
119
- `First call: ${result1.success ? "✅ Added credits" : "❌ Failed"}\n\nSecond call: ${duplicateProtectionWorks ? "✅ Skipped (protection works!)" : "❌ Added again (protection failed!)"}`,
120
- [{ text: "OK" }],
121
- );
122
- } catch (error) {
123
- if (__DEV__) {
124
- console.error("❌ [Dev Test] Duplicate test failed:", error);
125
- }
126
- Alert.alert(
127
- "Test Failed",
128
- error instanceof Error ? error.message : "Unknown error",
129
- );
130
- }
131
- }, [user?.uid, refetch]);
132
-
133
- if (!__DEV__) {
134
- return undefined;
135
- }
136
-
137
- return {
138
- onTestRenewal,
139
- onCheckCredits,
140
- onTestDuplicate,
141
- };
142
- };
@@ -1,92 +0,0 @@
1
- # useInitializeCredits Hook
2
-
3
- TanStack Query mutation hook for initializing credits after purchase.
4
-
5
- ## Location
6
-
7
- **Import Path**: `@umituz/react-native-subscription`
8
-
9
- **File**: `src/presentation/hooks/useInitializeCredits.ts`
10
-
11
- **Type**: Hook
12
-
13
- ## Strategy
14
-
15
- ### Credit Initialization Flow
16
-
17
- 1. **User Validation**: Verify user is authenticated before initialization
18
- 2. **Repository Call**: Call credits repository to initialize credits
19
- 3. **Duplicate Protection**: Repository prevents duplicate initialization with same purchase ID
20
- 4. **Loading State**: Track initialization progress with isInitializing flag
21
- 5. **Error Handling**: Handle and report initialization failures
22
- 6. **Success Tracking**: Return success boolean for caller to handle
23
-
24
- ### Integration Points
25
-
26
- - **Credits Repository**: `src/domains/wallet/infrastructure/repositories/CreditsRepository.ts`
27
- - **Credits Entity**: `src/domains/wallet/domain/entities/UserCredits.ts`
28
- - **TanStack Query**: For mutation and optimistic updates
29
- - **Purchase Flow**: Called after successful subscription purchase
30
-
31
- ## Restrictions
32
-
33
- ### REQUIRED
34
-
35
- - **User ID**: MUST provide valid userId parameter
36
- - **Authentication**: User MUST be authenticated
37
- - **Error Handling**: MUST handle initialization failures
38
- - **Loading State**: MUST show loading indicator during initialization
39
-
40
- ### PROHIBITED
41
-
42
- - **NEVER** initialize credits without valid userId
43
- - **NEVER** call for unauthenticated users
44
- - **DO NOT** assume successful initialization (check return value)
45
- - **DO NOT** call excessively (repository handles duplicates)
46
-
47
- ### CRITICAL SAFETY
48
-
49
- - **ALWAYS** validate userId before initialization
50
- - **MUST** handle errors gracefully
51
- - **ALWAYS** check return value
52
- - **NEVER** rely on side effects without checking success
53
-
54
- ## AI Agent Guidelines
55
-
56
- ### When Implementing Credit Initialization
57
-
58
- 1. **Always** validate userId before calling initializeCredits
59
- 2. **Always** handle loading state
60
- 3. **Always** check return value
61
- 4. **Always** provide purchaseId and productId when available
62
- 5. **Never** initialize credits for unauthenticated users
63
-
64
- ### Integration Checklist
65
-
66
- - [ ] Import from correct path: `@umituz/react-native-subscription`
67
- - [ ] Validate userId is not undefined
68
- - [ ] Handle isInitializing state
69
- - [ ] Check return value from initializeCredits
70
- - [ ] Provide purchaseId when available
71
- - [ ] Provide productId when available
72
- - [ ] Test with premium user (no existing credits)
73
- - [ ] Test with premium user (existing credits)
74
- - [ ] Test duplicate protection
75
- - [ ] Test error scenarios
76
-
77
- ### Common Patterns
78
-
79
- 1. **Post-Purchase Init**: Initialize after successful purchase
80
- 2. **Auto-Init for Premium**: Automatically initialize for premium users without credits
81
- 3. **Product-Specific Allocation**: Different products provide different credit amounts
82
- 4. **Retry Logic**: Implement retry mechanism on failure
83
- 5. **Admin Init**: Manual initialization for admin users
84
-
85
- ## Related Documentation
86
-
87
- - **useCredits**: For accessing credits balance
88
- - **useDeductCredit**: For deducting credits
89
- - **usePremiumWithCredits**: For premium + credits integration
90
- - **useDevTestCallbacks**: For testing credit initialization
91
- - **Credits Repository**: `src/domains/wallet/infrastructure/repositories/README.md`
92
- - **Wallet Domain**: `src/domains/wallet/README.md`
@@ -1,57 +0,0 @@
1
- /**
2
- * useInitializeCredits Hook
3
- * TanStack Query mutation hook for initializing credits after purchase.
4
- */
5
-
6
- import { useCallback } from "react";
7
- import { useMutation, useQueryClient } from "@umituz/react-native-design-system";
8
- import { getCreditsRepository } from "../../infrastructure/repositories/CreditsRepositoryProvider";
9
- import { creditsQueryKeys } from "./useCredits";
10
-
11
- declare const __DEV__: boolean;
12
-
13
- export interface UseInitializeCreditsParams {
14
- userId: string | undefined;
15
- }
16
-
17
- export interface InitializeCreditsOptions {
18
- purchaseId?: string;
19
- productId?: string;
20
- }
21
-
22
- export interface UseInitializeCreditsResult {
23
- initializeCredits: (options?: InitializeCreditsOptions) => Promise<boolean>;
24
- isInitializing: boolean;
25
- }
26
-
27
- export const useInitializeCredits = ({
28
- userId,
29
- }: UseInitializeCreditsParams): UseInitializeCreditsResult => {
30
- const repository = getCreditsRepository();
31
- const queryClient = useQueryClient();
32
-
33
- const mutation = useMutation({
34
- mutationFn: async (options?: InitializeCreditsOptions) => {
35
- if (!userId) throw new Error("User not authenticated");
36
- if (__DEV__) console.log("[useInitializeCredits] Initializing:", { userId, ...options });
37
- return repository.initializeCredits(userId, options?.purchaseId, options?.productId);
38
- },
39
- onSuccess: (result) => {
40
- if (userId && result.success && result.data) {
41
- if (__DEV__) console.log("[useInitializeCredits] Success:", result.data);
42
- queryClient.setQueryData(creditsQueryKeys.user(userId), result.data);
43
- queryClient.invalidateQueries({ queryKey: creditsQueryKeys.user(userId) });
44
- }
45
- },
46
- onError: (error) => { if (__DEV__) console.error("[useInitializeCredits] Error:", error); },
47
- });
48
-
49
- const initializeCredits = useCallback(async (opts?: InitializeCreditsOptions): Promise<boolean> => {
50
- try {
51
- const res = await mutation.mutateAsync(opts);
52
- return res.success;
53
- } catch { return false; }
54
- }, [mutation]);
55
-
56
- return { initializeCredits, isInitializing: mutation.isPending };
57
- };
@@ -1,88 +0,0 @@
1
- # usePremiumGate Hook
2
-
3
- Feature gating hook for premium-only features with optional authentication.
4
-
5
- ## Location
6
-
7
- **Import Path**: `@umituz/react-native-subscription`
8
-
9
- **File**: `src/presentation/hooks/usePremiumGate.ts`
10
-
11
- **Type**: Hook
12
-
13
- ## Strategy
14
-
15
- ### Premium Gating Flow
16
-
17
- 1. **Premium Check**: Verify if user has premium access
18
- 2. **Auth Check**: Optionally verify authentication status
19
- 3. **Gate Functions**: Provide requirePremium, requireAuth, requirePremiumWithAuth
20
- 4. **Access Control**: Simple booleans for conditional rendering (canAccess, canAccessWithAuth)
21
- 5. **Callback Triggers**: Execute appropriate callback when requirements not met
22
-
23
- ### Integration Points
24
-
25
- - **usePremium**: For premium status check
26
- - **useAuth**: For authentication status
27
- - **Paywall Domain**: For premium upgrade flow
28
- - **Auth UI**: For authentication flow
29
-
30
- ## Restrictions
31
-
32
- ### REQUIRED
33
-
34
- - **Premium Status**: MUST provide isPremium parameter
35
- - **Callback**: MUST implement onPremiumRequired callback
36
- - **Access Check**: MUST verify canAccess before showing premium content
37
-
38
- ### PROHIBITED
39
-
40
- - **NEVER** show premium content without checking isPremium
41
- - **NEVER** use for security decisions without server validation
42
- - **DO NOT** assume premium status (always verify)
43
-
44
- ### CRITICAL SAFETY
45
-
46
- - **ALWAYS** verify canAccess before showing premium features
47
- - **NEVER** trust client-side state for security
48
- - **MUST** implement proper upgrade flow
49
- - **ALWAYS** handle authentication when required
50
-
51
- ## AI Agent Guidelines
52
-
53
- ### When Implementing Premium Gates
54
-
55
- 1. **Always** check canAccess before showing premium content
56
- 2. **Always** provide clear upgrade path in callback
57
- 3. **Always** use requirePremium for action gating
58
- 4. **Always** handle authentication when using requirePremiumWithAuth
59
- 5. **Never** bypass premium checks
60
-
61
- ### Integration Checklist
62
-
63
- - [ ] Import from correct path: `@umituz/react-native-subscription`
64
- - [ ] Provide isPremium from usePremium
65
- - [ ] Implement onPremiumRequired callback
66
- - [ ] Optionally provide auth status and callback
67
- - [ ] Use requirePremium for action gating
68
- - [ ] Check canAccess for conditional rendering
69
- - [ ] Test with premium user
70
- - [ ] Test with non-premium user
71
- - [ ] Test with authenticated user
72
- - [ ] Test with unauthenticated user
73
-
74
- ### Common Patterns
75
-
76
- 1. **Premium Only**: Gate features behind premium only
77
- 2. **Auth + Premium**: Require both authentication and premium
78
- 3. **Conditional Rendering**: Check canAccess for UI
79
- 4. **Button States**: Disable buttons when not premium
80
- 5. **Upgrade Prompts**: Show in callback when not premium
81
-
82
- ## Related Documentation
83
-
84
- - **usePremium**: Premium status check
85
- - **useAuthGate**: Auth + subscription gating
86
- - **useSubscriptionGate**: Subscription-only gating
87
- - **useFeatureGate**: Unified feature gating
88
- - **Paywall Domain**: `src/domains/paywall/README.md`
@@ -1,116 +0,0 @@
1
- /**
2
- * usePremiumGate Hook
3
- *
4
- * Feature gating hook for premium-only features
5
- * Provides a simple way to gate features behind premium subscription
6
- *
7
- * @example
8
- * ```typescript
9
- * const { requirePremium, isPremium } = usePremiumGate({
10
- * isPremium: subscriptionStore.isPremium,
11
- * onPremiumRequired: () => navigation.navigate('Paywall'),
12
- * });
13
- *
14
- * const handleGenerate = () => {
15
- * requirePremium(() => {
16
- * // This only runs if user is premium
17
- * generateContent();
18
- * });
19
- * };
20
- * ```
21
- */
22
-
23
- import { useCallback, useMemo } from "react";
24
-
25
- export interface UsePremiumGateParams {
26
- /** Whether user has premium access */
27
- isPremium: boolean;
28
- /** Callback when premium is required but user is not premium */
29
- onPremiumRequired: () => void;
30
- /** Optional: Whether user is authenticated */
31
- isAuthenticated?: boolean;
32
- /** Optional: Callback when auth is required but user is not authenticated */
33
- onAuthRequired?: () => void;
34
- }
35
-
36
- export interface UsePremiumGateResult {
37
- /** Whether user has premium access */
38
- isPremium: boolean;
39
- /** Whether user is authenticated */
40
- isAuthenticated: boolean;
41
- /** Gate a feature behind premium - executes action if premium, else calls onPremiumRequired */
42
- requirePremium: (action: () => void) => void;
43
- /** Gate a feature behind auth - executes action if authenticated, else calls onAuthRequired */
44
- requireAuth: (action: () => void) => void;
45
- /** Gate a feature behind both auth and premium */
46
- requirePremiumWithAuth: (action: () => void) => void;
47
- /** Check if feature is accessible (premium check only) */
48
- canAccess: boolean;
49
- /** Check if feature is accessible (auth + premium) */
50
- canAccessWithAuth: boolean;
51
- }
52
-
53
- export function usePremiumGate(
54
- params: UsePremiumGateParams
55
- ): UsePremiumGateResult {
56
- const {
57
- isPremium,
58
- onPremiumRequired,
59
- isAuthenticated = true,
60
- onAuthRequired,
61
- } = params;
62
-
63
- const requirePremium = useCallback(
64
- (action: () => void) => {
65
- if (isPremium) {
66
- action();
67
- } else {
68
- onPremiumRequired();
69
- }
70
- },
71
- [isPremium, onPremiumRequired]
72
- );
73
-
74
- const requireAuth = useCallback(
75
- (action: () => void) => {
76
- if (isAuthenticated) {
77
- action();
78
- } else {
79
- onAuthRequired?.();
80
- }
81
- },
82
- [isAuthenticated, onAuthRequired]
83
- );
84
-
85
- const requirePremiumWithAuth = useCallback(
86
- (action: () => void) => {
87
- if (!isAuthenticated) {
88
- onAuthRequired?.();
89
- return;
90
- }
91
- if (!isPremium) {
92
- onPremiumRequired();
93
- return;
94
- }
95
- action();
96
- },
97
- [isAuthenticated, isPremium, onAuthRequired, onPremiumRequired]
98
- );
99
-
100
- const canAccess = useMemo(() => isPremium, [isPremium]);
101
-
102
- const canAccessWithAuth = useMemo(
103
- () => isAuthenticated && isPremium,
104
- [isAuthenticated, isPremium]
105
- );
106
-
107
- return {
108
- isPremium,
109
- isAuthenticated,
110
- requirePremium,
111
- requireAuth,
112
- requirePremiumWithAuth,
113
- canAccess,
114
- canAccessWithAuth,
115
- };
116
- }
@@ -1,92 +0,0 @@
1
- # usePremiumWithCredits Hook
2
-
3
- Combined hook for premium subscription with credits system integration.
4
-
5
- ## Location
6
-
7
- **Import Path**: `@umituz/react-native-subscription`
8
-
9
- **File**: `src/presentation/hooks/usePremiumWithCredits.ts`
10
-
11
- **Type**: Hook
12
-
13
- ## Strategy
14
-
15
- ### Premium + Credits Integration
16
-
17
- 1. **Credits Access**: Provide all credits data from useCredits hook
18
- 2. **Auto-Initialization**: Automatically initialize credits when user becomes premium
19
- 3. **Premium Check**: Monitor isPremium status to trigger initialization
20
- 4. **Duplicate Prevention**: Skip initialization if credits already exist
21
- 5. **Loading Management**: Handle loading state during initialization
22
- 6. **Error Handling**: Handle initialization failures gracefully
23
-
24
- ### Integration Points
25
-
26
- - **useCredits**: For credits balance and transactions
27
- - **usePremium**: For premium status check
28
- - **useInitializeCredits**: For credit initialization
29
- - **Credits Repository**: `src/domains/wallet/infrastructure/repositories/CreditsRepository.ts`
30
-
31
- ## Restrictions
32
-
33
- ### REQUIRED
34
-
35
- - **User ID**: MUST provide valid userId parameter
36
- - **Premium Status**: MUST provide isPremium parameter
37
- - **Loading State**: MUST handle loading state
38
- - **Error Handling**: MUST handle initialization errors
39
-
40
- ### PROHIBITED
41
-
42
- - **NEVER** call without valid userId
43
- - **NEVER** call without isPremium parameter
44
- - **DO NOT** manually manage credits state (use hook values)
45
- - **DO NOT** call ensureCreditsInitialized excessively
46
-
47
- ### CRITICAL SAFETY
48
-
49
- - **ALWAYS** validate userId before use
50
- - **MUST** handle loading state during initialization
51
- - **ALWAYS** check isPremium before showing premium features
52
- - **NEVER** trust client-side state for security
53
-
54
- ## AI Agent Guidelines
55
-
56
- ### When Implementing Premium + Credits
57
-
58
- 1. **Always** provide valid userId
59
- 2. **Always** provide isPremium status
60
- 3. **Always** handle loading state
61
- 4. **Always** call ensureCreditsInitialized for premium users
62
- 5. **Never** manually initialize credits without checking isPremium
63
-
64
- ### Integration Checklist
65
-
66
- - [ ] Import from correct path: `@umituz/react-native-subscription`
67
- - [ ] Provide valid userId
68
- - [ ] Provide isPremium from usePremium
69
- - [ ] Handle loading state
70
- - [ ] Call ensureCreditsInitialized when isPremium is true
71
- - [ ] Test with premium user (no credits)
72
- - [ ] Test with premium user (has credits)
73
- - [ ] Test with free user
74
- - [ ] Test subscription upgrade flow
75
- - [ ] Test error scenarios
76
-
77
- ### Common Patterns
78
-
79
- 1. **Auto-Initialization**: Automatically initialize credits for premium users
80
- 2. **Subscription Change Detection**: Detect when user subscribes
81
- 3. **Premium Benefits Display**: Show credits along with premium status
82
- 4. **Subscription Monitor**: Refresh status periodically
83
- 5. **Manual Init**: Provide button for manual initialization
84
-
85
- ## Related Documentation
86
-
87
- - **useCredits**: Credits management
88
- - **useInitializeCredits**: Manual credit initialization
89
- - **usePremium**: Premium status
90
- - **useDeductCredit**: Credit deduction
91
- - **Credits System**: `src/domains/wallet/README.md`
92
- - **Premium Integration**: `src/docs/PREMIUM_INTEGRATION.md`