# Plan Limits Implementation Checklist

**Version:** v1.1.0 (Minor version - new feature)  
**Started:** December 12, 2025  
**Status:** In Progress

---

## 📋 Overview

Implementing comprehensive plan limit system to enforce pricing tier limits for:
- Hard limits (persistent): sites, users, keywords, clusters
- Monthly limits (reset on billing cycle): content ideas, words, images, prompts

---

## Phase 1: Backend Setup ✅ / ❌

### 1.1 Plan Model Updates
- [ ] Add `max_keywords` field to Plan model
- [ ] Add `max_clusters` field to Plan model  
- [ ] Add `max_content_ideas` field to Plan model
- [ ] Add `max_content_words` field to Plan model
- [ ] Add `max_images_basic` field to Plan model
- [ ] Add `max_images_premium` field to Plan model
- [ ] Add `max_image_prompts` field to Plan model
- [ ] Add help text and validators for all fields
- [ ] Update `__str__` method if needed

**File:** `backend/igny8_core/auth/models.py`

### 1.2 PlanLimitUsage Model Creation
- [ ] Create new `PlanLimitUsage` model
- [ ] Add fields: account, limit_type, amount_used, period_start, period_end
- [ ] Add Meta class with db_table, indexes, unique_together
- [ ] Add `__str__` method
- [ ] Add helper methods: `is_current_period()`, `remaining_allowance()`

**File:** `backend/igny8_core/business/billing/models.py`

### 1.3 Database Migration
- [ ] Run `makemigrations` command
- [ ] Review generated migration
- [ ] Test migration with `migrate --plan`
- [ ] Run migration `migrate`
- [ ] Verify schema in database

**Command:** `python manage.py makemigrations && python manage.py migrate`

### 1.4 Data Seeding
- [ ] Create data migration for existing plans
- [ ] Populate limit fields with default values (Starter: 2/1/100K, Growth: 5/3/300K, Scale: Unlimited/5/500K)
- [ ] Create initial PlanLimitUsage records for existing accounts
- [ ] Calculate current usage from existing data

**File:** `backend/igny8_core/business/billing/migrations/00XX_seed_plan_limits.py`

### 1.5 Word Counter Utility
- [ ] Create `word_counter.py` utility
- [ ] Implement `calculate_word_count(html_content)` function
- [ ] Strip HTML tags using BeautifulSoup or regex
- [ ] Handle edge cases (empty content, None, malformed HTML)
- [ ] Add unit tests

**File:** `backend/igny8_core/utils/word_counter.py`

### 1.6 Content Model Auto-Calculation
- [ ] Update Content model `save()` method
- [ ] Auto-calculate `word_count` when `content_html` changes
- [ ] Use `word_counter.calculate_word_count()`
- [ ] Test with sample content

**File:** `backend/igny8_core/business/content/models.py`

### 1.7 LimitService Creation
- [ ] Create `limit_service.py`
- [ ] Implement `check_hard_limit(account, limit_type)` - sites, users, keywords, clusters
- [ ] Implement `check_monthly_limit(account, limit_type, amount)` - ideas, words, images, prompts
- [ ] Implement `increment_usage(account, limit_type, amount, metadata)`
- [ ] Implement `get_usage_summary(account)` - current usage stats
- [ ] Implement `get_current_period(account)` - get billing period
- [ ] Create custom exceptions: `HardLimitExceededError`, `MonthlyLimitExceededError`
- [ ] Add logging for all operations
- [ ] Add unit tests

**File:** `backend/igny8_core/business/billing/services/limit_service.py`

### 1.8 Update PlanSerializer
- [ ] Add all new limit fields to `PlanSerializer.Meta.fields`
- [ ] Test serialization
- [ ] Verify API response includes new fields

**File:** `backend/igny8_core/auth/serializers.py`

### 1.9 Create LimitUsageSerializer
- [ ] Create `PlanLimitUsageSerializer`
- [ ] Include all fields
- [ ] Add computed fields: remaining, percentage_used

**File:** `backend/igny8_core/business/billing/serializers.py`

---

