@umituz/react-native-subscription 2.15.2 → 2.15.4

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.
@@ -1,284 +0,0 @@
1
- # useFeatureGate Hook
2
-
3
- Unified feature gate combining authentication, subscription, and credits checks.
4
-
5
- ## Location
6
-
7
- **Import Path**: `@umituz/react-native-subscription`
8
-
9
- **File**: `src/presentation/hooks/useFeatureGate.ts`
10
-
11
- **Type**: Hook
12
-
13
- ## Strategy
14
-
15
- ### Progressive Access Control
16
-
17
- 1. **Authentication Check**
18
- - Verify user is authenticated
19
- - Show auth modal if not authenticated
20
- - Queue pending action for post-auth execution
21
-
22
- 2. **Subscription Check**
23
- - Verify user has required subscription tier
24
- - Show paywall if subscription insufficient
25
- - Bypass credit check for premium users
26
-
27
- 3. **Credit Check**
28
- - Verify sufficient credit balance
29
- - Show purchase prompt if insufficient
30
- - Deduct credits only after all checks pass
31
-
32
- 4. **Action Execution**
33
- - Execute gated action only if all checks pass
34
- - Handle failures gracefully
35
- - Update UI state appropriately
36
-
37
- ### Integration Points
38
-
39
- - **useAuth**: For authentication state
40
- - **usePremium**: For subscription status
41
- - **useCredits**: For credit balance
42
- - **useDeductCredit**: For credit deduction
43
- - **Auth Modals**: Custom authentication UI
44
- - **Paywall Components**: Upgrade prompts
45
-
46
- ## Restrictions
47
-
48
- ### REQUIRED
49
-
50
- - **Authentication Check**: MUST implement `onShowAuthModal` callback
51
- - **Paywall Handler**: MUST implement `onShowPaywall` callback
52
- - **Credit Validation**: MUST check `hasCredits` before allowing actions
53
- - **State Management**: MUST respect `canAccess` boolean
54
-
55
- ### PROHIBITED
56
-
57
- - **NEVER** bypass authentication check for sensitive features
58
- - **NEVER** show feature gate if user has access (confusing UX)
59
- - **NEVER** execute action without checking all gates first
60
- - **DO NOT** hardcode gate logic (use hook parameters)
61
- - **NEVER** deduct credits without checking subscription status first
62
-
63
- ### CRITICAL SAFETY
64
-
65
- - **ALWAYS** check gates in order: Auth → Subscription → Credits
66
- - **ALWAYS** provide clear messaging about why access is denied
67
- - **ALWAYS** preserve user intent through auth/purchase flows
68
- - **NEVER** trust client-side gate for security (server-side validation required)
69
- - **MUST** implement proper error boundaries around gated actions
70
-
71
- ## Rules
72
-
73
- ### Basic Feature Gating
74
-
75
- ```typescript
76
- // CORRECT - All gates with clear messaging
77
- function PremiumFeature() {
78
- const { requireFeature, canAccess, isAuthenticated, hasSubscription, hasCredits } =
79
- useFeatureGate({
80
- isAuthenticated: !!user,
81
- onShowAuthModal: (pendingAction) => {
82
- navigation.navigate('Auth', { pendingAction });
83
- },
84
- hasSubscription: isPremium,
85
- hasCredits: credits >= 5,
86
- creditBalance: credits,
87
- requiredCredits: 5,
88
- onShowPaywall: (required) => {
89
- if (!isAuthenticated) return;
90
- if (!hasSubscription) showPaywall();
91
- else showCreditPurchase(required);
92
- },
93
- });
94
-
95
- const handleAction = () => {
96
- requireFeature(async () => {
97
- await executeFeature();
98
- });
99
- };
100
-
101
- return (
102
- <Button
103
- onPress={handleAction}
104
- title={!canAccess ? 'Unlock Feature' : 'Execute'}
105
- />
106
- );
107
- }
108
-
109
- // INCORRECT - Missing auth callback
110
- const { requireFeature } = useFeatureGate({
111
- isAuthenticated: !!user,
112
- // Missing onShowAuthModal
113
- hasSubscription: isPremium,
114
- hasCredits: credits >= 5,
115
- creditBalance: credits,
116
- onShowPaywall: showPaywall,
117
- });
118
-
119
- // INCORRECT - No access check
120
- const handleAction = () => {
121
- requireFeature(() => executeFeature());
122
- };
123
- // Always shows button, even if user can't access
124
- ```
125
-
126
- ### Progressive Access Control
127
-
128
- ```typescript
129
- // CORRECT - Show appropriate message for each gate
130
- function ProgressiveGate() {
131
- const { canAccess, isAuthenticated, hasSubscription, hasCredits } = useFeatureGate({
132
- isAuthenticated: !!user,
133
- onShowAuthModal: (pending) => showAuthModal({ pendingAction: pending }),
134
- hasSubscription: isPremium,
135
- hasCredits: credits >= 3,
136
- creditBalance: credits,
137
- requiredCredits: 3,
138
- onShowPaywall: (required) => showUpgradeModal({ requiredCredits: required }),
139
- });
140
-
141
- const getAccessMessage = () => {
142
- if (!isAuthenticated) return 'Sign in to access';
143
- if (!hasSubscription && !hasCredits) return 'Upgrade or purchase credits';
144
- if (!hasCredits) return `Need ${requiredCredits} credits`;
145
- return 'Full access';
146
- };
147
-
148
- return (
149
- <View>
150
- <Text>{getAccessMessage()}</Text>
151
- <Button
152
- onPress={() => requireFeature(() => executeAction())}
153
- disabled={!canAccess}
154
- title={canAccess ? 'Execute' : 'Unlock'}
155
- />
156
- </View>
157
- );
158
- }
159
-
160
- // INCORRECT - Generic message for all gates
161
- if (!canAccess) {
162
- return <Text>You cannot access this feature</Text>;
163
- }
164
- // Doesn't tell user what they need to do
165
- ```
166
-
167
- ### Premium Bypass Logic
168
-
169
- ```typescript
170
- // CORRECT - Premium users bypass credit check
171
- function PremiumBypass() {
172
- const { requireFeature } = useFeatureGate({
173
- isAuthenticated: !!user,
174
- onShowAuthModal: (pending) => showAuthModal({ pendingAction: pending }),
175
- hasSubscription: isPremium,
176
- hasCredits: isPremium ? true : credits >= 5,
177
- creditBalance: credits,
178
- requiredCredits: isPremium ? 0 : 5,
179
- onShowPaywall: (required) => {
180
- if (isPremium) {
181
- showInsufficientCreditsModal(required);
182
- } else {
183
- showPaywall();
184
- }
185
- },
186
- });
187
-
188
- return <Button onPress={() => requireFeature(executeAction)} />;
189
- }
190
-
191
- // INCORRECT - Charges premium users for credits
192
- hasCredits: credits >= 5, // Even if isPremium is true
193
- requiredCredits: 5, // Charges premium users
194
- ```
195
-
196
- ### Callback Implementation
197
-
198
- ```typescript
199
- // CORRECT - Proper auth modal with pending action
200
- onShowAuthModal: (pendingAction) => {
201
- navigation.navigate('Auth', {
202
- onAuthSuccess: pendingAction,
203
- });
204
- }
205
-
206
- // CORRECT - Context-aware paywall
207
- onShowPaywall: (requiredCredits) => {
208
- if (isPremium) {
209
- // Already premium, need credits
210
- showCreditPurchaseModal({ requiredCredits });
211
- } else {
212
- // Not premium, show subscription
213
- showSubscriptionPaywall();
214
- }
215
- }
216
-
217
- // INCORRECT - No pending action preservation
218
- onShowAuthModal: () => {
219
- navigation.navigate('Auth');
220
- // User's intent is lost
221
- }
222
- ```
223
-
224
- ### Action Gating
225
-
226
- ```typescript
227
- // CORRECT - Gate action execution
228
- const handleGenerate = () => {
229
- requireFeature(async () => {
230
- // Only runs if all gates pass
231
- const result = await generateContent();
232
- showResult(result);
233
- });
234
- };
235
-
236
- // INCORRECT - Execute action before gating
237
- const handleGenerate = async () => {
238
- const result = await generateContent(); // Runs regardless!
239
- requireFeature(() => showResult(result));
240
- };
241
- ```
242
-
243
- ## AI Agent Guidelines
244
-
245
- ### When Implementing Feature Gates
246
-
247
- 1. **Always** check gates in order: Auth → Subscription → Credits
248
- 2. **Always** provide clear, specific messaging for each gate
249
- 3. **Always** preserve user intent through auth/purchase flows
250
- 4. **Always** bypass credit check for premium users (if applicable)
251
- 5. **Never** trust client-side gates for security (server validation required)
252
-
253
- ### Integration Checklist
254
-
255
- - [ ] Import from correct path: `@umituz/react-native-subscription`
256
- - [ ] Implement `onShowAuthModal` with pending action preservation
257
- - [ ] Implement `onShowPaywall` with context-aware messaging
258
- - [ ] Check `canAccess` before showing feature
259
- - [ ] Provide appropriate messaging for each gate state
260
- - [ ] Respect premium status (bypass credit check if needed)
261
- - [ ] Test all gate combinations (auth, subscription, credits)
262
- - [ ] Test pending action execution after auth/purchase
263
- - [ ] Implement error boundaries around gated actions
264
-
265
- ### Common Patterns to Implement
266
-
267
- 1. **Progressive Unlocking**: Show upgrade path for each gate
268
- 2. **Smart Paywalls**: Show subscription OR credits based on user state
269
- 3. **Intent Preservation**: Queue actions through auth/purchase flows
270
- 4. **Clear Messaging**: Tell users exactly what's required
271
- 5. **Premium Bypass**: Skip credit check for premium users
272
- 6. **Access Indicators**: Show lock/unlock status in UI
273
- 7. **Graceful Degradation**: Show limited version for free users
274
- 8. **Analytics Tracking**: Monitor gate triggers and conversions
275
-
276
- ## Related Documentation
277
-
278
- - **useAuthGate**: Authentication gating only
279
- - **useSubscriptionGate**: Subscription gating only
280
- - **useCreditsGate**: Credits gating only
281
- - **usePremiumGate**: Premium feature gating
282
- - **useDeductCredit**: Credit deduction after gate passes
283
- - **Feature Gating**: `../../../docs/FEATURE_GATING.md`
284
- - **Access Control**: `../../../docs/ACCESS_PATTERNS.md`