@umituz/react-native-subscription 2.26.14 → 2.26.16

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 (37) 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 -13
  7. package/src/presentation/hooks/useFeatureGate.ts +12 -33
  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/useAuthGate.md +0 -89
  13. package/src/presentation/hooks/useAuthGate.ts +0 -65
  14. package/src/presentation/hooks/useCreditChecker.md +0 -102
  15. package/src/presentation/hooks/useCreditChecker.ts +0 -41
  16. package/src/presentation/hooks/useCreditsGate.md +0 -94
  17. package/src/presentation/hooks/useCreditsGate.ts +0 -67
  18. package/src/presentation/hooks/useDevTestCallbacks.md +0 -91
  19. package/src/presentation/hooks/useDevTestCallbacks.ts +0 -142
  20. package/src/presentation/hooks/useInitializeCredits.md +0 -92
  21. package/src/presentation/hooks/useInitializeCredits.ts +0 -57
  22. package/src/presentation/hooks/usePremiumGate.md +0 -88
  23. package/src/presentation/hooks/usePremiumGate.ts +0 -116
  24. package/src/presentation/hooks/usePremiumWithCredits.md +0 -92
  25. package/src/presentation/hooks/usePremiumWithCredits.ts +0 -48
  26. package/src/presentation/hooks/useSubscription.md +0 -94
  27. package/src/presentation/hooks/useSubscription.ts +0 -119
  28. package/src/presentation/hooks/useSubscriptionDetails.md +0 -93
  29. package/src/presentation/hooks/useSubscriptionDetails.ts +0 -85
  30. package/src/presentation/hooks/useSubscriptionGate.md +0 -84
  31. package/src/presentation/hooks/useSubscriptionGate.ts +0 -67
  32. package/src/presentation/hooks/useSubscriptionStatus.md +0 -94
  33. package/src/presentation/hooks/useTrialEligibility.ts +0 -66
  34. package/src/presentation/hooks/useUserTier.md +0 -91
  35. package/src/presentation/hooks/useUserTier.ts +0 -78
  36. package/src/presentation/hooks/useUserTierWithRepository.md +0 -92
  37. package/src/presentation/hooks/useUserTierWithRepository.ts +0 -151