## Phase 2: Backend Enforcement ✅ / ❌

### 2.1 Hard Limit Enforcement - Sites
- [ ] Update `SiteViewSet.create()` to check `max_sites`
- [ ] Use `LimitService.check_hard_limit(account, 'sites')`
- [ ] Return proper error message if limit exceeded
- [ ] Test with different plan limits

**File:** `backend/igny8_core/auth/views.py`

### 2.2 Hard Limit Enforcement - Users
- [ ] Update user invitation logic to check `max_users`
- [ ] Use `LimitService.check_hard_limit(account, 'users')`
- [ ] Return proper error message if limit exceeded

**File:** `backend/igny8_core/auth/views.py` (UserViewSet or invitation endpoint)

### 2.3 Hard Limit Enforcement - Keywords
- [ ] Update keyword creation/import to check `max_keywords`
- [ ] Check before bulk import
- [ ] Check before individual creation
- [ ] Use `LimitService.check_hard_limit(account, 'keywords')`

**File:** `backend/igny8_core/business/planning/views.py`

### 2.4 Hard Limit Enforcement - Clusters
- [ ] Update clustering service to check `max_clusters`
- [ ] Check before AI clustering operation
- [ ] Use `LimitService.check_hard_limit(account, 'clusters')`

**File:** `backend/igny8_core/business/planning/services/clustering_service.py`

### 2.5 Monthly Limit Enforcement - Content Ideas
- [ ] Update idea generation service
- [ ] Check `max_content_ideas` before generation
- [ ] Increment usage after successful generation
- [ ] Use `LimitService.check_monthly_limit()` and `increment_usage()`

**File:** `backend/igny8_core/business/planning/services/idea_service.py` or similar

### 2.6 Monthly Limit Enforcement - Content Words
- [ ] Update content generation service
- [ ] Check `max_content_words` before generation
- [ ] Use `Content.word_count` for actual usage
- [ ] Increment usage after content created
- [ ] Sum word counts for batch operations

**File:** `backend/igny8_core/business/content/services/content_generation_service.py`

### 2.7 Monthly Limit Enforcement - Images
- [ ] Update image generation service
- [ ] Check `max_images_basic` or `max_images_premium` based on model
- [ ] Increment usage after image created
- [ ] Track basic vs premium separately

**File:** `backend/igny8_core/business/content/services/image_service.py` or similar

### 2.8 Monthly Limit Enforcement - Image Prompts
- [ ] Update image prompt extraction
- [ ] Check `max_image_prompts` before extraction
- [ ] Increment usage after prompts extracted

**File:** `backend/igny8_core/business/content/services/` (wherever prompts are extracted)

### 2.9 Automation Pipeline Integration
- [ ] Update automation to check limits before each stage
- [ ] Show limit warnings in pre-run estimation
- [ ] Stop automation if limit would be exceeded
- [ ] Log limit checks in activity log

**File:** `backend/igny8_core/business/automation/services/`

---

## Phase 3: Monthly Reset Task ✅ / ❌

### 3.1 Celery Task Creation
- [ ] Create `reset_monthly_plan_limits()` task
- [ ] Find accounts with billing period ending today
- [ ] Reset PlanLimitUsage records
- [ ] Create new records for new period
- [ ] Log reset operations
- [ ] Handle errors gracefully

**File:** `backend/igny8_core/tasks/billing.py`

### 3.2 Celery Beat Schedule
- [ ] Add task to `CELERY_BEAT_SCHEDULE`
- [ ] Set to run daily at midnight UTC
- [ ] Test task execution

**File:** `backend/igny8_core/celery.py`

### 3.3 Manual Reset Capability
- [ ] Create admin action to manually reset limits
- [ ] Add to `PlanLimitUsageAdmin`
- [ ] Test manual reset

**File:** `backend/igny8_core/business/billing/admin.py`

---

## Phase 4: API Endpoints ✅ / ❌

### 4.1 Limits Usage Endpoint
- [ ] Create `/api/v1/billing/limits/usage/` endpoint
- [ ] Return current usage for all limit types
- [ ] Return remaining allowance
- [ ] Return days until reset
- [ ] Include plan limits for reference
- [ ] Test endpoint

