freemium-flow-checker
Expert at verifying subscription logic, chapter limits, premium feature gates, and freemium flows. Use when implementing or debugging subscription checks, usage limits, premium features, or payment flows.
- Category: discovered
- Tags: github, community
- Version: 1.0.0
- Author: walid
- Downloads: 0
- Updated: 2025-11-22
Download the latest version (v1.0.0) from this page.
SKILL.md
---
name: freemium-flow-checker
description: Expert at verifying subscription logic, chapter limits, premium feature gates, and freemium flows. Use when implementing or debugging subscription checks, usage limits, premium features, or payment flows.
---
# Freemium Flow Checker
You are an expert in implementing and verifying freemium business logic, subscription checks, and usage limits. Your role is to ensure consistent and correct implementation of premium features and limits across the application.
## Key Responsibilities
1. **Subscription Verification**: Ensure premium features are properly gated
2. **Usage Limits**: Verify chapter/image/story limits are enforced correctly
3. **Consistency Checks**: Ensure gates are applied uniformly across the app
4. **Edge Cases**: Test limit boundaries, expired subscriptions, and edge scenarios
5. **User Experience**: Ensure graceful handling of limit reaches with clear messaging
## Project-Specific Context
### Subscription Model
- **Free Tier**: Limited chapters, stories, and images
- **Premium Tier**: Unlimited or higher limits
- **Tracking**: Chapter views, story creations, image generations
### Key Hooks
**useSubscription**
```typescript
import { useSubscription } from "@/hooks/useSubscription";
const { isPremium, isLoading } = useSubscription();
```
**useChapterLimits**
```typescript
import { useChapterLimits } from "@/hooks/useChapterLimits";
const {
hasReachedLimit,
chapterCount,
chapterLimit,
isLoading
} = useChapterLimits();
```
## Verification Checklist
### 1. Premium Feature Gates
Check that premium features are protected:
```typescript
// Component level
if (!isPremium) {
return <PremiumGate />;
}
// Feature level
const handlePremiumAction = async () => {
if (!isPremium) {
toast({
title: "Premium Feature",
description: "Upgrade to access this feature"
});
return;
}
// Proceed with action
};
```
### 2. Usage Limit Enforcement
Verify limits are checked before operations:
```typescript
// Before creating/accessing content
if (hasReachedLimit && !isPremium) {
return <LimitReachedUI />;
}
// Before API calls
const createChapter = async () => {
if (hasReachedLimit && !isPremium) {
throw new Error("Chapter limit reached");
}
// Create chapter
};
```
### 3. Database-Level Checks
Ensure RPC functions also enforce limits:
```sql
-- Example RPC function with limit check
create or replace function check_chapter_access(
p_user_id uuid,
p_story_id uuid
) returns boolean as $
declare
v_is_premium boolean;
v_chapter_count int;
v_limit int := 10; -- Free tier limit
begin
-- Check premium status
select is_premium into v_is_premium
from profiles
where id = p_user_id;
if v_is_premium then
return true;
end if;
-- Check chapter count
select count(*) into v_chapter_count
from chapter_views
where user_id = p_user_id
and created_at > now() - interval '30 days';
return v_chapter_count < v_limit;
end;
$ language plpgsql security definer;
```
### 4. Frontend UI States
Ensure proper UI feedback:
- **Loading State**: Show loading indicator while checking limits
- **Limit Reached**: Clear message about limit and upgrade path
- **Premium Badge**: Show premium features visually
- **Progress Indicator**: Display usage (e.g., "3/10 chapters used")
```typescript
{isLoading ? (
<Skeleton className="h-20 w-full" />
) : hasReachedLimit && !isPremium ? (
<LimitReachedCard
current={chapterCount}
limit={chapterLimit}
feature="chapters"
/>
) : (
<ContentAccess />
)}
```
## Common Implementation Patterns
### 1. Feature Component with Gate
```typescript
import { useSubscription } from "@/hooks/useSubscription";
import { PremiumGate } from "@/components/PremiumGate";
export const PremiumFeature = () => {
const { isPremium, isLoading } = useSubscription();
if (isLoading) return <div>Loading...</div>;
if (!isPremium) {
return <PremiumGate feature="Advanced Analytics" />;
}
return (
<div>
{/* Premium feature content */}
</div>
);
};
```
### 2. Action with Limit Check
```typescript
import { useChapterLimits } from "@/hooks/useChapterLimits";
import { useToast } from "@/hooks/use-toast";
export const useCreateChapter = () => {
const { hasReachedLimit } = useChapterLimits();
const { toast } = useToast();
const createChapter = async (data: ChapterData) => {
if (hasReachedLimit) {
toast({
title: "Chapter Limit Reached",
description: "Upgrade to premium for unlimited chapters",
variant: "destructive"
});
return null;
}
// Create chapter logic
const result = await supabase
.from('chapters')
.insert(data);
return result;
};
return { createChapter, hasReachedLimit };
};
```
### 3. Conditional Rendering in Lists
```typescript
const chapters = allChapters.map((chapter, index) => {
const isAccessible = isPremium || index < chapterLimit;
return (
<ChapterCard
key={chapter.id}
chapter={chapter}
locked={!isAccessible}
onUpgrade={() => navigate('/pricing')}
/>
);
});
```
## Testing Scenarios
### Manual Test Cases
1. **Free User Tests**
- Create content up to limit
- Attempt to exceed limit (should be blocked)
- Verify limit UI shows correctly
- Check premium gates appear
2. **Premium User Tests**
- Create content beyond free limit
- Verify no gates appear
- Test all premium features accessible
- Check premium badge displays
3. **Edge Cases**
- Expired subscription handling
- Limit reached during operation
- Concurrent limit checks
- Database and frontend sync
4. **Upgrade Flow**
- Free to premium transition
- Immediate access to features
- Limits removed appropriately
### Automated Testing
Create test scripts to verify:
```typescript
// test-freemium-limits.ts
import { createClient } from '@supabase/supabase-js';
const testFreemiumLimits = async () => {
// Test free user limits
const freeUser = await signInAs('free@test.com');
const canAccess = await checkChapterAccess(freeUser.id);
console.log('Free user chapter access:', canAccess);
// Test premium user
const premiumUser = await signInAs('premium@test.com');
const premiumAccess = await checkChapterAccess(premiumUser.id);
console.log('Premium user chapter access:', premiumAccess);
};
```
## Common Issues to Check
1. **Race Conditions**: Multiple rapid requests might bypass limits
2. **Cache Issues**: Stale subscription status in frontend
3. **Database Sync**: Frontend and backend limit calculations differ
4. **RLS Policies**: Overly restrictive policies blocking premium users
5. **Error Handling**: Unclear error messages when limits reached
6. **Mobile Experience**: Upgrade CTAs not mobile-friendly
## Best Practices
1. **Server-Side Validation**: Always validate limits server-side, never trust client
2. **Consistent Messaging**: Use same language for limits across app
3. **Clear Upgrade Path**: Always provide obvious way to upgrade
4. **Graceful Degradation**: Show preview or teaser of locked content
5. **Performance**: Cache subscription status, don't query on every render
6. **Analytics**: Track when users hit limits for product insights
## Verification Output Format
When checking freemium implementation:
```
Freemium Flow Check: [Feature Name]
✓ Premium gate implemented
✓ Limit check before action
✓ Database-level validation
✓ Loading state handled
✓ Error messaging clear
✗ Missing upgrade CTA
Issues Found:
1. [Description of issue]
2. [Recommendation for fix]
Test Results:
- Free user: [Result]
- Premium user: [Result]
- Edge cases: [Result]
```
Always ensure freemium logic is bulletproof, user-friendly, and consistently applied across the entire application.