@@ -1,119 +0,0 @@
1
- /**
2
- * useSubscription Hook
3
- * React hook for subscription management
4
- */
5
-
6
- import { useState, useCallback } from 'react';
7
- import type { SubscriptionStatus } from '../../domain/entities/SubscriptionStatus';
8
- import { isSubscriptionValid } from '../../domain/entities/SubscriptionStatus';
9
- import {
10
- checkSubscriptionService,
11
- validateUserId,
12
- executeSubscriptionOperation,
13
- } from './useSubscription.utils';
14
-
15
- export interface UseSubscriptionResult {
16
- /** Current subscription status */
17
- status: SubscriptionStatus | null;
18
- /** Whether subscription is loading */
19
- loading: boolean;
20
- /** Error if any */
21
- error: string | null;
22
- /** Whether user has active subscription */
23
- isPremium: boolean;
24
- /** Load subscription status */
25
- loadStatus: (userId: string) => Promise<void>;
26
- /** Refresh subscription status */
27
- refreshStatus: (userId: string) => Promise<void>;
28
- /** Activate subscription */
29
- activateSubscription: (
30
- userId: string,
31
- productId: string,
32
- expiresAt: string | null,
33
- ) => Promise<void>;
34
- /** Deactivate subscription */
35
- deactivateSubscription: (userId: string) => Promise<void>;
36
- }
37
-
38
- /**
39
- * Hook for subscription operations
40
- *
41
- * @example
42
- * ```typescript
43
- * const { status, isPremium, loadStatus } = useSubscription();
44
- * ```
45
- */
46
- export function useSubscription(): UseSubscriptionResult {
47
- const [status, setStatus] = useState<SubscriptionStatus | null>(null);
48
- const [loading, setLoading] = useState(false);
49
- const [error, setError] = useState<string | null>(null);
50
-
51
- const performOperation = useCallback(async (
52
- userId: string,
53
- operation: () => Promise<SubscriptionStatus | null | void>
54
- ) => {
55
- const errorMsg = validateUserId(userId);
56
- if (errorMsg) {
57
- setError(errorMsg);
58
- return;
59
- }
60
-
61
- const check = checkSubscriptionService();
62
- if (!check.success) {
63
- setError(check.error || "Service error");
64
- return;
65
- }
66
-
67
- await executeSubscriptionOperation(
68
- operation,
69
- setLoading,
70
- setError,
71
- (result) => { if (result) setStatus(result as SubscriptionStatus); }
72
- );
73
- }, []);
74
-
75
- const loadStatus = useCallback((userId: string) =>
76
- performOperation(userId, () => {
77
- const { service } = checkSubscriptionService();
78
-
79
- return service!.getSubscriptionStatus(userId);
80
- }), [performOperation]);
81
-
82
- const refreshStatus = loadStatus;
83
-
84
- const activateSubscription = useCallback(
85
- (userId: string, productId: string, expiresAt: string | null) => {
86
- if (!productId) {
87
- setError("Product ID is required");
88
- return Promise.resolve();
89
- }
90
- return performOperation(userId, () => {
91
- const { service } = checkSubscriptionService();
92
-
93
- return service!.activateSubscription(userId, productId, expiresAt).then(res => res ?? undefined);
94
- });
95
- },
96
- [performOperation]
97
- );
98
-
99
- const deactivateSubscription = useCallback((userId: string) =>
100
- performOperation(userId, () => {
101
- const { service } = checkSubscriptionService();
102
-
103
- return service!.deactivateSubscription(userId).then(res => res ?? undefined);
104
- }), [performOperation]);
105
-
106
- const isPremium = isSubscriptionValid(status);
107
-
108
- return {
109
- status,
110
- loading,
111
- error,
112
- isPremium,
113
- loadStatus,
114
- refreshStatus,
115
- activateSubscription,
116
- deactivateSubscription,
117
- };
118
- }
119
-
@@ -1,93 +0,0 @@
1
- # useSubscriptionDetails Hook
2
-
3
- Hook for accessing detailed subscription information including package details.
4
-
5
- ## Location
6
-
7
- **Import Path**: `@umituz/react-native-subscription`
8
-
9
- **File**: `src/presentation/hooks/useSubscriptionDetails.ts`
10
-
11
- **Type**: Hook
12
-
13
- ## Strategy
14
-
15
- ### Detailed Subscription Information
16
-
17
- 1. **Subscription Status**: Fetch current subscription status object
18
- 2. **Package Details**: Retrieve RevenueCat package information
19
- 3. **Period Detection**: Determine subscription period (monthly/annual/lifetime)
20
- 4. **Price Calculation**: Calculate current price and monthly equivalent
21
- 5. **Feature List**: Extract feature list from package configuration
22
- 6. **Real-time Updates**: Refresh when subscription changes
23
-
24
- ### Integration Points
25
-
26
- - **Subscription Repository**: `src/infrastructure/repositories/SubscriptionRepository.ts`
27
- - **Package Configuration**: RevenueCat package definitions
28
- - **useSubscriptionStatus**: For detailed status information
29
- - **TanStack Query**: For caching and background updates
30
-
31
- ## Restrictions
32
-
33
- ### REQUIRED
34
-
35
- - **Loading State**: MUST handle loading state
36
- - **Null Handling**: MUST handle null subscription and package
37
- - **Error Handling**: MUST handle error state
38
- - **Price Formatting**: MUST format prices appropriately
39
-
40
- ### PROHIBITED
41
-
42
- - **NEVER** assume subscription exists (check for null)
43
- - **NEVER** assume package exists (check for null)
44
- - **DO NOT** use prices without formatting
45
- - **DO NOT** hardcode feature lists
46
-
47
- ### CRITICAL SAFETY
48
-
49
- - **ALWAYS** check for null subscription and package
50
- - **MUST** handle loading state before accessing details
51
- - **ALWAYS** format prices with currency codes
52
- - **NEVER** trust client-side details for security
53
-
54
- ## AI Agent Guidelines
55
-
56
- ### When Implementing Subscription Details
57
-
58
- 1. **Always** check for null subscription and package
59
- 2. **Always** handle loading state
60
- 3. **Always** format prices properly
61
- 4. **Always** handle all period types (monthly, annual, lifetime)
62
- 5. **Never** use for security decisions without server validation
63
-
64
- ### Integration Checklist
65
-
66
- - [ ] Import from correct path: `@umituz/react-native-subscription`
67
- - [ ] Handle loading state
68
- - [ ] Check subscription for null
69
- - [ ] Check package for null
70
- - [ ] Format prices with currency codes
71
- - [ ] Handle all period types
72
- - [ ] Display features properly
73
- - [ ] Test with monthly subscription
74
- - [ ] Test with annual subscription
75
- - [ ] Test with lifetime subscription
76
- - [ ] Test with no subscription
77
-
78
- ### Common Patterns
79
-
80
- 1. **Detailed Card**: Display comprehensive subscription information
81
- 2. **Price Comparison**: Show monthly vs annual pricing
82
- 3. **Upgrade Suggestion**: Suggest upgrades based on current plan
83
- 4. **Feature List**: Display included features
84
- 5. **Billing History**: Show subscription history
85
- 6. **Cancellation Flow**: Handle subscription cancellation
86
-
87
- ## Related Documentation
88
-
89
- - **useSubscription**: Basic subscription status
90
- - **useSubscriptionStatus**: Detailed status
91
- - **usePremium**: Simple premium check
92
- - **useSubscriptionPackages**: Available packages
93
- - **Package Utilities**: `src/utils/README.md`
@@ -1,85 +0,0 @@
1
- import { useMemo } from "react";
2
- import {
3
- type SubscriptionStatus,
4
- SUBSCRIPTION_STATUS,
5
- type SubscriptionStatusType,
6
- isSubscriptionValid,
7
- calculateDaysRemaining
8
- } from "../../domain/entities/SubscriptionStatus";
9
- import { formatDate } from "../utils/subscriptionDateUtils";
10
-
11
- export interface SubscriptionDetails {
12
- /** Raw subscription status */
13
- status: SubscriptionStatus | null;
14
- /** Whether user has active premium */
15
- isPremium: boolean;
16
- /** Whether subscription is expired */
17
- isExpired: boolean;
18
- /** Whether this is a lifetime subscription */
19
- isLifetime: boolean;
20
- /** Days remaining until expiration (null for lifetime) */
21
- daysRemaining: number | null;
22
- /** Formatted expiration date (null if lifetime) */
23
- formattedExpirationDate: string | null;
24
- /** Formatted purchase date */
25
- formattedPurchaseDate: string | null;
26
- /** Status text key for localization */
27
- statusKey: SubscriptionStatusType;
28
- }
29
-
30
- interface UseSubscriptionDetailsParams {
31
- status: SubscriptionStatus | null;
32
- }
33
-
34
- /**
35
- * Hook for formatted subscription details
36
- */
37
- export function useSubscriptionDetails(
38
- params: UseSubscriptionDetailsParams,
39
- ): SubscriptionDetails {
40
- const { status } = params;
41
-
42
- return useMemo(() => {
43
- if (!status) {
44
- return {
45
- status: null,
46
- isPremium: false,
47
- isExpired: false,
48
- isLifetime: false,
49
- daysRemaining: null,
50
- formattedExpirationDate: null,
51
- formattedPurchaseDate: null,
52
- statusKey: SUBSCRIPTION_STATUS.NONE,
53
- };
54
- }
55
-
56
- const isValid = isSubscriptionValid(status);
57
- const isExpired = status.isPremium && !isValid;
58
- const isLifetime = status.isPremium && !status.expiresAt;
59
- const daysRemainingValue = calculateDaysRemaining(status.expiresAt ?? null);
60
- const isPremium = status.isPremium && isValid;
61
-
62
- let statusKey: SubscriptionStatusType = status.status || SUBSCRIPTION_STATUS.NONE;
63
-
64
- // Override status key based on current calculation for active/expired
65
- if (status.isPremium) {
66
- statusKey = isExpired ? SUBSCRIPTION_STATUS.EXPIRED : SUBSCRIPTION_STATUS.ACTIVE;
67
- } else if (status.status === SUBSCRIPTION_STATUS.CANCELED) {
68
- statusKey = SUBSCRIPTION_STATUS.CANCELED;
69
- } else {
70
- statusKey = SUBSCRIPTION_STATUS.NONE;
71
- }
72
-
73
- return {
74
- status,
75
- isPremium,
76
- isExpired,
77
- isLifetime,
78
- daysRemaining: daysRemainingValue,
79
- formattedExpirationDate: formatDate(status.expiresAt ?? null),
80
- formattedPurchaseDate: formatDate(status.purchasedAt ?? null),
81
- statusKey,
82
- };
83
- }, [status]);
84
- }
85
-
@@ -1,84 +0,0 @@
1
- # useSubscriptionGate Hook
2
-
3
- Subscription-only feature gating with simple, focused API.
4
-
5
- ## Location
6
-
7
- **Import Path**: `@umituz/react-native-subscription`
8
-
9
- **File**: `src/presentation/hooks/useSubscriptionGate.ts`
10
-
11
- **Type**: Hook
12
-
13
- ## Strategy
14
-
15
- ### Subscription Gating Flow
16
-
17
- 1. **Subscription Check**: Verify if user has active subscription
18
- 2. **Gate Function**: Provide requireSubscription function for gating
19
- 3. **Action Wrapping**: Wrap actions behind subscription check
20
- 4. **Callback Trigger**: Execute callback when subscription is required
21
- 5. **Boolean Access**: Provide simple hasSubscription boolean for conditional rendering
22
-
23
- ### Integration Points
24
-
25
- - **usePremium**: For subscription status check
26
- - **Paywall Domain**: For subscription upgrade flow
27
- - **Feature Gates**: For unified feature access control
28
-
29
- ## Restrictions
30
-
31
- ### REQUIRED
32
-
33
- - **Subscription Status**: MUST provide hasSubscription parameter
34
- - **Callback**: MUST implement onSubscriptionRequired callback
35
- - **Return Check**: SHOULD check return value from requireSubscription
36
-
37
- ### PROHIBITED
38
-
39
- - **NEVER** show protected content without checking hasSubscription
40
- - **NEVER** use for security decisions without server validation
41
- - **DO NOT** assume subscription status (always verify)
42
-
43
- ### CRITICAL SAFETY
44
-
45
- - **ALWAYS** verify hasSubscription before allowing access
46
- - **NEVER** trust client-side state for security
47
- - **MUST** implement proper upgrade flow
48
- - **ALWAYS** handle both subscribed and non-subscribed states
49
-
50
- ## AI Agent Guidelines
51
-
52
- ### When Implementing Subscription Gates
53
-
54
- 1. **Always** check hasSubscription before showing protected content
55
- 2. **Always** provide clear upgrade path in callback
56
- 3. **Always** use requireSubscription for action gating
57
- 4. **Never** bypass subscription checks
58
- 5. **Always** test with both subscribed and non-subscribed users
59
-
60
- ### Integration Checklist
61
-
62
- - [ ] Import from correct path: `@umituz/react-native-subscription`
63
- - [ ] Provide hasSubscription from usePremium
64
- - [ ] Implement onSubscriptionRequired callback
65
- - [ ] Use requireSubscription for action gating
66
- - [ ] Check hasSubscription for conditional rendering
67
- - [ ] Test with subscribed user
68
- - [ ] Test with non-subscribed user
69
- - [ ] Verify upgrade flow triggers correctly
70
-
71
- ### Common Patterns
72
-
73
- 1. **Action Gating**: Use requireSubscription to wrap actions
74
- 2. **Conditional Rendering**: Check hasSubscription for UI
75
- 3. **Button States**: Disable buttons when not subscribed
76
- 4. **Upgrade Prompts**: Show in callback when not subscribed
77
-
78
- ## Related Documentation
79
-
80
- - **usePremium**: Subscription status check
81
- - **usePremiumGate**: Premium feature gating
82
- - **useAuthGate**: Auth + subscription gating
83
- - **useFeatureGate**: Unified feature gating
84
- - **Paywall Domain**: `src/domains/paywall/README.md`
@@ -1,67 +0,0 @@
1
- /**
2
- * useSubscriptionGate Hook
3
- *
4
- * Single responsibility: Subscription/Premium gating
5
- * Checks if user has active subscription before allowing actions.
6
- *
7
- * @example
8
- * ```typescript
9
- * const { requireSubscription, hasSubscription } = useSubscriptionGate({
10
- * hasSubscription: isPremium,
11
- * onSubscriptionRequired: () => showPaywall(),
12
- * });
13
- *
14
- * const handlePremiumAction = () => {
15
- * requireSubscription(() => doPremiumThing());
16
- * };
17
- * ```
18
- */
19
-
20
- import { useCallback } from "react";
21
-
22
- declare const __DEV__: boolean;
23
-
24
- export interface UseSubscriptionGateParams {
25
- /** Whether user has active subscription */
26
- hasSubscription: boolean;
27
- /** Callback when subscription is required */
28
- onSubscriptionRequired: () => void;
29
- }
30
-
31
- export interface UseSubscriptionGateResult {
32
- /** Whether user has active subscription */
33
- hasSubscription: boolean;
34
- /** Gate action behind subscription - executes if subscribed, else shows paywall */
35
- requireSubscription: (action: () => void | Promise<void>) => boolean;
36
- }
37
-
38
- export function useSubscriptionGate(
39
- params: UseSubscriptionGateParams
40
- ): UseSubscriptionGateResult {
41
- const { hasSubscription, onSubscriptionRequired } = params;
42
-
43
- const requireSubscription = useCallback(
44
- (_action: () => void | Promise<void>): boolean => {
45
- if (!hasSubscription) {
46
- if (__DEV__) {
47
-
48
- console.log("[useSubscriptionGate] No subscription, showing paywall");
49
- }
50
- onSubscriptionRequired();
51
- return false;
52
- }
53
-
54
- if (__DEV__) {
55
-
56
- console.log("[useSubscriptionGate] Has subscription, proceeding");
57
- }
58
- return true;
59
- },
60
- [hasSubscription, onSubscriptionRequired]
61
- );
62
-
63
- return {
64
- hasSubscription,
65
- requireSubscription,
66
- };
67
- }
@@ -1,94 +0,0 @@
1
- # useSubscriptionStatus Hook
2
-
3
- Hook for accessing detailed subscription status information.
4
-
5
- ## Location
6
-
7
- **Import Path**: `@umituz/react-native-subscription`
8
-
9
- **File**: `src/presentation/hooks/useSubscriptionStatus.ts`
10
-
11
- **Type**: Hook
12
-
13
- ## Strategy
14
-
15
- ### Subscription Status Flow
16
-
17
- 1. **Status Fetch**: Retrieve current subscription status from repository
18
- 2. **Status Parsing**: Extract tier, active state, expiration info
19
- 3. **Real-time Updates**: Update when subscription changes
20
- 4. **Expiration Tracking**: Calculate days until expiration
21
- 5. **Renewal Status**: Determine if subscription will auto-renew
22
- 6. **Caching**: Cache status for performance (5 min default)
23
-
24
- ### Integration Points
25
-
26
- - **Subscription Repository**: `src/infrastructure/repositories/SubscriptionRepository.ts`
27
- - **SubscriptionStatus Entity**: `src/domain/entities/README.md`
28
- - **TanStack Query**: For caching and real-time updates
29
- - **RevenueCat**: For subscription data source
30
-
31
- ## Restrictions
32
-
33
- ### REQUIRED
34
-
35
- - **Loading State**: MUST handle loading state
36
- - **Error Handling**: MUST handle error state
37
- - **Null Check**: MUST handle null status (guest users)
38
- - **Expiration**: SHOULD warn users before expiration
39
-
40
- ### PROHIBITED
41
-
42
- - **NEVER** assume status exists (check for null)
43
- - **NEVER** use for security decisions without server validation
44
- - **DO NOT** show expiration for lifetime subscriptions
45
- - **DO NOT** cache beyond configured time
46
-
47
- ### CRITICAL SAFETY
48
-
49
- - **ALWAYS** check if status is null before accessing properties
50
- - **NEVER** trust client-side status for security
51
- - **MUST** implement error boundaries
52
- - **ALWAYS** refresh status when app comes to foreground
53
-
54
- ## AI Agent Guidelines
55
-
56
- ### When Displaying Subscription Info
57
-
58
- 1. **Always** check for null status (guest users)
59
- 2. **Always** handle loading and error states
60
- 3. **Always** show expiration warnings
61
- 4. **Always** display auto-renewal status
62
- 5. **Never** show technical details to end users
63
-
64
- ### Integration Checklist
65
-
66
- - [ ] Import from correct path: `@umituz/react-native-subscription`
67
- - [ ] Handle loading state
68
- - [ ] Handle error state
69
- - [ ] Check for null status (guest users)
70
- - [ ] Display subscription tier
71
- - [ ] Show expiration date
72
- - [ ] Show days until expiration
73
- - [ ] Show auto-renewal status
74
- - [ ] Implement expiration warnings
75
- - [ ] Test with active subscription
76
- - [ ] Test with expired subscription
77
- - [ ] Test with guest user (null status)
78
-
79
- ### Common Patterns
80
-
81
- 1. **Status Badge**: Visual indicator of subscription status
82
- 2. **Expiration Countdown**: Days remaining until expiration
83
- 3. **Warning System**: Notify users before expiration
84
- 4. **Detail Card**: Comprehensive subscription information
85
- 5. **Lifecycle Management**: Handle subscription events
86
-
87
- ## Related Documentation
88
-
89
- - **usePremium**: Simple premium status check
90
- - **useSubscription**: Detailed subscription information
91
- - **useSubscriptionDetails**: Package and feature details
92
- - **useUserTier**: Tier information
93
- - **SubscriptionStatus Entity**: `src/domain/entities/README.md`
94
- - **Subscription Repository**: `src/infrastructure/repositories/README.md`
@@ -1,66 +0,0 @@
1
- /**
2
- * useTrialEligibility Hook
3
- * Checks if device is eligible for free trial
4
- * Uses persistent device ID to prevent trial abuse
5
- */
6
-
7
- import { useState, useEffect, useCallback } from "react";
8
- import {
9
- checkTrialEligibility,
10
- getDeviceId,
11
- } from "../../infrastructure/services/TrialService";
12
-
13
- export interface UseTrialEligibilityResult {
14
- /** Whether device is eligible for trial */
15
- isEligible: boolean;
16
- /** Whether eligibility check is in progress */
17
- isLoading: boolean;
18
- /** Reason why not eligible (if applicable) */
19
- reason?: "already_used" | "device_not_found" | "error";
20
- /** Device ID used for checking */
21
- deviceId: string | null;
22
- /** Refresh eligibility status */
23
- refresh: () => Promise<void>;
24
- }
25
-
26
- /**
27
- * Hook to check trial eligibility based on device ID
28
- * Device ID persists across app reinstalls via Keychain
29
- */
30
- export function useTrialEligibility(): UseTrialEligibilityResult {
31
- const [isEligible, setIsEligible] = useState(true);
32
- const [isLoading, setIsLoading] = useState(true);
33
- const [reason, setReason] = useState<"already_used" | "device_not_found" | "error">();
34
- const [deviceId, setDeviceId] = useState<string | null>(null);
35
-
36
- const checkEligibility = useCallback(async () => {
37
- setIsLoading(true);
38
-
39
- try {
40
- const id = await getDeviceId();
41
- setDeviceId(id);
42
-
43
- const result = await checkTrialEligibility(id);
44
- setIsEligible(result.eligible);
45
- setReason(result.reason);
46
- } catch {
47
- // On error, allow trial (better UX)
48
- setIsEligible(true);
49
- setReason("error");
50
- } finally {
51
- setIsLoading(false);
52
- }
53
- }, []);
54
-
55
- useEffect(() => {
56
- checkEligibility();
57
- }, [checkEligibility]);
58
-
59
- return {
60
- isEligible,
61
- isLoading,
62
- reason,
63
- deviceId,
64
- refresh: checkEligibility,
65
- };
66
- }
@@ -1,91 +0,0 @@
1
- # useUserTier Hook
2
-
3
- Hook for determining and tracking user tier (guest, free, premium).
4
-
5
- ## Location
6
-
7
- **Import Path**: `@umituz/react-native-subscription`
8
-
9
- **File**: `src/presentation/hooks/useUserTier.ts`
10
-
11
- **Type**: Hook
12
-
13
- ## Strategy
14
-
15
- ### Tier Determination Flow
16
-
17
- 1. **Auth State Check**: Determine if user is authenticated
18
- 2. **Subscription Check**: Verify active subscription status
19
- 3. **Tier Assignment**: Assign tier based on auth + subscription
20
- 4. **Real-time Updates**: Update tier when auth or subscription changes
21
- 5. **Caching**: Cache tier status for performance
22
- 6. **Transition Tracking**: Monitor and track tier changes
23
-
24
- ### Integration Points
25
-
26
- - **Auth Context**: User authentication state
27
- - **Subscription Repository**: `src/infrastructure/repositories/SubscriptionRepository.ts`
28
- - **Domain Layer**: `src/domain/entities/README.md`
29
- - **TanStack Query**: For caching and real-time updates
30
-
31
- ## Restrictions
32
-
33
- ### REQUIRED
34
-
35
- - **Tier Handling**: MUST handle all three tiers (guest, free, premium)
36
- - **Loading State**: MUST handle loading state
37
- - **Auth Integration**: MUST sync with authentication state
38
- - **Guest Support**: MUST support unauthenticated users
39
-
40
- ### PROHIBITED
41
-
42
- - **NEVER** assume user is authenticated (check isGuest)
43
- - **NEVER** use for security decisions without server validation
44
- - **DO NOT** hardcode tier values (use hook return values)
45
-
46
- ### CRITICAL SAFETY
47
-
48
- - **ALWAYS** check loading state before using tier values
49
- - **NEVER** trust client-side tier for security enforcement
50
- - **MUST** handle tier transitions gracefully
51
- - **ALWAYS** test with all three tier types
52
-
53
- ## AI Agent Guidelines
54
-
55
- ### When Implementing Tier-Based Features
56
-
57
- 1. **Always** handle loading state before checking tier
58
- 2. **Always** handle all three tiers (guest, free, premium)
59
- 3. **Always** provide upgrade path for free users
60
- 4. **Never** show features to guests that require auth
61
- 5. **Always** track tier changes in analytics
62
-
63
- ### Integration Checklist
64
-
65
- - [ ] Import from correct path: `@umituz/react-native-subscription`
66
- - [ ] Handle loading state
67
- - [ ] Implement logic for guest users
68
- - [ ] Implement logic for free users
69
- - [ ] Implement logic for premium users
70
- - [ ] Provide upgrade prompts for free users
71
- - [ ] Provide auth prompts for guest users
72
- - [ ] Test tier transitions (guest → free → premium)
73
- - [ ] Test tier downgrade (premium → free)
74
- - [ ] Track tier changes in analytics
75
-
76
- ### Common Patterns
77
-
78
- 1. **Conditional Rendering**: Show/hide features based on tier
79
- 2. **Navigation Guards**: Redirect based on tier requirements
80
- 3. **Feature Flags**: Enable features per tier
81
- 4. **Progress Indicators**: Show tier progression
82
- 5. **Upgrade Prompts**: Guide users to higher tiers
83
-
84
- ## Related Documentation
85
-
86
- - **useAuth**: Authentication state
87
- - **usePremium**: Premium subscription check
88
- - **useSubscription**: Detailed subscription information
89
- - **useAuthGate**: Authentication and subscription gating
90
- - **Domain Entities**: `src/domain/entities/README.md`
91
- - **User Tier Utils**: `src/utils/README.md`