**File:** `backend/igny8_core/business/billing/views.py`

### 4.2 Limits History Endpoint (Optional)
- [ ] Create `/api/v1/billing/limits/history/` endpoint
- [ ] Return historical usage data
- [ ] Support date range filtering
- [ ] Test endpoint

**File:** `backend/igny8_core/business/billing/views.py`

---

## Phase 5: Frontend Updates ✅ / ❌

### 5.1 Update Plan Interface
- [ ] Add limit fields to Plan interface in `billing.api.ts`
- [ ] Add limit fields to Plan interface in `Settings/Plans.tsx`
- [ ] Add limit fields to Plan interface in `SignUpFormUnified.tsx`
- [ ] Add limit fields to Plan interface in `AuthPages/SignUp.tsx`
- [ ] Ensure consistency across all 4 locations

**Files:** Multiple interface definitions

### 5.2 Create PlanLimitsWidget Component
- [ ] Create `PlanLimitsWidget.tsx` component
- [ ] Display hard limits (Sites, Users, Keywords, Clusters) with counts
- [ ] Display monthly limits with progress bars
- [ ] Show days until reset
- [ ] Fetch from `/api/v1/billing/limits/usage/`
- [ ] Add refresh capability
- [ ] Style with existing design system

**File:** `frontend/src/components/dashboard/PlanLimitsWidget.tsx`

### 5.3 Update Dashboard
- [ ] Add `PlanLimitsWidget` to dashboard
- [ ] Position alongside CreditBalanceWidget
- [ ] Test responsive layout

**File:** `frontend/src/pages/Dashboard/Dashboard.tsx` or similar

### 5.4 Update Settings/Plans Page
- [ ] Display all limit fields in plan cards
- [ ] Format numbers (1,000 / 100K / Unlimited)
- [ ] Update `extractFeatures()` function
- [ ] Test plan display

**File:** `frontend/src/pages/Settings/Plans.tsx`

### 5.5 Update Usage Page
- [ ] Add limits section to Usage page
- [ ] Display current usage vs limits
- [ ] Show limit types (hard vs monthly)
- [ ] Add progress bars for monthly limits
- [ ] Test with real data

**File:** `frontend/src/pages/Billing/Usage.tsx`

### 5.6 Create Limit Exceeded Modal
- [ ] Create `LimitExceededModal.tsx` component
- [ ] Show when limit is reached
- [ ] Display current usage and limit
- [ ] Show upgrade options
- [ ] Link to billing page
- [ ] Style with existing modal pattern

**File:** `frontend/src/components/billing/LimitExceededModal.tsx`

### 5.7 Add Limit Guards
- [ ] Check limits before operations (optional - server-side is primary)
- [ ] Show limit exceeded modal on API error
- [ ] Handle `HardLimitExceededError` and `MonthlyLimitExceededError`
- [ ] Display user-friendly messages

**Files:** Various page components

---

## Phase 6: Admin & Testing ✅ / ❌

### 6.1 Django Admin for PlanLimitUsage
- [ ] Create `PlanLimitUsageAdmin` class
- [ ] Add list display fields
- [ ] Add filters (account, limit_type, period)
- [ ] Add search fields
- [ ] Add readonly fields (created_at, updated_at)
- [ ] Add custom actions (reset, export)
- [ ] Register admin

**File:** `backend/igny8_core/business/billing/admin.py`

### 6.2 Update Plan Admin
- [ ] Add new limit fields to `PlanAdmin`
- [ ] Group fields logically (Hard Limits, Monthly Limits)
- [ ] Add inline for related limit usage (optional)
- [ ] Test admin interface

**File:** `backend/igny8_core/auth/admin.py`

### 6.3 Backend Testing
- [ ] Test hard limit checks
- [ ] Test monthly limit checks
- [ ] Test limit increment
- [ ] Test monthly reset
- [ ] Test word count calculation
- [ ] Test API endpoints
- [ ] Test error handling

### 6.4 Frontend Testing
- [ ] Test plan display with limits
- [ ] Test limits widget
- [ ] Test usage page
- [ ] Test limit exceeded modal
- [ ] Test responsive design
- [ ] Test with different plan tiers

### 6.5 Integration Testing
- [ ] Test complete workflow: create content → check limits → increment usage
- [ ] Test monthly reset → verify limits reset
- [ ] Test upgrade plan → verify new limits apply
- [ ] Test limit exceeded → verify operation blocked
- [ ] Test across different accounts and sites

---

## Phase 7: Documentation ✅ / ❌

### 7.1 Update CHANGELOG
- [ ] Document all changes
- [ ] List new fields added
- [ ] List new services created
- [ ] List API endpoints added
- [ ] List frontend components added
- [ ] Update to v1.1.0

**File:** `CHANGELOG.md`

### 7.2 Update API Documentation
- [ ] Document `/api/v1/billing/limits/usage/` endpoint
- [ ] Document error responses
- [ ] Add examples

**File:** `docs/20-API/BILLING-ENDPOINTS.md`

### 7.3 Update Feature Guide
- [ ] Document plan limits feature
- [ ] Document limit types
- [ ] Document monthly reset
- [ ] Add to features list

**File:** `IGNY8-COMPLETE-FEATURES-GUIDE.md`

---

## Phase 8: Deployment ✅ / ❌

### 8.1 Pre-Deployment Checklist
- [ ] All migrations created and tested
- [ ] All tests passing
- [ ] No console errors in frontend
- [ ] CHANGELOG updated
- [ ] Version bumped to v1.1.0
- [ ] Code reviewed

### 8.2 Deployment Steps
- [ ] Backup database
- [ ] Run migrations
- [ ] Deploy backend
- [ ] Deploy frontend
- [ ] Verify limits working
- [ ] Monitor for errors

### 8.3 Post-Deployment Validation
- [ ] Test limit checks work
- [ ] Test usage tracking works
- [ ] Test monthly reset (wait or trigger manually)
- [ ] Verify no existing functionality broken
- [ ] Monitor error logs

---

## 📊 Progress Summary

**Total Tasks:** ~80  
**Completed:** 2  
**In Progress:** 1  
**Not Started:** 77

**Estimated Time:** 8-12 hours  
**Started:** December 12, 2025  
**Target Completion:** December 13, 2025

---

## 🔍 Testing Scenarios

### Scenario 1: Hard Limit - Sites
1. Account with Starter plan (max 2 sites)
2. Create 2 sites successfully
3. Try to create 3rd site → should fail with limit error

### Scenario 2: Monthly Limit - Content Words
1. Account with Starter plan (100K words/month)
2. Generate content totaling 99K words
3. Try to generate 2K words → should fail
4. Wait for monthly reset
5. Generate 2K words → should succeed

### Scenario 3: Monthly Reset
1. Account at end of billing period
2. Has used 90% of limits
3. Run reset task
4. Verify usage reset to 0
5. Verify new period created

### Scenario 4: Plan Upgrade
1. Account on Starter plan
2. Reached 100% of limit
3. Upgrade to Growth plan
4. Verify new limits apply
5. Perform operation → should succeed

---

## ⚠️ Known Risks & Mitigation

**Risk 1:** Breaking existing content generation  
**Mitigation:** Test thoroughly, use feature flags if needed

**Risk 2:** Word count inconsistency  
**Mitigation:** Use single source (Content.word_count), standardize calculation

**Risk 3:** Monthly reset errors  
**Mitigation:** Add error handling, logging, manual reset capability

**Risk 4:** Performance impact of limit checks  
**Mitigation:** Optimize queries, add database indexes, cache plan data

---

## 📝 Notes

- Use `Content.word_count` as single source of truth for word counting
- Ignore `estimated_word_count` in Ideas and `word_count` in Tasks for limit tracking
- Hard limits check COUNT from database
- Monthly limits track usage in PlanLimitUsage table
- Reset task must be idempotent (safe to run multiple times)
- All limit checks happen server-side (frontend is informational only)
- Use proper error classes for different limit types
- Log all limit operations for debugging
