9 phases
This commit is contained in:
524
docs/planning/phases/PHASE-0-FOUNDATION-CREDIT-SYSTEM.md
Normal file
524
docs/planning/phases/PHASE-0-FOUNDATION-CREDIT-SYSTEM.md
Normal file
@@ -0,0 +1,524 @@
|
|||||||
|
# PHASE 0: FOUNDATION & CREDIT SYSTEM
|
||||||
|
**Detailed Implementation Plan**
|
||||||
|
|
||||||
|
**Goal**: Migrate to credit-only model while preserving all existing functionality.
|
||||||
|
|
||||||
|
**Timeline**: 1-2 weeks
|
||||||
|
**Priority**: HIGH
|
||||||
|
**Dependencies**: None
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TABLE OF CONTENTS
|
||||||
|
|
||||||
|
1. [Overview](#overview)
|
||||||
|
2. [Module Settings System](#module-settings-system)
|
||||||
|
3. [Credit System Updates](#credit-system-updates)
|
||||||
|
4. [Operational Limits](#operational-limits)
|
||||||
|
5. [Database Migrations](#database-migrations)
|
||||||
|
6. [Testing & Validation](#testing--validation)
|
||||||
|
7. [Implementation Checklist](#implementation-checklist)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## OVERVIEW
|
||||||
|
|
||||||
|
### Objectives
|
||||||
|
- ✅ Migrate from plan-based limits to credit-only system
|
||||||
|
- ✅ Implement module enable/disable functionality
|
||||||
|
- ✅ Add credit cost tracking for all operations
|
||||||
|
- ✅ Preserve all existing functionality
|
||||||
|
- ✅ Update frontend to show credits instead of limits
|
||||||
|
|
||||||
|
### Key Principles
|
||||||
|
- **Backward Compatibility**: All existing APIs continue working
|
||||||
|
- **No Breaking Changes**: Frontend continues working without changes
|
||||||
|
- **Gradual Migration**: Add credit checks without removing existing code initially
|
||||||
|
- **Credit-Only Model**: Remove all plan limit fields, keep only credits
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## MODULE SETTINGS SYSTEM
|
||||||
|
|
||||||
|
### 0.0 Module Settings System (Enable/Disable Modules)
|
||||||
|
|
||||||
|
**Purpose**: Allow accounts to enable/disable modules per account.
|
||||||
|
|
||||||
|
#### Backend Implementation
|
||||||
|
|
||||||
|
| Task | File | Current State | Implementation |
|
||||||
|
|------|------|---------------|----------------|
|
||||||
|
| **Extend ModuleSettings Model** | `domain/system/models.py` | EXISTING (ModuleSettings) | Add `enabled` boolean field per module |
|
||||||
|
| **Module Settings API** | `modules/system/views.py` | EXISTING | Extend ViewSet to handle enable/disable |
|
||||||
|
| **Module Settings Serializer** | `modules/system/serializers.py` | EXISTING | Add enabled field to serializer |
|
||||||
|
|
||||||
|
**ModuleSettings Model Extension**:
|
||||||
|
```python
|
||||||
|
# domain/system/models.py (or core/system/models.py if exists)
|
||||||
|
class ModuleSettings(AccountBaseModel):
|
||||||
|
# Existing fields...
|
||||||
|
|
||||||
|
# NEW: Module enable/disable flags
|
||||||
|
planner_enabled = models.BooleanField(default=True)
|
||||||
|
writer_enabled = models.BooleanField(default=True)
|
||||||
|
thinker_enabled = models.BooleanField(default=True)
|
||||||
|
automation_enabled = models.BooleanField(default=True)
|
||||||
|
site_builder_enabled = models.BooleanField(default=True)
|
||||||
|
linker_enabled = models.BooleanField(default=True)
|
||||||
|
optimizer_enabled = models.BooleanField(default=True)
|
||||||
|
publisher_enabled = models.BooleanField(default=True)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Modules to Control**:
|
||||||
|
- Planner
|
||||||
|
- Writer
|
||||||
|
- Thinker
|
||||||
|
- Automation
|
||||||
|
- Site Builder (NEW)
|
||||||
|
- Linker (NEW)
|
||||||
|
- Optimizer (NEW)
|
||||||
|
- Publisher (NEW)
|
||||||
|
|
||||||
|
#### Frontend Implementation
|
||||||
|
|
||||||
|
| Task | File | Current State | Implementation |
|
||||||
|
|------|------|---------------|----------------|
|
||||||
|
| **Module Settings UI** | `frontend/src/pages/Settings/Modules.tsx` | EXISTING (placeholder) | Implement toggle UI for each module |
|
||||||
|
| **Frontend Module Loader** | `frontend/src/config/modules.config.ts` | NEW | Define module config with enabled checks |
|
||||||
|
| **Route Guard** | `frontend/src/components/common/ModuleGuard.tsx` | NEW | Component to check module status before rendering |
|
||||||
|
| **Sidebar Filter** | `frontend/src/layout/AppSidebar.tsx` | EXISTING | Filter out disabled modules from sidebar |
|
||||||
|
|
||||||
|
**Module Enable/Disable Logic**:
|
||||||
|
- Each module has `enabled` flag in ModuleSettings
|
||||||
|
- Frontend checks module status before loading routes
|
||||||
|
- Disabled modules don't appear in sidebar
|
||||||
|
- Disabled modules don't load code (lazy loading check)
|
||||||
|
|
||||||
|
**Module Config Example**:
|
||||||
|
```typescript
|
||||||
|
// frontend/src/config/modules.config.ts
|
||||||
|
export const MODULES = {
|
||||||
|
planner: {
|
||||||
|
name: 'Planner',
|
||||||
|
route: '/planner',
|
||||||
|
enabled: true, // Checked from API
|
||||||
|
},
|
||||||
|
writer: {
|
||||||
|
name: 'Writer',
|
||||||
|
route: '/writer',
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
// ... other modules
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
**Route Guard Example**:
|
||||||
|
```typescript
|
||||||
|
// frontend/src/components/common/ModuleGuard.tsx
|
||||||
|
const ModuleGuard = ({ module, children }) => {
|
||||||
|
const { moduleSettings } = useSettingsStore();
|
||||||
|
const isEnabled = moduleSettings[module]?.enabled ?? true;
|
||||||
|
|
||||||
|
if (!isEnabled) {
|
||||||
|
return <Navigate to="/settings/modules" />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return children;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CREDIT SYSTEM UPDATES
|
||||||
|
|
||||||
|
### 0.1 Credit System Updates
|
||||||
|
|
||||||
|
**Purpose**: Migrate from plan-based limits to credit-only system.
|
||||||
|
|
||||||
|
#### Plan Model Updates
|
||||||
|
|
||||||
|
| Task | File | Current State | Implementation |
|
||||||
|
|------|------|---------------|----------------|
|
||||||
|
| **Remove Plan Limit Fields** | `core/auth/models.py` | EXISTING | Remove all limit fields, add migration |
|
||||||
|
| **Update Plan Model** | `core/auth/models.py` | EXISTING | Keep only `monthly_credits`, `support_level`, `billing_cycle`, `price` |
|
||||||
|
|
||||||
|
**Plan Model (Simplified)**:
|
||||||
|
```python
|
||||||
|
# core/auth/models.py
|
||||||
|
class Plan(models.Model):
|
||||||
|
name = models.CharField(max_length=255)
|
||||||
|
monthly_credits = models.IntegerField(default=0) # KEEP
|
||||||
|
support_level = models.CharField(max_length=50) # KEEP
|
||||||
|
billing_cycle = models.CharField(max_length=20) # KEEP
|
||||||
|
price = models.DecimalField(max_digits=10, decimal_places=2) # KEEP
|
||||||
|
features = models.JSONField(default=dict) # KEEP (for future use)
|
||||||
|
|
||||||
|
# REMOVE: All limit fields
|
||||||
|
# - max_keywords
|
||||||
|
# - max_clusters
|
||||||
|
# - max_content_ideas
|
||||||
|
# - daily_content_tasks
|
||||||
|
# - monthly_word_count_limit
|
||||||
|
# - daily_image_generation_limit
|
||||||
|
# - monthly_image_count
|
||||||
|
# - etc.
|
||||||
|
```
|
||||||
|
|
||||||
|
**Migration Strategy**:
|
||||||
|
1. Create migration to add defaults for removed fields (if needed)
|
||||||
|
2. Create migration to remove limit fields
|
||||||
|
3. Ensure existing accounts have credit balances set
|
||||||
|
|
||||||
|
#### Credit Cost Constants
|
||||||
|
|
||||||
|
| Task | File | Current State | Implementation |
|
||||||
|
|------|------|---------------|----------------|
|
||||||
|
| **Add Credit Costs** | `domain/billing/constants.py` | NEW | Define credit costs per operation |
|
||||||
|
|
||||||
|
**Credit Cost Constants**:
|
||||||
|
```python
|
||||||
|
# domain/billing/constants.py
|
||||||
|
CREDIT_COSTS = {
|
||||||
|
'clustering': 10, # Per clustering request
|
||||||
|
'idea_generation': 15, # Per cluster → ideas request
|
||||||
|
'content_generation': 1, # Per 100 words
|
||||||
|
'image_prompt_extraction': 2, # Per content piece
|
||||||
|
'image_generation': 5, # Per image
|
||||||
|
'linking': 8, # Per content piece (NEW)
|
||||||
|
'optimization': 1, # Per 200 words (NEW)
|
||||||
|
'site_structure_generation': 50, # Per site blueprint (NEW)
|
||||||
|
'site_page_generation': 20, # Per page (NEW)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### CreditService Updates
|
||||||
|
|
||||||
|
| Task | File | Current State | Implementation |
|
||||||
|
|------|------|---------------|----------------|
|
||||||
|
| **Update CreditService** | `domain/billing/services/credit_service.py` | EXISTING | Add credit cost constants, update methods |
|
||||||
|
|
||||||
|
**CreditService Methods**:
|
||||||
|
```python
|
||||||
|
# domain/billing/services/credit_service.py
|
||||||
|
class CreditService:
|
||||||
|
def check_credits(self, account, operation_type, amount=None):
|
||||||
|
"""Check if account has sufficient credits"""
|
||||||
|
required = self.get_credit_cost(operation_type, amount)
|
||||||
|
if account.credits < required:
|
||||||
|
raise InsufficientCreditsError(f"Need {required} credits, have {account.credits}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
def deduct_credits(self, account, operation_type, amount=None):
|
||||||
|
"""Deduct credits after operation"""
|
||||||
|
cost = self.get_credit_cost(operation_type, amount)
|
||||||
|
account.credits -= cost
|
||||||
|
account.save()
|
||||||
|
# Log usage
|
||||||
|
CreditUsageLog.objects.create(...)
|
||||||
|
|
||||||
|
def get_credit_cost(self, operation_type, amount=None):
|
||||||
|
"""Get credit cost for operation"""
|
||||||
|
base_cost = CREDIT_COSTS.get(operation_type, 0)
|
||||||
|
if operation_type == 'content_generation' and amount:
|
||||||
|
return base_cost * (amount / 100) # Per 100 words
|
||||||
|
if operation_type == 'optimization' and amount:
|
||||||
|
return base_cost * (amount / 200) # Per 200 words
|
||||||
|
return base_cost
|
||||||
|
```
|
||||||
|
|
||||||
|
#### AI Engine Updates
|
||||||
|
|
||||||
|
| Task | File | Current State | Implementation |
|
||||||
|
|------|------|---------------|----------------|
|
||||||
|
| **Update AI Engine** | `infrastructure/ai/engine.py` | EXISTING | Check credits before AI calls |
|
||||||
|
|
||||||
|
**AI Engine Credit Check**:
|
||||||
|
```python
|
||||||
|
# infrastructure/ai/engine.py
|
||||||
|
class AIEngine:
|
||||||
|
def execute(self, function, payload, account):
|
||||||
|
# Check credits BEFORE AI call
|
||||||
|
operation_type = function.get_operation_type()
|
||||||
|
estimated_cost = function.get_estimated_cost(payload)
|
||||||
|
|
||||||
|
credit_service.check_credits(account, operation_type, estimated_cost)
|
||||||
|
|
||||||
|
# Execute AI function
|
||||||
|
result = function.execute(payload)
|
||||||
|
|
||||||
|
# Deduct credits AFTER successful execution
|
||||||
|
credit_service.deduct_credits(account, operation_type, actual_cost)
|
||||||
|
|
||||||
|
return result
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Content Generation Updates
|
||||||
|
|
||||||
|
| Task | File | Current State | Implementation |
|
||||||
|
|------|------|---------------|----------------|
|
||||||
|
| **Update Content Generation** | `domain/content/services/content_generation_service.py` | NEW (Phase 1) | Check credits before generation |
|
||||||
|
|
||||||
|
**Content Generation Credit Check**:
|
||||||
|
```python
|
||||||
|
# domain/content/services/content_generation_service.py
|
||||||
|
class ContentGenerationService:
|
||||||
|
def generate_content(self, task, account):
|
||||||
|
# Check credits before generation
|
||||||
|
estimated_words = task.estimated_word_count or 1000
|
||||||
|
credit_service.check_credits(account, 'content_generation', estimated_words)
|
||||||
|
|
||||||
|
# Generate content
|
||||||
|
content = self._generate(task)
|
||||||
|
|
||||||
|
# Deduct credits after generation
|
||||||
|
actual_words = content.word_count
|
||||||
|
credit_service.deduct_credits(account, 'content_generation', actual_words)
|
||||||
|
|
||||||
|
return content
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Image Generation Updates
|
||||||
|
|
||||||
|
| Task | File | Current State | Implementation |
|
||||||
|
|------|------|---------------|----------------|
|
||||||
|
| **Update Image Generation** | `infrastructure/ai/functions/generate_images.py` | EXISTING | Check credits before generation |
|
||||||
|
|
||||||
|
**Image Generation Credit Check**:
|
||||||
|
```python
|
||||||
|
# infrastructure/ai/functions/generate_images.py
|
||||||
|
class GenerateImagesFunction(BaseAIFunction):
|
||||||
|
def execute(self, payload, account):
|
||||||
|
image_ids = payload['image_ids']
|
||||||
|
|
||||||
|
# Check credits before generation
|
||||||
|
credit_service.check_credits(account, 'image_generation', len(image_ids))
|
||||||
|
|
||||||
|
# Generate images
|
||||||
|
results = self._generate_images(image_ids)
|
||||||
|
|
||||||
|
# Deduct credits after generation
|
||||||
|
credit_service.deduct_credits(account, 'image_generation', len(results))
|
||||||
|
|
||||||
|
return results
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Remove Limit Checks
|
||||||
|
|
||||||
|
| Task | File | Current State | Implementation |
|
||||||
|
|------|------|---------------|----------------|
|
||||||
|
| **Remove Limit Checks** | All services | EXISTING | Remove all plan limit validations |
|
||||||
|
|
||||||
|
**Files to Update**:
|
||||||
|
- `modules/planner/views.py` - Remove keyword/cluster limit checks
|
||||||
|
- `modules/writer/views.py` - Remove task/content limit checks
|
||||||
|
- `infrastructure/ai/engine.py` - Remove plan limit checks
|
||||||
|
- All ViewSets - Remove limit validation
|
||||||
|
|
||||||
|
**Before (Remove)**:
|
||||||
|
```python
|
||||||
|
# OLD: Check plan limits
|
||||||
|
if account.plan.max_keywords and keywords_count > account.plan.max_keywords:
|
||||||
|
raise ValidationError("Exceeds plan limit")
|
||||||
|
```
|
||||||
|
|
||||||
|
**After (Credit Only)**:
|
||||||
|
```python
|
||||||
|
# NEW: Check credits only
|
||||||
|
credit_service.check_credits(account, 'clustering', keyword_count)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Usage Logging Updates
|
||||||
|
|
||||||
|
| Task | File | Current State | Implementation |
|
||||||
|
|------|------|---------------|----------------|
|
||||||
|
| **Update Usage Logging** | `domain/billing/models.py` | EXISTING | Ensure all operations log credits |
|
||||||
|
|
||||||
|
**CreditUsageLog Model**:
|
||||||
|
```python
|
||||||
|
# domain/billing/models.py
|
||||||
|
class CreditUsageLog(AccountBaseModel):
|
||||||
|
account = models.ForeignKey(Account, on_delete=models.CASCADE)
|
||||||
|
operation_type = models.CharField(max_length=50)
|
||||||
|
credits_used = models.IntegerField()
|
||||||
|
related_object_type = models.CharField(max_length=50, blank=True)
|
||||||
|
related_object_id = models.IntegerField(null=True, blank=True)
|
||||||
|
metadata = models.JSONField(default=dict)
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Frontend Updates
|
||||||
|
|
||||||
|
| Task | File | Current State | Implementation |
|
||||||
|
|------|------|---------------|----------------|
|
||||||
|
| **Update Frontend Limits UI** | `frontend/src/pages/Billing/` | EXISTING | Replace limits display with credit display |
|
||||||
|
|
||||||
|
**Frontend Changes**:
|
||||||
|
- Remove plan limit displays
|
||||||
|
- Show credit balance prominently
|
||||||
|
- Show credit costs per operation
|
||||||
|
- Show usage history by operation type
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## OPERATIONAL LIMITS
|
||||||
|
|
||||||
|
### 0.2 Operational Limits (Keep)
|
||||||
|
|
||||||
|
**Purpose**: Technical constraints, not business limits.
|
||||||
|
|
||||||
|
| Limit | Value | Location | Implementation | Reason |
|
||||||
|
|-------|-------|----------|----------------|--------|
|
||||||
|
| **Keywords per request** | 50 | `modules/planner/views.py` | Request validation | API payload size, processing time |
|
||||||
|
| **Images per request** | 6 | `modules/writer/views.py` | Request validation | Queue management (user sees as batch) |
|
||||||
|
| **Images per AI call** | 1 | `infrastructure/ai/functions/generate_images.py` | Internal | Image API limitation |
|
||||||
|
|
||||||
|
**Note**: These are **NOT** business limits - they're technical constraints for request processing.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## DATABASE MIGRATIONS
|
||||||
|
|
||||||
|
### 0.3 Database Migrations
|
||||||
|
|
||||||
|
| Migration | Purpose | Risk | Implementation |
|
||||||
|
|-----------|---------|------|----------------|
|
||||||
|
| **Remove limit fields from Plan** | Clean up unused fields | LOW - Add defaults first | Create migration to remove fields |
|
||||||
|
| **Add credit cost tracking** | Enhance CreditUsageLog | LOW - Additive only | Add fields to CreditUsageLog |
|
||||||
|
| **Monthly credit replenishment** | Celery Beat task | LOW - New feature | Add scheduled task |
|
||||||
|
|
||||||
|
**Migration 1: Remove Plan Limit Fields**:
|
||||||
|
```python
|
||||||
|
# core/auth/migrations/XXXX_remove_plan_limits.py
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(model_name='plan', name='max_keywords'),
|
||||||
|
migrations.RemoveField(model_name='plan', name='max_clusters'),
|
||||||
|
# ... remove all limit fields
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Migration 2: Add Credit Cost Tracking**:
|
||||||
|
```python
|
||||||
|
# domain/billing/migrations/XXXX_add_credit_tracking.py
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='creditusagelog',
|
||||||
|
name='related_object_type',
|
||||||
|
field=models.CharField(max_length=50, blank=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='creditusagelog',
|
||||||
|
name='related_object_id',
|
||||||
|
field=models.IntegerField(null=True, blank=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='creditusagelog',
|
||||||
|
name='metadata',
|
||||||
|
field=models.JSONField(default=dict),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Migration 3: Monthly Credit Replenishment**:
|
||||||
|
- Add Celery Beat task (see Automation section)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TESTING & VALIDATION
|
||||||
|
|
||||||
|
### 0.4 Testing
|
||||||
|
|
||||||
|
**Test Cases**:
|
||||||
|
|
||||||
|
1. **Credit System Tests**:
|
||||||
|
- ✅ All existing features work with credit checks
|
||||||
|
- ✅ Credit deduction happens correctly
|
||||||
|
- ✅ Insufficient credits show clear error
|
||||||
|
- ✅ Usage logging tracks all operations
|
||||||
|
- ✅ Frontend shows credit balance, not limits
|
||||||
|
|
||||||
|
2. **Module Settings Tests**:
|
||||||
|
- ✅ Disabled modules don't appear in sidebar
|
||||||
|
- ✅ Disabled modules don't load routes
|
||||||
|
- ✅ Disabled modules return 403/404 appropriately
|
||||||
|
- ✅ Module settings persist correctly
|
||||||
|
|
||||||
|
3. **Backward Compatibility Tests**:
|
||||||
|
- ✅ All existing API endpoints work
|
||||||
|
- ✅ All existing workflows function
|
||||||
|
- ✅ Frontend continues working
|
||||||
|
- ✅ No data loss during migration
|
||||||
|
|
||||||
|
**Test Files to Create**:
|
||||||
|
- `backend/tests/test_credit_system.py`
|
||||||
|
- `backend/tests/test_module_settings.py`
|
||||||
|
- `frontend/src/__tests__/ModuleGuard.test.tsx`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## IMPLEMENTATION CHECKLIST
|
||||||
|
|
||||||
|
### Backend Tasks
|
||||||
|
|
||||||
|
- [ ] Create `domain/billing/constants.py` with credit costs
|
||||||
|
- [ ] Update `CreditService` with credit cost methods
|
||||||
|
- [ ] Update `Plan` model - remove limit fields
|
||||||
|
- [ ] Create migration to remove plan limit fields
|
||||||
|
- [ ] Update `AIEngine` to check credits before AI calls
|
||||||
|
- [ ] Update content generation to check credits
|
||||||
|
- [ ] Update image generation to check credits
|
||||||
|
- [ ] Remove all plan limit checks from ViewSets
|
||||||
|
- [ ] Update `CreditUsageLog` model with tracking fields
|
||||||
|
- [ ] Create migration for credit tracking
|
||||||
|
- [ ] Extend `ModuleSettings` model with enabled flags
|
||||||
|
- [ ] Update module settings API
|
||||||
|
- [ ] Add monthly credit replenishment Celery Beat task
|
||||||
|
|
||||||
|
### Frontend Tasks
|
||||||
|
|
||||||
|
- [ ] Implement `frontend/src/pages/Settings/Modules.tsx`
|
||||||
|
- [ ] Create `frontend/src/config/modules.config.ts`
|
||||||
|
- [ ] Create `frontend/src/components/common/ModuleGuard.tsx`
|
||||||
|
- [ ] Update `frontend/src/App.tsx` with conditional route loading
|
||||||
|
- [ ] Update `frontend/src/layout/AppSidebar.tsx` to filter disabled modules
|
||||||
|
- [ ] Update `frontend/src/pages/Billing/` to show credits instead of limits
|
||||||
|
- [ ] Update billing UI to show credit costs per operation
|
||||||
|
|
||||||
|
### Testing Tasks
|
||||||
|
|
||||||
|
- [ ] Test credit deduction for all operations
|
||||||
|
- [ ] Test insufficient credits error handling
|
||||||
|
- [ ] Test module enable/disable functionality
|
||||||
|
- [ ] Test disabled modules don't load
|
||||||
|
- [ ] Test backward compatibility
|
||||||
|
- [ ] Test migration safety
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## RISK ASSESSMENT
|
||||||
|
|
||||||
|
| Risk | Level | Mitigation |
|
||||||
|
|------|-------|------------|
|
||||||
|
| **Breaking existing functionality** | MEDIUM | Extensive testing, gradual rollout |
|
||||||
|
| **Credit calculation errors** | MEDIUM | Unit tests for credit calculations |
|
||||||
|
| **Migration data loss** | LOW | Backup before migration, test on staging |
|
||||||
|
| **Frontend breaking changes** | LOW | Backward compatible API changes |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SUCCESS CRITERIA
|
||||||
|
|
||||||
|
- ✅ All existing features work with credit checks
|
||||||
|
- ✅ Credit deduction happens correctly for all operations
|
||||||
|
- ✅ Insufficient credits show clear error messages
|
||||||
|
- ✅ Usage logging tracks all operations
|
||||||
|
- ✅ Frontend shows credit balance, not limits
|
||||||
|
- ✅ Module settings enable/disable modules correctly
|
||||||
|
- ✅ Disabled modules don't appear in UI
|
||||||
|
- ✅ No breaking changes for existing users
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**END OF PHASE 0 DOCUMENT**
|
||||||
|
|
||||||
436
docs/planning/phases/PHASE-1-SERVICE-LAYER-REFACTORING.md
Normal file
436
docs/planning/phases/PHASE-1-SERVICE-LAYER-REFACTORING.md
Normal file
@@ -0,0 +1,436 @@
|
|||||||
|
# PHASE 1: SERVICE LAYER REFACTORING
|
||||||
|
**Detailed Implementation Plan**
|
||||||
|
|
||||||
|
**Goal**: Extract business logic from ViewSets into services, preserving all existing functionality.
|
||||||
|
|
||||||
|
**Timeline**: 2-3 weeks
|
||||||
|
**Priority**: HIGH
|
||||||
|
**Dependencies**: Phase 0
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TABLE OF CONTENTS
|
||||||
|
|
||||||
|
1. [Overview](#overview)
|
||||||
|
2. [Create Domain Structure](#create-domain-structure)
|
||||||
|
3. [Move Models to Domain](#move-models-to-domain)
|
||||||
|
4. [Create Services](#create-services)
|
||||||
|
5. [Refactor ViewSets](#refactor-viewsets)
|
||||||
|
6. [Testing & Validation](#testing--validation)
|
||||||
|
7. [Implementation Checklist](#implementation-checklist)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## OVERVIEW
|
||||||
|
|
||||||
|
### Objectives
|
||||||
|
- ✅ Create `domain/` folder structure
|
||||||
|
- ✅ Move models from `modules/` to `domain/`
|
||||||
|
- ✅ Extract business logic from ViewSets to services
|
||||||
|
- ✅ Keep ViewSets as thin wrappers
|
||||||
|
- ✅ Preserve all existing API functionality
|
||||||
|
|
||||||
|
### Key Principles
|
||||||
|
- **Backward Compatibility**: All APIs remain unchanged
|
||||||
|
- **Service Layer Pattern**: Business logic in services, not ViewSets
|
||||||
|
- **No Breaking Changes**: Response formats unchanged
|
||||||
|
- **Testable Services**: Services can be tested independently
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CREATE DOMAIN STRUCTURE
|
||||||
|
|
||||||
|
### 1.1 Create Domain Structure
|
||||||
|
|
||||||
|
**Purpose**: Organize code by business domains, not technical layers.
|
||||||
|
|
||||||
|
#### Folder Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
backend/igny8_core/
|
||||||
|
├── domain/ # NEW: Domain layer
|
||||||
|
│ ├── content/ # Content domain
|
||||||
|
│ │ ├── __init__.py
|
||||||
|
│ │ ├── models.py # Content, Tasks, Images
|
||||||
|
│ │ ├── services/
|
||||||
|
│ │ │ ├── __init__.py
|
||||||
|
│ │ │ ├── content_generation_service.py
|
||||||
|
│ │ │ ├── content_pipeline_service.py
|
||||||
|
│ │ │ └── content_versioning_service.py
|
||||||
|
│ │ └── migrations/
|
||||||
|
│ │
|
||||||
|
│ ├── planning/ # Planning domain
|
||||||
|
│ │ ├── __init__.py
|
||||||
|
│ │ ├── models.py # Keywords, Clusters, Ideas
|
||||||
|
│ │ ├── services/
|
||||||
|
│ │ │ ├── __init__.py
|
||||||
|
│ │ │ ├── clustering_service.py
|
||||||
|
│ │ │ └── ideas_service.py
|
||||||
|
│ │ └── migrations/
|
||||||
|
│ │
|
||||||
|
│ ├── billing/ # Billing domain (already exists)
|
||||||
|
│ │ ├── models.py # Credits, Transactions
|
||||||
|
│ │ └── services/
|
||||||
|
│ │ └── credit_service.py # Already exists
|
||||||
|
│ │
|
||||||
|
│ └── automation/ # Automation domain (Phase 2)
|
||||||
|
│ ├── models.py
|
||||||
|
│ └── services/
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Implementation Tasks
|
||||||
|
|
||||||
|
| Task | File | Current Location | New Location | Risk |
|
||||||
|
|------|------|------------------|--------------|------|
|
||||||
|
| **Create domain/ folder** | `backend/igny8_core/domain/` | N/A | NEW | LOW |
|
||||||
|
| **Create content domain** | `domain/content/` | N/A | NEW | LOW |
|
||||||
|
| **Create planning domain** | `domain/planning/` | N/A | NEW | LOW |
|
||||||
|
| **Create billing domain** | `domain/billing/` | `modules/billing/` | MOVE | LOW |
|
||||||
|
| **Create automation domain** | `domain/automation/` | N/A | NEW (Phase 2) | LOW |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## MOVE MODELS TO DOMAIN
|
||||||
|
|
||||||
|
### 1.2 Move Models to Domain
|
||||||
|
|
||||||
|
**Purpose**: Move models from `modules/` to `domain/` to separate business logic from API layer.
|
||||||
|
|
||||||
|
#### Content Models Migration
|
||||||
|
|
||||||
|
| Model | Current Location | New Location | Changes Needed |
|
||||||
|
|------|------------------|--------------|----------------|
|
||||||
|
| `Content` | `modules/writer/models.py` | `domain/content/models.py` | Move, update imports |
|
||||||
|
| `Tasks` | `modules/writer/models.py` | `domain/content/models.py` | Move, update imports |
|
||||||
|
| `Images` | `modules/writer/models.py` | `domain/content/models.py` | Move, update imports |
|
||||||
|
|
||||||
|
**Migration Steps**:
|
||||||
|
1. Create `domain/content/models.py`
|
||||||
|
2. Copy models from `modules/writer/models.py`
|
||||||
|
3. Update imports in `modules/writer/views.py`
|
||||||
|
4. Create migration to ensure no data loss
|
||||||
|
5. Update all references to models
|
||||||
|
|
||||||
|
#### Planning Models Migration
|
||||||
|
|
||||||
|
| Model | Current Location | New Location | Changes Needed |
|
||||||
|
|------|------------------|--------------|----------------|
|
||||||
|
| `Keywords` | `modules/planner/models.py` | `domain/planning/models.py` | Move, update imports |
|
||||||
|
| `Clusters` | `modules/planner/models.py` | `domain/planning/models.py` | Move, update imports |
|
||||||
|
| `ContentIdeas` | `modules/planner/models.py` | `domain/planning/models.py` | Move, update imports |
|
||||||
|
|
||||||
|
**Migration Steps**:
|
||||||
|
1. Create `domain/planning/models.py`
|
||||||
|
2. Copy models from `modules/planner/models.py`
|
||||||
|
3. Update imports in `modules/planner/views.py`
|
||||||
|
4. Create migration to ensure no data loss
|
||||||
|
5. Update all references to models
|
||||||
|
|
||||||
|
#### Billing Models Migration
|
||||||
|
|
||||||
|
| Model | Current Location | New Location | Changes Needed |
|
||||||
|
|------|------------------|--------------|----------------|
|
||||||
|
| `CreditTransaction` | `modules/billing/models.py` | `domain/billing/models.py` | Move, update imports |
|
||||||
|
| `CreditUsageLog` | `modules/billing/models.py` | `domain/billing/models.py` | Move, update imports |
|
||||||
|
|
||||||
|
**Migration Steps**:
|
||||||
|
1. Create `domain/billing/models.py`
|
||||||
|
2. Copy models from `modules/billing/models.py`
|
||||||
|
3. Move `CreditService` to `domain/billing/services/credit_service.py`
|
||||||
|
4. Update imports in `modules/billing/views.py`
|
||||||
|
5. Create migration to ensure no data loss
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CREATE SERVICES
|
||||||
|
|
||||||
|
### 1.3 Create Services
|
||||||
|
|
||||||
|
**Purpose**: Extract business logic from ViewSets into reusable services.
|
||||||
|
|
||||||
|
#### ContentService
|
||||||
|
|
||||||
|
| Task | File | Purpose | Dependencies |
|
||||||
|
|------|------|---------|--------------|
|
||||||
|
| **Create ContentService** | `domain/content/services/content_generation_service.py` | Unified content generation | Existing Writer logic, CreditService |
|
||||||
|
|
||||||
|
**ContentService Methods**:
|
||||||
|
```python
|
||||||
|
# domain/content/services/content_generation_service.py
|
||||||
|
class ContentGenerationService:
|
||||||
|
def __init__(self):
|
||||||
|
self.credit_service = CreditService()
|
||||||
|
|
||||||
|
def generate_content(self, task, account):
|
||||||
|
"""Generate content for a task"""
|
||||||
|
# Check credits
|
||||||
|
self.credit_service.check_credits(account, 'content_generation', task.estimated_word_count)
|
||||||
|
|
||||||
|
# Generate content (existing logic from Writer ViewSet)
|
||||||
|
content = self._generate(task)
|
||||||
|
|
||||||
|
# Deduct credits
|
||||||
|
self.credit_service.deduct_credits(account, 'content_generation', content.word_count)
|
||||||
|
|
||||||
|
return content
|
||||||
|
|
||||||
|
def _generate(self, task):
|
||||||
|
"""Internal content generation logic"""
|
||||||
|
# Move logic from Writer ViewSet here
|
||||||
|
pass
|
||||||
|
```
|
||||||
|
|
||||||
|
#### PlanningService
|
||||||
|
|
||||||
|
| Task | File | Purpose | Dependencies |
|
||||||
|
|------|------|---------|--------------|
|
||||||
|
| **Create PlanningService** | `domain/planning/services/clustering_service.py` | Keyword clustering | Existing Planner logic, CreditService |
|
||||||
|
|
||||||
|
**PlanningService Methods**:
|
||||||
|
```python
|
||||||
|
# domain/planning/services/clustering_service.py
|
||||||
|
class ClusteringService:
|
||||||
|
def __init__(self):
|
||||||
|
self.credit_service = CreditService()
|
||||||
|
|
||||||
|
def cluster_keywords(self, keyword_ids, account):
|
||||||
|
"""Cluster keywords using AI"""
|
||||||
|
# Check credits
|
||||||
|
self.credit_service.check_credits(account, 'clustering', len(keyword_ids))
|
||||||
|
|
||||||
|
# Cluster keywords (existing logic from Planner ViewSet)
|
||||||
|
clusters = self._cluster(keyword_ids)
|
||||||
|
|
||||||
|
# Deduct credits
|
||||||
|
self.credit_service.deduct_credits(account, 'clustering', len(keyword_ids))
|
||||||
|
|
||||||
|
return clusters
|
||||||
|
```
|
||||||
|
|
||||||
|
#### IdeasService
|
||||||
|
|
||||||
|
| Task | File | Purpose | Dependencies |
|
||||||
|
|------|------|---------|--------------|
|
||||||
|
| **Create IdeasService** | `domain/planning/services/ideas_service.py` | Generate content ideas | Existing Planner logic, CreditService |
|
||||||
|
|
||||||
|
**IdeasService Methods**:
|
||||||
|
```python
|
||||||
|
# domain/planning/services/ideas_service.py
|
||||||
|
class IdeasService:
|
||||||
|
def __init__(self):
|
||||||
|
self.credit_service = CreditService()
|
||||||
|
|
||||||
|
def generate_ideas(self, cluster_ids, account):
|
||||||
|
"""Generate content ideas from clusters"""
|
||||||
|
# Check credits
|
||||||
|
self.credit_service.check_credits(account, 'idea_generation', len(cluster_ids))
|
||||||
|
|
||||||
|
# Generate ideas (existing logic from Planner ViewSet)
|
||||||
|
ideas = self._generate_ideas(cluster_ids)
|
||||||
|
|
||||||
|
# Deduct credits
|
||||||
|
self.credit_service.deduct_credits(account, 'idea_generation', len(ideas))
|
||||||
|
|
||||||
|
return ideas
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## REFACTOR VIEWSETS
|
||||||
|
|
||||||
|
### 1.4 Refactor ViewSets (Keep APIs Working)
|
||||||
|
|
||||||
|
**Purpose**: Make ViewSets thin wrappers that delegate to services.
|
||||||
|
|
||||||
|
#### Planner ViewSets Refactoring
|
||||||
|
|
||||||
|
| ViewSet | Current | New | Risk |
|
||||||
|
|---------|---------|-----|------|
|
||||||
|
| **KeywordViewSet** | Business logic in views | Delegate to services | LOW |
|
||||||
|
| **ClusterViewSet** | Business logic in views | Delegate to services | LOW |
|
||||||
|
| **ContentIdeasViewSet** | Business logic in views | Delegate to services | LOW |
|
||||||
|
|
||||||
|
**Before (Business Logic in ViewSet)**:
|
||||||
|
```python
|
||||||
|
# modules/planner/views.py
|
||||||
|
class ClusterViewSet(SiteSectorModelViewSet):
|
||||||
|
@action(detail=False, methods=['post'])
|
||||||
|
def auto_generate_ideas(self, request):
|
||||||
|
cluster_ids = request.data.get('cluster_ids')
|
||||||
|
# Business logic here (50+ lines)
|
||||||
|
clusters = Cluster.objects.filter(id__in=cluster_ids)
|
||||||
|
# AI call logic
|
||||||
|
# Idea creation logic
|
||||||
|
# etc.
|
||||||
|
return Response(...)
|
||||||
|
```
|
||||||
|
|
||||||
|
**After (Delegate to Service)**:
|
||||||
|
```python
|
||||||
|
# modules/planner/views.py
|
||||||
|
class ClusterViewSet(SiteSectorModelViewSet):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.ideas_service = IdeasService()
|
||||||
|
|
||||||
|
@action(detail=False, methods=['post'])
|
||||||
|
def auto_generate_ideas(self, request):
|
||||||
|
cluster_ids = request.data.get('cluster_ids')
|
||||||
|
account = request.account
|
||||||
|
|
||||||
|
# Delegate to service
|
||||||
|
ideas = self.ideas_service.generate_ideas(cluster_ids, account)
|
||||||
|
|
||||||
|
# Serialize and return
|
||||||
|
serializer = ContentIdeasSerializer(ideas, many=True)
|
||||||
|
return Response(serializer.data)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Writer ViewSets Refactoring
|
||||||
|
|
||||||
|
| ViewSet | Current | New | Risk |
|
||||||
|
|---------|---------|-----|------|
|
||||||
|
| **TasksViewSet** | Business logic in views | Delegate to services | LOW |
|
||||||
|
| **ImagesViewSet** | Business logic in views | Delegate to services | LOW |
|
||||||
|
|
||||||
|
**Before (Business Logic in ViewSet)**:
|
||||||
|
```python
|
||||||
|
# modules/writer/views.py
|
||||||
|
class TasksViewSet(SiteSectorModelViewSet):
|
||||||
|
@action(detail=False, methods=['post'])
|
||||||
|
def auto_generate_content(self, request):
|
||||||
|
task_ids = request.data.get('task_ids')
|
||||||
|
# Business logic here (100+ lines)
|
||||||
|
tasks = Task.objects.filter(id__in=task_ids)
|
||||||
|
# AI call logic
|
||||||
|
# Content creation logic
|
||||||
|
# etc.
|
||||||
|
return Response(...)
|
||||||
|
```
|
||||||
|
|
||||||
|
**After (Delegate to Service)**:
|
||||||
|
```python
|
||||||
|
# modules/writer/views.py
|
||||||
|
class TasksViewSet(SiteSectorModelViewSet):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.content_service = ContentGenerationService()
|
||||||
|
|
||||||
|
@action(detail=False, methods=['post'])
|
||||||
|
def auto_generate_content(self, request):
|
||||||
|
task_ids = request.data.get('task_ids')
|
||||||
|
account = request.account
|
||||||
|
|
||||||
|
# Delegate to service
|
||||||
|
contents = []
|
||||||
|
for task_id in task_ids:
|
||||||
|
task = Task.objects.get(id=task_id)
|
||||||
|
content = self.content_service.generate_content(task, account)
|
||||||
|
contents.append(content)
|
||||||
|
|
||||||
|
# Serialize and return
|
||||||
|
serializer = ContentSerializer(contents, many=True)
|
||||||
|
return Response(serializer.data)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Billing ViewSets
|
||||||
|
|
||||||
|
| ViewSet | Current | New | Risk |
|
||||||
|
|---------|---------|-----|------|
|
||||||
|
| **CreditTransactionViewSet** | Already uses CreditService | Keep as-is | NONE |
|
||||||
|
| **CreditUsageLogViewSet** | Already uses CreditService | Keep as-is | NONE |
|
||||||
|
|
||||||
|
**Note**: Billing ViewSets already use CreditService, so no changes needed.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TESTING & VALIDATION
|
||||||
|
|
||||||
|
### 1.5 Testing
|
||||||
|
|
||||||
|
**Test Cases**:
|
||||||
|
|
||||||
|
1. **Service Tests**:
|
||||||
|
- ✅ Services can be tested independently
|
||||||
|
- ✅ Services handle errors correctly
|
||||||
|
- ✅ Services check credits before operations
|
||||||
|
- ✅ Services deduct credits after operations
|
||||||
|
|
||||||
|
2. **API Compatibility Tests**:
|
||||||
|
- ✅ All existing API endpoints work identically
|
||||||
|
- ✅ Response formats unchanged
|
||||||
|
- ✅ No breaking changes for frontend
|
||||||
|
- ✅ All ViewSet actions work correctly
|
||||||
|
|
||||||
|
3. **Model Migration Tests**:
|
||||||
|
- ✅ Models work after migration
|
||||||
|
- ✅ All relationships preserved
|
||||||
|
- ✅ No data loss during migration
|
||||||
|
- ✅ All queries work correctly
|
||||||
|
|
||||||
|
**Test Files to Create**:
|
||||||
|
- `backend/tests/test_content_service.py`
|
||||||
|
- `backend/tests/test_planning_service.py`
|
||||||
|
- `backend/tests/test_ideas_service.py`
|
||||||
|
- `backend/tests/test_viewset_refactoring.py`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## IMPLEMENTATION CHECKLIST
|
||||||
|
|
||||||
|
### Backend Tasks
|
||||||
|
|
||||||
|
- [ ] Create `domain/` folder structure
|
||||||
|
- [ ] Create `domain/content/` folder
|
||||||
|
- [ ] Create `domain/planning/` folder
|
||||||
|
- [ ] Create `domain/billing/` folder (move existing)
|
||||||
|
- [ ] Move Content models to `domain/content/models.py`
|
||||||
|
- [ ] Move Planning models to `domain/planning/models.py`
|
||||||
|
- [ ] Move Billing models to `domain/billing/models.py`
|
||||||
|
- [ ] Create migrations for model moves
|
||||||
|
- [ ] Create `ContentGenerationService`
|
||||||
|
- [ ] Create `ClusteringService`
|
||||||
|
- [ ] Create `IdeasService`
|
||||||
|
- [ ] Refactor `KeywordViewSet` to use services
|
||||||
|
- [ ] Refactor `ClusterViewSet` to use services
|
||||||
|
- [ ] Refactor `ContentIdeasViewSet` to use services
|
||||||
|
- [ ] Refactor `TasksViewSet` to use services
|
||||||
|
- [ ] Refactor `ImagesViewSet` to use services
|
||||||
|
- [ ] Update all imports
|
||||||
|
- [ ] Test all API endpoints
|
||||||
|
|
||||||
|
### Testing Tasks
|
||||||
|
|
||||||
|
- [ ] Test all existing API endpoints work
|
||||||
|
- [ ] Test response formats unchanged
|
||||||
|
- [ ] Test services independently
|
||||||
|
- [ ] Test model migrations
|
||||||
|
- [ ] Test backward compatibility
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## RISK ASSESSMENT
|
||||||
|
|
||||||
|
| Risk | Level | Mitigation |
|
||||||
|
|------|-------|------------|
|
||||||
|
| **Breaking API changes** | MEDIUM | Extensive testing, keep response formats identical |
|
||||||
|
| **Import errors** | MEDIUM | Update all imports systematically |
|
||||||
|
| **Data loss during migration** | LOW | Backup before migration, test on staging |
|
||||||
|
| **Service logic errors** | MEDIUM | Unit tests for all services |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SUCCESS CRITERIA
|
||||||
|
|
||||||
|
- ✅ All existing API endpoints work identically
|
||||||
|
- ✅ Response formats unchanged
|
||||||
|
- ✅ No breaking changes for frontend
|
||||||
|
- ✅ Services are testable independently
|
||||||
|
- ✅ Business logic extracted from ViewSets
|
||||||
|
- ✅ ViewSets are thin wrappers
|
||||||
|
- ✅ All models moved to domain layer
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**END OF PHASE 1 DOCUMENT**
|
||||||
|
|
||||||
596
docs/planning/phases/PHASE-2-AUTOMATION-SYSTEM.md
Normal file
596
docs/planning/phases/PHASE-2-AUTOMATION-SYSTEM.md
Normal file
@@ -0,0 +1,596 @@
|
|||||||
|
# PHASE 2: AUTOMATION SYSTEM
|
||||||
|
**Detailed Implementation Plan**
|
||||||
|
|
||||||
|
**Goal**: Implement automation rules and scheduled tasks.
|
||||||
|
|
||||||
|
**Timeline**: 2-3 weeks
|
||||||
|
**Priority**: HIGH
|
||||||
|
**Dependencies**: Phase 1
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TABLE OF CONTENTS
|
||||||
|
|
||||||
|
1. [Overview](#overview)
|
||||||
|
2. [Automation Models](#automation-models)
|
||||||
|
3. [Automation Service](#automation-service)
|
||||||
|
4. [Celery Beat Tasks](#celery-beat-tasks)
|
||||||
|
5. [Automation API](#automation-api)
|
||||||
|
6. [Automation UI](#automation-ui)
|
||||||
|
7. [Testing & Validation](#testing--validation)
|
||||||
|
8. [Implementation Checklist](#implementation-checklist)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## OVERVIEW
|
||||||
|
|
||||||
|
### Objectives
|
||||||
|
- ✅ Create AutomationRule and ScheduledTask models
|
||||||
|
- ✅ Build AutomationService with rule execution engine
|
||||||
|
- ✅ Implement Celery Beat scheduled tasks
|
||||||
|
- ✅ Create automation API endpoints
|
||||||
|
- ✅ Build automation UI (Dashboard, Rules, History)
|
||||||
|
|
||||||
|
### Key Principles
|
||||||
|
- **Rule-Based**: Users create rules with triggers, conditions, actions
|
||||||
|
- **Scheduled Execution**: Rules can run on schedule or event triggers
|
||||||
|
- **Credit-Aware**: Automation respects credit limits
|
||||||
|
- **Audit Trail**: All automation executions logged
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AUTOMATION MODELS
|
||||||
|
|
||||||
|
### 2.1 Automation Models
|
||||||
|
|
||||||
|
**Purpose**: Store automation rules and scheduled task records.
|
||||||
|
|
||||||
|
#### AutomationRule Model
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **AutomationRule Model** | `domain/automation/models.py` | Phase 1 | Create model with trigger, conditions, actions, schedule |
|
||||||
|
|
||||||
|
**AutomationRule Model**:
|
||||||
|
```python
|
||||||
|
# domain/automation/models.py
|
||||||
|
class AutomationRule(SiteSectorBaseModel):
|
||||||
|
name = models.CharField(max_length=255)
|
||||||
|
description = models.TextField(blank=True)
|
||||||
|
|
||||||
|
# Trigger configuration
|
||||||
|
trigger = models.CharField(
|
||||||
|
max_length=50,
|
||||||
|
choices=[
|
||||||
|
('schedule', 'Scheduled'),
|
||||||
|
('keyword_added', 'Keyword Added'),
|
||||||
|
('cluster_created', 'Cluster Created'),
|
||||||
|
('idea_created', 'Idea Created'),
|
||||||
|
('content_generated', 'Content Generated'),
|
||||||
|
('task_created', 'Task Created'),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Condition evaluation
|
||||||
|
conditions = models.JSONField(default=dict)
|
||||||
|
# Example: {'field': 'status', 'operator': 'eq', 'value': 'draft'}
|
||||||
|
|
||||||
|
# Actions to execute
|
||||||
|
actions = models.JSONField(default=list)
|
||||||
|
# Example: [{'type': 'generate_ideas', 'params': {'cluster_ids': [1, 2]}}]
|
||||||
|
|
||||||
|
# Schedule configuration (for scheduled triggers)
|
||||||
|
schedule = models.JSONField(default=dict)
|
||||||
|
# Example: {'cron': '0 9 * * *', 'timezone': 'UTC'}
|
||||||
|
|
||||||
|
# Execution limits
|
||||||
|
is_active = models.BooleanField(default=True)
|
||||||
|
max_executions_per_day = models.IntegerField(default=10)
|
||||||
|
credit_limit_per_execution = models.IntegerField(default=100)
|
||||||
|
|
||||||
|
# Tracking
|
||||||
|
last_executed_at = models.DateTimeField(null=True, blank=True)
|
||||||
|
execution_count_today = models.IntegerField(default=0)
|
||||||
|
last_reset_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
ordering = ['-created_at']
|
||||||
|
```
|
||||||
|
|
||||||
|
#### ScheduledTask Model
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **ScheduledTask Model** | `domain/automation/models.py` | Phase 1 | Create model to track scheduled executions |
|
||||||
|
|
||||||
|
**ScheduledTask Model**:
|
||||||
|
```python
|
||||||
|
# domain/automation/models.py
|
||||||
|
class ScheduledTask(SiteSectorBaseModel):
|
||||||
|
automation_rule = models.ForeignKey(AutomationRule, on_delete=models.CASCADE)
|
||||||
|
scheduled_at = models.DateTimeField()
|
||||||
|
executed_at = models.DateTimeField(null=True, blank=True)
|
||||||
|
status = models.CharField(
|
||||||
|
max_length=20,
|
||||||
|
choices=[
|
||||||
|
('pending', 'Pending'),
|
||||||
|
('running', 'Running'),
|
||||||
|
('completed', 'Completed'),
|
||||||
|
('failed', 'Failed'),
|
||||||
|
('skipped', 'Skipped'),
|
||||||
|
],
|
||||||
|
default='pending'
|
||||||
|
)
|
||||||
|
result = models.JSONField(default=dict, blank=True)
|
||||||
|
error_message = models.TextField(blank=True)
|
||||||
|
credits_used = models.IntegerField(default=0)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
ordering = ['-scheduled_at']
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Automation Migrations
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Automation Migrations** | `domain/automation/migrations/` | Phase 1 | Create initial migrations |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AUTOMATION SERVICE
|
||||||
|
|
||||||
|
### 2.2 Automation Service
|
||||||
|
|
||||||
|
**Purpose**: Execute automation rules with condition evaluation and action execution.
|
||||||
|
|
||||||
|
#### AutomationService
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **AutomationService** | `domain/automation/services/automation_service.py` | Phase 1 services | Main service for rule execution |
|
||||||
|
|
||||||
|
**AutomationService Methods**:
|
||||||
|
```python
|
||||||
|
# domain/automation/services/automation_service.py
|
||||||
|
class AutomationService:
|
||||||
|
def __init__(self):
|
||||||
|
self.rule_engine = RuleEngine()
|
||||||
|
self.condition_evaluator = ConditionEvaluator()
|
||||||
|
self.action_executor = ActionExecutor()
|
||||||
|
self.credit_service = CreditService()
|
||||||
|
|
||||||
|
def execute_rule(self, rule, context=None):
|
||||||
|
"""Execute an automation rule"""
|
||||||
|
# Check if rule is active
|
||||||
|
if not rule.is_active:
|
||||||
|
return {'status': 'skipped', 'reason': 'Rule is inactive'}
|
||||||
|
|
||||||
|
# Check execution limits
|
||||||
|
if not self._check_execution_limits(rule):
|
||||||
|
return {'status': 'skipped', 'reason': 'Execution limit reached'}
|
||||||
|
|
||||||
|
# Check credits
|
||||||
|
if not self.credit_service.check_credits(rule.account, 'automation', rule.credit_limit_per_execution):
|
||||||
|
return {'status': 'skipped', 'reason': 'Insufficient credits'}
|
||||||
|
|
||||||
|
# Evaluate conditions
|
||||||
|
if not self.condition_evaluator.evaluate(rule.conditions, context):
|
||||||
|
return {'status': 'skipped', 'reason': 'Conditions not met'}
|
||||||
|
|
||||||
|
# Execute actions
|
||||||
|
results = self.action_executor.execute(rule.actions, context)
|
||||||
|
|
||||||
|
# Update rule tracking
|
||||||
|
rule.last_executed_at = timezone.now()
|
||||||
|
rule.execution_count_today += 1
|
||||||
|
rule.save()
|
||||||
|
|
||||||
|
return {'status': 'completed', 'results': results}
|
||||||
|
|
||||||
|
def _check_execution_limits(self, rule):
|
||||||
|
"""Check if rule can execute (daily limit)"""
|
||||||
|
# Reset counter if new day
|
||||||
|
if rule.last_reset_at.date() < timezone.now().date():
|
||||||
|
rule.execution_count_today = 0
|
||||||
|
rule.last_reset_at = timezone.now()
|
||||||
|
rule.save()
|
||||||
|
|
||||||
|
return rule.execution_count_today < rule.max_executions_per_day
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Rule Execution Engine
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Rule Execution Engine** | `domain/automation/services/rule_engine.py` | Phase 1 services | Orchestrates rule execution |
|
||||||
|
|
||||||
|
**RuleEngine Methods**:
|
||||||
|
```python
|
||||||
|
# domain/automation/services/rule_engine.py
|
||||||
|
class RuleEngine:
|
||||||
|
def execute_rule(self, rule, context):
|
||||||
|
"""Orchestrate rule execution"""
|
||||||
|
# Validate rule
|
||||||
|
# Check conditions
|
||||||
|
# Execute actions
|
||||||
|
# Handle errors
|
||||||
|
pass
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Condition Evaluator
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Condition Evaluator** | `domain/automation/services/condition_evaluator.py` | None | Evaluates rule conditions |
|
||||||
|
|
||||||
|
**ConditionEvaluator Methods**:
|
||||||
|
```python
|
||||||
|
# domain/automation/services/condition_evaluator.py
|
||||||
|
class ConditionEvaluator:
|
||||||
|
def evaluate(self, conditions, context):
|
||||||
|
"""Evaluate rule conditions"""
|
||||||
|
# Support operators: eq, ne, gt, gte, lt, lte, in, contains
|
||||||
|
# Example: {'field': 'status', 'operator': 'eq', 'value': 'draft'}
|
||||||
|
pass
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Action Executor
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Action Executor** | `domain/automation/services/action_executor.py` | Phase 1 services | Executes rule actions |
|
||||||
|
|
||||||
|
**ActionExecutor Methods**:
|
||||||
|
```python
|
||||||
|
# domain/automation/services/action_executor.py
|
||||||
|
class ActionExecutor:
|
||||||
|
def __init__(self):
|
||||||
|
self.clustering_service = ClusteringService()
|
||||||
|
self.ideas_service = IdeasService()
|
||||||
|
self.content_service = ContentGenerationService()
|
||||||
|
|
||||||
|
def execute(self, actions, context):
|
||||||
|
"""Execute rule actions"""
|
||||||
|
results = []
|
||||||
|
for action in actions:
|
||||||
|
action_type = action['type']
|
||||||
|
params = action.get('params', {})
|
||||||
|
|
||||||
|
if action_type == 'generate_ideas':
|
||||||
|
result = self.ideas_service.generate_ideas(params['cluster_ids'], context['account'])
|
||||||
|
elif action_type == 'generate_content':
|
||||||
|
result = self.content_service.generate_content(params['task_id'], context['account'])
|
||||||
|
# ... other action types
|
||||||
|
|
||||||
|
results.append(result)
|
||||||
|
|
||||||
|
return results
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CELERY BEAT TASKS
|
||||||
|
|
||||||
|
### 2.3 Celery Beat Tasks
|
||||||
|
|
||||||
|
**Purpose**: Schedule automation rules and monthly credit replenishment.
|
||||||
|
|
||||||
|
#### Scheduled Automation Task
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Scheduled Automation Task** | `infrastructure/messaging/automation_tasks.py` | AutomationService | Periodic task to execute scheduled rules |
|
||||||
|
|
||||||
|
**Scheduled Automation Task**:
|
||||||
|
```python
|
||||||
|
# infrastructure/messaging/automation_tasks.py
|
||||||
|
from celery import shared_task
|
||||||
|
from celery.schedules import crontab
|
||||||
|
|
||||||
|
@shared_task
|
||||||
|
def execute_scheduled_automation_rules():
|
||||||
|
"""Execute all scheduled automation rules"""
|
||||||
|
from domain.automation.services.automation_service import AutomationService
|
||||||
|
|
||||||
|
service = AutomationService()
|
||||||
|
rules = AutomationRule.objects.filter(
|
||||||
|
trigger='schedule',
|
||||||
|
is_active=True
|
||||||
|
)
|
||||||
|
|
||||||
|
for rule in rules:
|
||||||
|
# Check if rule should execute based on schedule
|
||||||
|
if should_execute_now(rule.schedule):
|
||||||
|
service.execute_rule(rule)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Monthly Credit Replenishment
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Monthly Credit Replenishment** | `infrastructure/messaging/automation_tasks.py` | CreditService | Add credits monthly to accounts |
|
||||||
|
|
||||||
|
**Monthly Credit Replenishment Task**:
|
||||||
|
```python
|
||||||
|
# infrastructure/messaging/automation_tasks.py
|
||||||
|
@shared_task
|
||||||
|
def replenish_monthly_credits():
|
||||||
|
"""Replenish monthly credits for all active accounts"""
|
||||||
|
from domain.billing.services.credit_service import CreditService
|
||||||
|
|
||||||
|
service = CreditService()
|
||||||
|
accounts = Account.objects.filter(status='active')
|
||||||
|
|
||||||
|
for account in accounts:
|
||||||
|
if account.plan:
|
||||||
|
monthly_credits = account.plan.monthly_credits
|
||||||
|
if monthly_credits > 0:
|
||||||
|
service.add_credits(account, monthly_credits, 'monthly_replenishment')
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Celery Beat Configuration
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Celery Beat Configuration** | `backend/igny8_core/celery.py` | None | Configure periodic tasks |
|
||||||
|
|
||||||
|
**Celery Beat Configuration**:
|
||||||
|
```python
|
||||||
|
# backend/igny8_core/celery.py
|
||||||
|
from celery.schedules import crontab
|
||||||
|
|
||||||
|
app.conf.beat_schedule = {
|
||||||
|
'execute-scheduled-automation-rules': {
|
||||||
|
'task': 'infrastructure.messaging.automation_tasks.execute_scheduled_automation_rules',
|
||||||
|
'schedule': crontab(minute='*/15'), # Every 15 minutes
|
||||||
|
},
|
||||||
|
'replenish-monthly-credits': {
|
||||||
|
'task': 'infrastructure.messaging.automation_tasks.replenish_monthly_credits',
|
||||||
|
'schedule': crontab(hour=0, minute=0, day_of_month=1), # First day of month
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AUTOMATION API
|
||||||
|
|
||||||
|
### 2.4 Automation API
|
||||||
|
|
||||||
|
**Purpose**: CRUD API for automation rules and scheduled tasks.
|
||||||
|
|
||||||
|
#### AutomationRule ViewSet
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **AutomationRule ViewSet** | `modules/automation/views.py` | AutomationService | CRUD operations for rules |
|
||||||
|
|
||||||
|
**AutomationRule ViewSet**:
|
||||||
|
```python
|
||||||
|
# modules/automation/views.py
|
||||||
|
class AutomationRuleViewSet(AccountModelViewSet):
|
||||||
|
queryset = AutomationRule.objects.all()
|
||||||
|
serializer_class = AutomationRuleSerializer
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.automation_service = AutomationService()
|
||||||
|
|
||||||
|
@action(detail=True, methods=['post'])
|
||||||
|
def execute(self, request, pk=None):
|
||||||
|
"""Manually execute a rule"""
|
||||||
|
rule = self.get_object()
|
||||||
|
result = self.automation_service.execute_rule(rule, {'account': request.account})
|
||||||
|
return Response(result)
|
||||||
|
|
||||||
|
@action(detail=True, methods=['post'])
|
||||||
|
def test(self, request, pk=None):
|
||||||
|
"""Test rule conditions without executing"""
|
||||||
|
rule = self.get_object()
|
||||||
|
# Test condition evaluation
|
||||||
|
pass
|
||||||
|
```
|
||||||
|
|
||||||
|
#### ScheduledTask ViewSet
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **ScheduledTask ViewSet** | `modules/automation/views.py` | AutomationService | View scheduled task history |
|
||||||
|
|
||||||
|
**ScheduledTask ViewSet**:
|
||||||
|
```python
|
||||||
|
# modules/automation/views.py
|
||||||
|
class ScheduledTaskViewSet(AccountModelViewSet):
|
||||||
|
queryset = ScheduledTask.objects.all()
|
||||||
|
serializer_class = ScheduledTaskSerializer
|
||||||
|
filterset_fields = ['status', 'automation_rule']
|
||||||
|
ordering = ['-scheduled_at']
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Automation URLs
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Automation URLs** | `modules/automation/urls.py` | None | Register automation routes |
|
||||||
|
|
||||||
|
**Automation URLs**:
|
||||||
|
```python
|
||||||
|
# modules/automation/urls.py
|
||||||
|
from rest_framework.routers import DefaultRouter
|
||||||
|
from .views import AutomationRuleViewSet, ScheduledTaskViewSet
|
||||||
|
|
||||||
|
router = DefaultRouter()
|
||||||
|
router.register(r'rules', AutomationRuleViewSet, basename='automation-rule')
|
||||||
|
router.register(r'scheduled-tasks', ScheduledTaskViewSet, basename='scheduled-task')
|
||||||
|
|
||||||
|
urlpatterns = router.urls
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AUTOMATION UI
|
||||||
|
|
||||||
|
### 2.5 Automation UI
|
||||||
|
|
||||||
|
**Purpose**: User interface for managing automation rules and viewing history.
|
||||||
|
|
||||||
|
#### Automation Dashboard
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Automation Dashboard** | `frontend/src/pages/Automation/Dashboard.tsx` | EXISTING (placeholder) | Overview of automation status |
|
||||||
|
|
||||||
|
**Dashboard Features**:
|
||||||
|
- Active rules count
|
||||||
|
- Recent executions
|
||||||
|
- Success/failure rates
|
||||||
|
- Credit usage from automation
|
||||||
|
- Quick actions (create rule, view history)
|
||||||
|
|
||||||
|
#### Rules Management
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Rules Management** | `frontend/src/pages/Automation/Rules.tsx` | NEW | CRUD interface for rules |
|
||||||
|
|
||||||
|
**Rules Management Features**:
|
||||||
|
- List all rules
|
||||||
|
- Create new rule (wizard)
|
||||||
|
- Edit existing rule
|
||||||
|
- Enable/disable rule
|
||||||
|
- Delete rule
|
||||||
|
- Test rule
|
||||||
|
- Manual execution
|
||||||
|
|
||||||
|
#### Schedules Page
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Schedules Page** | `frontend/src/pages/Schedules.tsx` | EXISTING (placeholder) | View scheduled task history |
|
||||||
|
|
||||||
|
**Schedules Page Features**:
|
||||||
|
- List scheduled tasks
|
||||||
|
- Filter by status, rule, date
|
||||||
|
- View execution results
|
||||||
|
- View error messages
|
||||||
|
- Retry failed tasks
|
||||||
|
|
||||||
|
#### Automation API Client
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Automation API Client** | `frontend/src/services/automation.api.ts` | NEW | API client for automation endpoints |
|
||||||
|
|
||||||
|
**Automation API Client**:
|
||||||
|
```typescript
|
||||||
|
// frontend/src/services/automation.api.ts
|
||||||
|
export const automationApi = {
|
||||||
|
getRules: () => fetchAPI('/automation/rules/'),
|
||||||
|
createRule: (data) => fetchAPI('/automation/rules/', { method: 'POST', body: data }),
|
||||||
|
updateRule: (id, data) => fetchAPI(`/automation/rules/${id}/`, { method: 'PUT', body: data }),
|
||||||
|
deleteRule: (id) => fetchAPI(`/automation/rules/${id}/`, { method: 'DELETE' }),
|
||||||
|
executeRule: (id) => fetchAPI(`/automation/rules/${id}/execute/`, { method: 'POST' }),
|
||||||
|
getScheduledTasks: (filters) => fetchAPI('/automation/scheduled-tasks/', { params: filters }),
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TESTING & VALIDATION
|
||||||
|
|
||||||
|
### 2.6 Testing
|
||||||
|
|
||||||
|
**Test Cases**:
|
||||||
|
|
||||||
|
1. **Automation Service Tests**:
|
||||||
|
- ✅ Rules execute correctly
|
||||||
|
- ✅ Conditions evaluate correctly
|
||||||
|
- ✅ Actions execute correctly
|
||||||
|
- ✅ Execution limits enforced
|
||||||
|
- ✅ Credit checks work
|
||||||
|
|
||||||
|
2. **Scheduled Tasks Tests**:
|
||||||
|
- ✅ Scheduled tasks run on time
|
||||||
|
- ✅ Credit replenishment works monthly
|
||||||
|
- ✅ Task status tracking works
|
||||||
|
|
||||||
|
3. **API Tests**:
|
||||||
|
- ✅ CRUD operations work
|
||||||
|
- ✅ Rule execution endpoint works
|
||||||
|
- ✅ Scheduled task history works
|
||||||
|
|
||||||
|
4. **UI Tests**:
|
||||||
|
- ✅ Dashboard displays correctly
|
||||||
|
- ✅ Rules management works
|
||||||
|
- ✅ Schedule history displays correctly
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## IMPLEMENTATION CHECKLIST
|
||||||
|
|
||||||
|
### Backend Tasks
|
||||||
|
|
||||||
|
- [ ] Create `domain/automation/models.py`
|
||||||
|
- [ ] Create AutomationRule model
|
||||||
|
- [ ] Create ScheduledTask model
|
||||||
|
- [ ] Create automation migrations
|
||||||
|
- [ ] Create `domain/automation/services/automation_service.py`
|
||||||
|
- [ ] Create `domain/automation/services/rule_engine.py`
|
||||||
|
- [ ] Create `domain/automation/services/condition_evaluator.py`
|
||||||
|
- [ ] Create `domain/automation/services/action_executor.py`
|
||||||
|
- [ ] Create `infrastructure/messaging/automation_tasks.py`
|
||||||
|
- [ ] Add scheduled automation task
|
||||||
|
- [ ] Add monthly credit replenishment task
|
||||||
|
- [ ] Configure Celery Beat
|
||||||
|
- [ ] Create `modules/automation/views.py`
|
||||||
|
- [ ] Create AutomationRule ViewSet
|
||||||
|
- [ ] Create ScheduledTask ViewSet
|
||||||
|
- [ ] Create `modules/automation/serializers.py`
|
||||||
|
- [ ] Create `modules/automation/urls.py`
|
||||||
|
- [ ] Register automation URLs in main urls.py
|
||||||
|
|
||||||
|
### Frontend Tasks
|
||||||
|
|
||||||
|
- [ ] Implement `frontend/src/pages/Automation/Dashboard.tsx`
|
||||||
|
- [ ] Create `frontend/src/pages/Automation/Rules.tsx`
|
||||||
|
- [ ] Implement `frontend/src/pages/Schedules.tsx`
|
||||||
|
- [ ] Create `frontend/src/services/automation.api.ts`
|
||||||
|
- [ ] Create rule creation wizard
|
||||||
|
- [ ] Create rule editor
|
||||||
|
- [ ] Create schedule history table
|
||||||
|
|
||||||
|
### Testing Tasks
|
||||||
|
|
||||||
|
- [ ] Test automation rule execution
|
||||||
|
- [ ] Test scheduled tasks
|
||||||
|
- [ ] Test credit replenishment
|
||||||
|
- [ ] Test API endpoints
|
||||||
|
- [ ] Test UI components
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## RISK ASSESSMENT
|
||||||
|
|
||||||
|
| Risk | Level | Mitigation |
|
||||||
|
|------|-------|------------|
|
||||||
|
| **Rule execution errors** | MEDIUM | Comprehensive error handling, logging |
|
||||||
|
| **Credit limit violations** | MEDIUM | Credit checks before execution |
|
||||||
|
| **Scheduled task failures** | MEDIUM | Retry mechanism, error logging |
|
||||||
|
| **Performance issues** | LOW | Background processing, rate limiting |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SUCCESS CRITERIA
|
||||||
|
|
||||||
|
- ✅ Automation rules execute correctly
|
||||||
|
- ✅ Scheduled tasks run on time
|
||||||
|
- ✅ Credit replenishment works monthly
|
||||||
|
- ✅ UI shows automation status
|
||||||
|
- ✅ Rules can be created, edited, deleted
|
||||||
|
- ✅ Execution history is tracked
|
||||||
|
- ✅ All automation respects credit limits
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**END OF PHASE 2 DOCUMENT**
|
||||||
|
|
||||||
642
docs/planning/phases/PHASE-3-SITE-BUILDER.md
Normal file
642
docs/planning/phases/PHASE-3-SITE-BUILDER.md
Normal file
@@ -0,0 +1,642 @@
|
|||||||
|
# PHASE 3: SITE BUILDER
|
||||||
|
**Detailed Implementation Plan**
|
||||||
|
|
||||||
|
**Goal**: Build Site Builder for creating sites via wizard.
|
||||||
|
|
||||||
|
**Timeline**: 3-4 weeks
|
||||||
|
**Priority**: HIGH
|
||||||
|
**Dependencies**: Phase 1, Phase 2
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TABLE OF CONTENTS
|
||||||
|
|
||||||
|
1. [Overview](#overview)
|
||||||
|
2. [Sites Folder Access & File Management](#sites-folder-access--file-management)
|
||||||
|
3. [Site Builder Models](#site-builder-models)
|
||||||
|
4. [Site Structure Generation](#site-structure-generation)
|
||||||
|
5. [Site Builder API](#site-builder-api)
|
||||||
|
6. [Site Builder Frontend](#site-builder-frontend)
|
||||||
|
7. [Global Component Library](#global-component-library)
|
||||||
|
8. [Page Generation](#page-generation)
|
||||||
|
9. [Testing & Validation](#testing--validation)
|
||||||
|
10. [Implementation Checklist](#implementation-checklist)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## OVERVIEW
|
||||||
|
|
||||||
|
### Objectives
|
||||||
|
- ✅ Create Site Builder wizard for site creation
|
||||||
|
- ✅ Generate site structure using AI
|
||||||
|
- ✅ Build preview canvas for site editing
|
||||||
|
- ✅ Create shared component library
|
||||||
|
- ✅ Support multiple layouts and templates
|
||||||
|
- ✅ Enable file management for site assets
|
||||||
|
|
||||||
|
### Key Principles
|
||||||
|
- **Wizard-Based**: Step-by-step site creation process
|
||||||
|
- **AI-Powered**: AI generates site structure from business brief
|
||||||
|
- **Component Reuse**: Shared components across Site Builder, Sites Renderer, Main App
|
||||||
|
- **User-Friendly**: "Website Builder" or "Site Creator" in UI
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SITES FOLDER ACCESS & FILE MANAGEMENT
|
||||||
|
|
||||||
|
### 3.0 Sites Folder Access & File Management
|
||||||
|
|
||||||
|
**Purpose**: Manage site files and assets with proper access control.
|
||||||
|
|
||||||
|
#### Sites Folder Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
/data/app/sites-data/
|
||||||
|
└── clients/
|
||||||
|
└── {site_id}/
|
||||||
|
└── v{version}/
|
||||||
|
├── site.json # Site definition
|
||||||
|
├── pages/ # Page definitions
|
||||||
|
│ ├── home.json
|
||||||
|
│ ├── about.json
|
||||||
|
│ └── ...
|
||||||
|
└── assets/ # User-managed files
|
||||||
|
├── images/
|
||||||
|
├── documents/
|
||||||
|
└── media/
|
||||||
|
```
|
||||||
|
|
||||||
|
#### User Access Rules
|
||||||
|
|
||||||
|
- **Owner/Admin**: Full access to all account sites
|
||||||
|
- **Editor**: Access to granted sites (via SiteUserAccess)
|
||||||
|
- **Viewer**: Read-only access to granted sites
|
||||||
|
- **File operations**: Scoped to user's accessible sites only
|
||||||
|
|
||||||
|
#### Site File Management Service
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Site File Management Service** | `domain/site_building/services/file_management_service.py` | Phase 1 | File upload, delete, organize |
|
||||||
|
|
||||||
|
**FileManagementService**:
|
||||||
|
```python
|
||||||
|
# domain/site_building/services/file_management_service.py
|
||||||
|
class SiteBuilderFileService:
|
||||||
|
def get_user_accessible_sites(self, user):
|
||||||
|
"""Get sites user can access for file management"""
|
||||||
|
if user.is_owner_or_admin():
|
||||||
|
return Site.objects.filter(account=user.account)
|
||||||
|
return user.get_accessible_sites()
|
||||||
|
|
||||||
|
def get_site_files_path(self, site_id, version=1):
|
||||||
|
"""Get site's files directory"""
|
||||||
|
return f"/data/app/sites-data/clients/{site_id}/v{version}/assets/"
|
||||||
|
|
||||||
|
def check_file_access(self, user, site_id):
|
||||||
|
"""Check if user can access site's files"""
|
||||||
|
accessible_sites = self.get_user_accessible_sites(user)
|
||||||
|
return any(site.id == site_id for site in accessible_sites)
|
||||||
|
|
||||||
|
def upload_file(self, user, site_id, file, folder='images'):
|
||||||
|
"""Upload file to site's assets folder"""
|
||||||
|
if not self.check_file_access(user, site_id):
|
||||||
|
raise PermissionDenied("No access to this site")
|
||||||
|
|
||||||
|
# Check storage quota
|
||||||
|
if not self.check_storage_quota(site_id, file.size):
|
||||||
|
raise ValidationError("Storage quota exceeded")
|
||||||
|
|
||||||
|
# Upload file
|
||||||
|
file_path = self._save_file(site_id, file, folder)
|
||||||
|
return file_path
|
||||||
|
```
|
||||||
|
|
||||||
|
#### File Upload API
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **File Upload API** | `modules/site_builder/views.py` | File Management Service | Handle file uploads |
|
||||||
|
|
||||||
|
#### File Browser UI
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **File Browser UI** | `site-builder/src/components/files/FileBrowser.tsx` | NEW | File browser component |
|
||||||
|
|
||||||
|
#### Storage Quota Check
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Storage Quota Check** | `infrastructure/storage/file_storage.py` | Phase 1 | Check site storage quota |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SITE BUILDER MODELS
|
||||||
|
|
||||||
|
### 3.1 Site Builder Models
|
||||||
|
|
||||||
|
**Purpose**: Store site blueprints and page definitions.
|
||||||
|
|
||||||
|
#### SiteBlueprint Model
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **SiteBlueprint Model** | `domain/site_building/models.py` | Phase 1 | Store site structure |
|
||||||
|
|
||||||
|
**SiteBlueprint Model**:
|
||||||
|
```python
|
||||||
|
# domain/site_building/models.py
|
||||||
|
class SiteBlueprint(SiteSectorBaseModel):
|
||||||
|
name = models.CharField(max_length=255)
|
||||||
|
description = models.TextField(blank=True)
|
||||||
|
|
||||||
|
# Site configuration
|
||||||
|
config_json = models.JSONField(default=dict)
|
||||||
|
# Example: {'business_type': 'ecommerce', 'style': 'modern'}
|
||||||
|
|
||||||
|
# Generated structure
|
||||||
|
structure_json = models.JSONField(default=dict)
|
||||||
|
# Example: {'pages': [...], 'layout': 'default', 'theme': {...}}
|
||||||
|
|
||||||
|
# Status tracking
|
||||||
|
status = models.CharField(
|
||||||
|
max_length=20,
|
||||||
|
choices=[
|
||||||
|
('draft', 'Draft'),
|
||||||
|
('generating', 'Generating'),
|
||||||
|
('ready', 'Ready'),
|
||||||
|
('deployed', 'Deployed'),
|
||||||
|
],
|
||||||
|
default='draft'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Hosting configuration
|
||||||
|
hosting_type = models.CharField(
|
||||||
|
max_length=50,
|
||||||
|
choices=[
|
||||||
|
('igny8_sites', 'IGNY8 Sites'),
|
||||||
|
('wordpress', 'WordPress'),
|
||||||
|
('shopify', 'Shopify'),
|
||||||
|
('multi', 'Multiple Destinations'),
|
||||||
|
],
|
||||||
|
default='igny8_sites'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Version tracking
|
||||||
|
version = models.IntegerField(default=1)
|
||||||
|
deployed_version = models.IntegerField(null=True, blank=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
ordering = ['-created_at']
|
||||||
|
```
|
||||||
|
|
||||||
|
#### PageBlueprint Model
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **PageBlueprint Model** | `domain/site_building/models.py` | Phase 1 | Store page definitions |
|
||||||
|
|
||||||
|
**PageBlueprint Model**:
|
||||||
|
```python
|
||||||
|
# domain/site_building/models.py
|
||||||
|
class PageBlueprint(SiteSectorBaseModel):
|
||||||
|
site_blueprint = models.ForeignKey(SiteBlueprint, on_delete=models.CASCADE, related_name='pages')
|
||||||
|
slug = models.SlugField(max_length=255)
|
||||||
|
title = models.CharField(max_length=255)
|
||||||
|
|
||||||
|
# Page type
|
||||||
|
type = models.CharField(
|
||||||
|
max_length=50,
|
||||||
|
choices=[
|
||||||
|
('home', 'Home'),
|
||||||
|
('about', 'About'),
|
||||||
|
('services', 'Services'),
|
||||||
|
('products', 'Products'),
|
||||||
|
('blog', 'Blog'),
|
||||||
|
('contact', 'Contact'),
|
||||||
|
('custom', 'Custom'),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Page content (blocks)
|
||||||
|
blocks_json = models.JSONField(default=list)
|
||||||
|
# Example: [{'type': 'hero', 'data': {...}}, {'type': 'features', 'data': {...}}]
|
||||||
|
|
||||||
|
# Status
|
||||||
|
status = models.CharField(
|
||||||
|
max_length=20,
|
||||||
|
choices=[
|
||||||
|
('draft', 'Draft'),
|
||||||
|
('generating', 'Generating'),
|
||||||
|
('ready', 'Ready'),
|
||||||
|
],
|
||||||
|
default='draft'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Order
|
||||||
|
order = models.IntegerField(default=0)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
ordering = ['order', 'created_at']
|
||||||
|
unique_together = [['site_blueprint', 'slug']]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Site Builder Migrations
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Site Builder Migrations** | `domain/site_building/migrations/` | Phase 1 | Create initial migrations |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SITE STRUCTURE GENERATION
|
||||||
|
|
||||||
|
### 3.2 Site Structure Generation
|
||||||
|
|
||||||
|
**Purpose**: Use AI to generate site structure from business brief.
|
||||||
|
|
||||||
|
#### Structure Generation AI Function
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Structure Generation AI Function** | `infrastructure/ai/functions/generate_site_structure.py` | Existing AI framework | AI function for structure generation |
|
||||||
|
|
||||||
|
**GenerateSiteStructureFunction**:
|
||||||
|
```python
|
||||||
|
# infrastructure/ai/functions/generate_site_structure.py
|
||||||
|
class GenerateSiteStructureFunction(BaseAIFunction):
|
||||||
|
def get_operation_type(self):
|
||||||
|
return 'site_structure_generation'
|
||||||
|
|
||||||
|
def get_estimated_cost(self, payload):
|
||||||
|
return CREDIT_COSTS['site_structure_generation']
|
||||||
|
|
||||||
|
def execute(self, payload, account):
|
||||||
|
"""Generate site structure from business brief"""
|
||||||
|
business_brief = payload['business_brief']
|
||||||
|
objectives = payload.get('objectives', [])
|
||||||
|
style_preferences = payload.get('style', {})
|
||||||
|
|
||||||
|
# Build prompt
|
||||||
|
prompt = self._build_prompt(business_brief, objectives, style_preferences)
|
||||||
|
|
||||||
|
# Call AI
|
||||||
|
response = self.ai_core.generate(prompt, model='gpt-4')
|
||||||
|
|
||||||
|
# Parse response to structure JSON
|
||||||
|
structure = self._parse_structure(response)
|
||||||
|
|
||||||
|
return structure
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Structure Generation Service
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Structure Generation Service** | `domain/site_building/services/structure_generation_service.py` | Phase 1, AI framework | Service to generate site structure |
|
||||||
|
|
||||||
|
**StructureGenerationService**:
|
||||||
|
```python
|
||||||
|
# domain/site_building/services/structure_generation_service.py
|
||||||
|
class StructureGenerationService:
|
||||||
|
def __init__(self):
|
||||||
|
self.ai_function = GenerateSiteStructureFunction()
|
||||||
|
self.credit_service = CreditService()
|
||||||
|
|
||||||
|
def generate_structure(self, site_blueprint, business_brief, objectives, style):
|
||||||
|
"""Generate site structure for blueprint"""
|
||||||
|
account = site_blueprint.account
|
||||||
|
|
||||||
|
# Check credits
|
||||||
|
self.credit_service.check_credits(account, 'site_structure_generation')
|
||||||
|
|
||||||
|
# Update status
|
||||||
|
site_blueprint.status = 'generating'
|
||||||
|
site_blueprint.save()
|
||||||
|
|
||||||
|
# Generate structure
|
||||||
|
payload = {
|
||||||
|
'business_brief': business_brief,
|
||||||
|
'objectives': objectives,
|
||||||
|
'style': style,
|
||||||
|
}
|
||||||
|
structure = self.ai_function.execute(payload, account)
|
||||||
|
|
||||||
|
# Deduct credits
|
||||||
|
self.credit_service.deduct_credits(account, 'site_structure_generation')
|
||||||
|
|
||||||
|
# Update blueprint
|
||||||
|
site_blueprint.structure_json = structure
|
||||||
|
site_blueprint.status = 'ready'
|
||||||
|
site_blueprint.save()
|
||||||
|
|
||||||
|
# Create page blueprints
|
||||||
|
self._create_page_blueprints(site_blueprint, structure)
|
||||||
|
|
||||||
|
return site_blueprint
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Site Structure Prompts
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Site Structure Prompts** | `infrastructure/ai/prompts.py` | Existing prompt system | Add site structure prompts |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SITE BUILDER API
|
||||||
|
|
||||||
|
### 3.3 Site Builder API
|
||||||
|
|
||||||
|
**Purpose**: API endpoints for site builder operations.
|
||||||
|
|
||||||
|
#### Site Builder ViewSet
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Site Builder ViewSet** | `modules/site_builder/views.py` | Structure Generation Service | CRUD operations for site blueprints |
|
||||||
|
|
||||||
|
**SiteBuilderViewSet**:
|
||||||
|
```python
|
||||||
|
# modules/site_builder/views.py
|
||||||
|
class SiteBuilderViewSet(AccountModelViewSet):
|
||||||
|
queryset = SiteBlueprint.objects.all()
|
||||||
|
serializer_class = SiteBlueprintSerializer
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.structure_service = StructureGenerationService()
|
||||||
|
|
||||||
|
@action(detail=True, methods=['post'])
|
||||||
|
def generate_structure(self, request, pk=None):
|
||||||
|
"""Generate site structure"""
|
||||||
|
blueprint = self.get_object()
|
||||||
|
business_brief = request.data.get('business_brief')
|
||||||
|
objectives = request.data.get('objectives', [])
|
||||||
|
style = request.data.get('style', {})
|
||||||
|
|
||||||
|
blueprint = self.structure_service.generate_structure(
|
||||||
|
blueprint, business_brief, objectives, style
|
||||||
|
)
|
||||||
|
|
||||||
|
serializer = self.get_serializer(blueprint)
|
||||||
|
return Response(serializer.data)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Site Builder URLs
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Site Builder URLs** | `modules/site_builder/urls.py` | None | Register site builder routes |
|
||||||
|
|
||||||
|
#### Site Builder Serializers
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Site Builder Serializers** | `modules/site_builder/serializers.py` | None | Serializers for SiteBlueprint and PageBlueprint |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SITE BUILDER FRONTEND
|
||||||
|
|
||||||
|
### 3.4 Site Builder Frontend (New Container)
|
||||||
|
|
||||||
|
**User-Friendly Name**: "Website Builder" or "Site Creator"
|
||||||
|
|
||||||
|
#### Create Site Builder Container
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Create Site Builder Container** | `docker-compose.app.yml` | None | Add new container for site builder |
|
||||||
|
|
||||||
|
**Docker Compose Configuration**:
|
||||||
|
```yaml
|
||||||
|
# docker-compose.app.yml
|
||||||
|
igny8_site_builder:
|
||||||
|
build: ./site-builder
|
||||||
|
ports:
|
||||||
|
- "8022:5175"
|
||||||
|
volumes:
|
||||||
|
- /data/app/igny8/site-builder:/app
|
||||||
|
environment:
|
||||||
|
- VITE_API_URL=http://igny8_backend:8010
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Wizard Steps
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Wizard Steps** | `site-builder/src/pages/wizard/` | NEW | Step-by-step wizard components |
|
||||||
|
|
||||||
|
**Wizard Steps**:
|
||||||
|
- Step 1: Type Selection (Business type, industry)
|
||||||
|
- Step 2: Business Brief (Description, goals)
|
||||||
|
- Step 3: Objectives (What pages needed)
|
||||||
|
- Step 4: Style Preferences (Colors, fonts, layout)
|
||||||
|
|
||||||
|
#### Preview Canvas
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Preview Canvas** | `site-builder/src/pages/preview/` | NEW | Live preview of site |
|
||||||
|
|
||||||
|
#### Site Builder State
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Site Builder State** | `site-builder/src/state/builderStore.ts` | NEW | Zustand store for builder state |
|
||||||
|
|
||||||
|
#### Site Builder API Client
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Site Builder API Client** | `site-builder/src/api/builder.api.ts` | NEW | API client for site builder |
|
||||||
|
|
||||||
|
#### Layout Selection
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Layout Selection** | `site-builder/src/components/layouts/` | NEW | Layout selector component |
|
||||||
|
|
||||||
|
#### Template Library
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Template Library** | `site-builder/src/components/templates/` | NEW | Template selector component |
|
||||||
|
|
||||||
|
#### Block Components
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Block Components** | `site-builder/src/components/blocks/` | NEW | Block components (imports from shared) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## GLOBAL COMPONENT LIBRARY
|
||||||
|
|
||||||
|
### 3.7 Global Component Library
|
||||||
|
|
||||||
|
**Purpose**: Shared components across Site Builder, Sites Renderer, and Main App.
|
||||||
|
|
||||||
|
#### Create Shared Component Library
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Create Shared Component Library** | `frontend/src/components/shared/` | None | Create shared component structure |
|
||||||
|
|
||||||
|
**Component Library Structure**:
|
||||||
|
```
|
||||||
|
frontend/src/components/shared/
|
||||||
|
├── blocks/
|
||||||
|
│ ├── Hero.tsx
|
||||||
|
│ ├── Features.tsx
|
||||||
|
│ ├── Services.tsx
|
||||||
|
│ ├── Products.tsx
|
||||||
|
│ ├── Testimonials.tsx
|
||||||
|
│ ├── ContactForm.tsx
|
||||||
|
│ └── ...
|
||||||
|
├── layouts/
|
||||||
|
│ ├── DefaultLayout.tsx
|
||||||
|
│ ├── MinimalLayout.tsx
|
||||||
|
│ ├── MagazineLayout.tsx
|
||||||
|
│ ├── EcommerceLayout.tsx
|
||||||
|
│ ├── PortfolioLayout.tsx
|
||||||
|
│ ├── BlogLayout.tsx
|
||||||
|
│ └── CorporateLayout.tsx
|
||||||
|
└── templates/
|
||||||
|
├── BlogTemplate.tsx
|
||||||
|
├── BusinessTemplate.tsx
|
||||||
|
├── PortfolioTemplate.tsx
|
||||||
|
└── ...
|
||||||
|
```
|
||||||
|
|
||||||
|
**Usage**: Site Builder, Sites Renderer, and Main App all use same components (no duplicates)
|
||||||
|
|
||||||
|
#### Component Documentation
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Component Documentation** | `frontend/src/components/shared/README.md` | None | Document all shared components |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PAGE GENERATION
|
||||||
|
|
||||||
|
### 3.5 Page Generation (Reuse Content Service)
|
||||||
|
|
||||||
|
**Purpose**: Generate page content using existing ContentService.
|
||||||
|
|
||||||
|
#### Extend ContentService
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Extend ContentService** | `domain/content/services/content_generation_service.py` | Phase 1 | Add site page generation method |
|
||||||
|
|
||||||
|
#### Add Site Page Type
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Add Site Page Type** | `domain/content/models.py` | Phase 1 | Add site page content type |
|
||||||
|
|
||||||
|
#### Page Generation Prompts
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Page Generation Prompts** | `infrastructure/ai/prompts.py` | Existing prompt system | Add page generation prompts |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TESTING & VALIDATION
|
||||||
|
|
||||||
|
### 3.6 Testing
|
||||||
|
|
||||||
|
**Test Cases**:
|
||||||
|
|
||||||
|
1. **Site Builder Tests**:
|
||||||
|
- ✅ Site Builder wizard works end-to-end
|
||||||
|
- ✅ Structure generation creates valid blueprints
|
||||||
|
- ✅ Preview renders correctly
|
||||||
|
- ✅ Page generation reuses existing content service
|
||||||
|
|
||||||
|
2. **File Management Tests**:
|
||||||
|
- ✅ File upload works
|
||||||
|
- ✅ File access control works
|
||||||
|
- ✅ Storage quota enforced
|
||||||
|
|
||||||
|
3. **Component Library Tests**:
|
||||||
|
- ✅ Components render correctly
|
||||||
|
- ✅ Components work in Site Builder
|
||||||
|
- ✅ Components work in Sites Renderer
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## IMPLEMENTATION CHECKLIST
|
||||||
|
|
||||||
|
### Backend Tasks
|
||||||
|
|
||||||
|
- [ ] Create `domain/site_building/models.py`
|
||||||
|
- [ ] Create SiteBlueprint model
|
||||||
|
- [ ] Create PageBlueprint model
|
||||||
|
- [ ] Create site builder migrations
|
||||||
|
- [ ] Create `domain/site_building/services/file_management_service.py`
|
||||||
|
- [ ] Create `domain/site_building/services/structure_generation_service.py`
|
||||||
|
- [ ] Create `infrastructure/ai/functions/generate_site_structure.py`
|
||||||
|
- [ ] Add site structure prompts
|
||||||
|
- [ ] Create `modules/site_builder/views.py`
|
||||||
|
- [ ] Create SiteBuilder ViewSet
|
||||||
|
- [ ] Create `modules/site_builder/serializers.py`
|
||||||
|
- [ ] Create `modules/site_builder/urls.py`
|
||||||
|
- [ ] Extend ContentService for page generation
|
||||||
|
|
||||||
|
### Frontend Tasks
|
||||||
|
|
||||||
|
- [ ] Create `site-builder/` folder structure
|
||||||
|
- [ ] Create Site Builder container in docker-compose
|
||||||
|
- [ ] Create wizard steps
|
||||||
|
- [ ] Create preview canvas
|
||||||
|
- [ ] Create builder state store
|
||||||
|
- [ ] Create API client
|
||||||
|
- [ ] Create layout selector
|
||||||
|
- [ ] Create template library
|
||||||
|
- [ ] Create `frontend/src/components/shared/` structure
|
||||||
|
- [ ] Create block components
|
||||||
|
- [ ] Create layout components
|
||||||
|
- [ ] Create template components
|
||||||
|
- [ ] Create component documentation
|
||||||
|
|
||||||
|
### Testing Tasks
|
||||||
|
|
||||||
|
- [ ] Test site builder wizard
|
||||||
|
- [ ] Test structure generation
|
||||||
|
- [ ] Test file management
|
||||||
|
- [ ] Test component library
|
||||||
|
- [ ] Test page generation
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## RISK ASSESSMENT
|
||||||
|
|
||||||
|
| Risk | Level | Mitigation |
|
||||||
|
|------|-------|------------|
|
||||||
|
| **AI structure generation quality** | MEDIUM | Prompt engineering, validation |
|
||||||
|
| **Component compatibility** | MEDIUM | Shared component library, testing |
|
||||||
|
| **File management security** | MEDIUM | Access control, validation |
|
||||||
|
| **Performance with large sites** | LOW | Optimization, caching |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SUCCESS CRITERIA
|
||||||
|
|
||||||
|
- ✅ Site Builder wizard works end-to-end
|
||||||
|
- ✅ Structure generation creates valid blueprints
|
||||||
|
- ✅ Preview renders correctly
|
||||||
|
- ✅ Page generation reuses existing content service
|
||||||
|
- ✅ File management works correctly
|
||||||
|
- ✅ Shared components work across all apps
|
||||||
|
- ✅ Multiple layouts supported
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**END OF PHASE 3 DOCUMENT**
|
||||||
|
|
||||||
391
docs/planning/phases/PHASE-4-LINKER-OPTIMIZER.md
Normal file
391
docs/planning/phases/PHASE-4-LINKER-OPTIMIZER.md
Normal file
@@ -0,0 +1,391 @@
|
|||||||
|
# PHASE 4: LINKER & OPTIMIZER
|
||||||
|
**Detailed Implementation Plan**
|
||||||
|
|
||||||
|
**Goal**: Add linking and optimization as post-processing stages with multiple entry points.
|
||||||
|
|
||||||
|
**Timeline**: 4-5 weeks
|
||||||
|
**Priority**: MEDIUM
|
||||||
|
**Dependencies**: Phase 1
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TABLE OF CONTENTS
|
||||||
|
|
||||||
|
1. [Overview](#overview)
|
||||||
|
2. [Content Workflow & Entry Points](#content-workflow--entry-points)
|
||||||
|
3. [Content Model Extensions](#content-model-extensions)
|
||||||
|
4. [Linker Implementation](#linker-implementation)
|
||||||
|
5. [Optimizer Implementation](#optimizer-implementation)
|
||||||
|
6. [Content Pipeline Service](#content-pipeline-service)
|
||||||
|
7. [Linker & Optimizer APIs](#linker--optimizer-apis)
|
||||||
|
8. [Linker & Optimizer UI](#linker--optimizer-ui)
|
||||||
|
9. [Testing & Validation](#testing--validation)
|
||||||
|
10. [Implementation Checklist](#implementation-checklist)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## OVERVIEW
|
||||||
|
|
||||||
|
### Objectives
|
||||||
|
- ✅ Add internal linking to content
|
||||||
|
- ✅ Add content optimization
|
||||||
|
- ✅ Support multiple entry points (Writer, WordPress Sync, 3rd Party, Manual)
|
||||||
|
- ✅ Create content pipeline service
|
||||||
|
- ✅ Build UI for linker and optimizer
|
||||||
|
|
||||||
|
### Key Principles
|
||||||
|
- **Multiple Entry Points**: Optimizer works from any content source
|
||||||
|
- **Unified Content Model**: All content stored in same model with source tracking
|
||||||
|
- **Pipeline Orchestration**: Linker → Optimizer → Publish workflow
|
||||||
|
- **Source Agnostic**: Optimizer works on any content regardless of source
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CONTENT WORKFLOW & ENTRY POINTS
|
||||||
|
|
||||||
|
### 4.0 Content Workflow & Entry Points
|
||||||
|
|
||||||
|
**Content Sources**:
|
||||||
|
1. **IGNY8 Generated** - Content created via Writer module
|
||||||
|
2. **WordPress Synced** - Content synced from WordPress via plugin
|
||||||
|
3. **3rd Party Synced** - Content synced from external sources (Shopify, custom APIs)
|
||||||
|
|
||||||
|
**Workflow Entry Points**:
|
||||||
|
```
|
||||||
|
Entry Point 1: Writer → Linker → Optimizer → Publish
|
||||||
|
Entry Point 2: WordPress Sync → Optimizer → Publish
|
||||||
|
Entry Point 3: 3rd Party Sync → Optimizer → Publish
|
||||||
|
Entry Point 4: Manual Selection → Linker/Optimizer
|
||||||
|
```
|
||||||
|
|
||||||
|
**Content Storage Strategy**:
|
||||||
|
- All content stored in unified `Content` model
|
||||||
|
- `source` field: `'igny8'`, `'wordpress'`, `'shopify'`, `'custom'`
|
||||||
|
- `sync_status` field: `'native'`, `'imported'`, `'synced'`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CONTENT MODEL EXTENSIONS
|
||||||
|
|
||||||
|
### 4.1 Content Model Extensions
|
||||||
|
|
||||||
|
**Purpose**: Add fields to track content source and sync status.
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Add source field** | `domain/content/models.py` | Phase 1 | Track content source |
|
||||||
|
| **Add sync_status field** | `domain/content/models.py` | Phase 1 | Track sync status |
|
||||||
|
| **Add external_id field** | `domain/content/models.py` | Phase 1 | Store external platform ID |
|
||||||
|
| **Add sync_metadata field** | `domain/content/models.py` | Phase 1 | Store platform-specific metadata |
|
||||||
|
|
||||||
|
**Content Model Extensions**:
|
||||||
|
```python
|
||||||
|
# domain/content/models.py
|
||||||
|
class Content(SiteSectorBaseModel):
|
||||||
|
# Existing fields...
|
||||||
|
|
||||||
|
# NEW: Source tracking
|
||||||
|
source = models.CharField(
|
||||||
|
max_length=50,
|
||||||
|
choices=[
|
||||||
|
('igny8', 'IGNY8 Generated'),
|
||||||
|
('wordpress', 'WordPress Synced'),
|
||||||
|
('shopify', 'Shopify Synced'),
|
||||||
|
('custom', 'Custom API Synced'),
|
||||||
|
],
|
||||||
|
default='igny8'
|
||||||
|
)
|
||||||
|
|
||||||
|
# NEW: Sync status
|
||||||
|
sync_status = models.CharField(
|
||||||
|
max_length=50,
|
||||||
|
choices=[
|
||||||
|
('native', 'Native IGNY8 Content'),
|
||||||
|
('imported', 'Imported from External'),
|
||||||
|
('synced', 'Synced from External'),
|
||||||
|
],
|
||||||
|
default='native'
|
||||||
|
)
|
||||||
|
|
||||||
|
# NEW: External reference
|
||||||
|
external_id = models.CharField(max_length=255, blank=True, null=True)
|
||||||
|
external_url = models.URLField(blank=True, null=True)
|
||||||
|
sync_metadata = models.JSONField(default=dict)
|
||||||
|
|
||||||
|
# NEW: Linking fields
|
||||||
|
internal_links = models.JSONField(default=list)
|
||||||
|
linker_version = models.IntegerField(default=0)
|
||||||
|
|
||||||
|
# NEW: Optimization fields
|
||||||
|
optimizer_version = models.IntegerField(default=0)
|
||||||
|
optimization_scores = models.JSONField(default=dict)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## LINKER IMPLEMENTATION
|
||||||
|
|
||||||
|
### 4.2 Linker Models
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **InternalLink Model** | `domain/linking/models.py` | Phase 1 | Store link relationships |
|
||||||
|
| **LinkGraph Model** | `domain/linking/models.py` | Phase 1 | Store link graph |
|
||||||
|
|
||||||
|
### 4.3 Linker Service
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **LinkerService** | `domain/linking/services/linker_service.py` | Phase 1, ContentService | Main linking service |
|
||||||
|
| **Link Candidate Engine** | `domain/linking/services/candidate_engine.py` | Phase 1 | Find link candidates |
|
||||||
|
| **Link Injection Engine** | `domain/linking/services/injection_engine.py` | Phase 1 | Inject links into content |
|
||||||
|
|
||||||
|
**LinkerService**:
|
||||||
|
```python
|
||||||
|
# domain/linking/services/linker_service.py
|
||||||
|
class LinkerService:
|
||||||
|
def process(self, content_id):
|
||||||
|
"""Process content for linking"""
|
||||||
|
content = Content.objects.get(id=content_id)
|
||||||
|
|
||||||
|
# Check credits
|
||||||
|
credit_service.check_credits(content.account, 'linking')
|
||||||
|
|
||||||
|
# Find link candidates
|
||||||
|
candidates = self.candidate_engine.find_candidates(content)
|
||||||
|
|
||||||
|
# Inject links
|
||||||
|
linked_content = self.injection_engine.inject_links(content, candidates)
|
||||||
|
|
||||||
|
# Update content
|
||||||
|
content.internal_links = linked_content['links']
|
||||||
|
content.linker_version += 1
|
||||||
|
content.save()
|
||||||
|
|
||||||
|
# Deduct credits
|
||||||
|
credit_service.deduct_credits(content.account, 'linking')
|
||||||
|
|
||||||
|
return content
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## OPTIMIZER IMPLEMENTATION
|
||||||
|
|
||||||
|
### 4.5 Optimizer Models
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **OptimizationTask Model** | `domain/optimization/models.py` | Phase 1 | Store optimization results |
|
||||||
|
| **OptimizationScores Model** | `domain/optimization/models.py` | Phase 1 | Store optimization scores |
|
||||||
|
|
||||||
|
### 4.6 Optimizer Service (Multiple Entry Points)
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **OptimizerService** | `domain/optimization/services/optimizer_service.py` | Phase 1, ContentService | Main optimization service |
|
||||||
|
| **Content Analyzer** | `domain/optimization/services/analyzer.py` | Phase 1 | Analyze content quality |
|
||||||
|
| **Optimization AI Function** | `infrastructure/ai/functions/optimize_content.py` | Existing AI framework | AI optimization function |
|
||||||
|
|
||||||
|
**OptimizerService**:
|
||||||
|
```python
|
||||||
|
# domain/optimization/services/optimizer_service.py
|
||||||
|
class OptimizerService:
|
||||||
|
def optimize_from_writer(self, content_id):
|
||||||
|
"""Entry Point 1: Writer → Optimizer"""
|
||||||
|
content = Content.objects.get(id=content_id, source='igny8')
|
||||||
|
return self.optimize(content)
|
||||||
|
|
||||||
|
def optimize_from_wordpress_sync(self, content_id):
|
||||||
|
"""Entry Point 2: WordPress Sync → Optimizer"""
|
||||||
|
content = Content.objects.get(id=content_id, source='wordpress')
|
||||||
|
return self.optimize(content)
|
||||||
|
|
||||||
|
def optimize_from_external_sync(self, content_id):
|
||||||
|
"""Entry Point 3: External Sync → Optimizer"""
|
||||||
|
content = Content.objects.get(id=content_id, source__in=['shopify', 'custom'])
|
||||||
|
return self.optimize(content)
|
||||||
|
|
||||||
|
def optimize_manual(self, content_id):
|
||||||
|
"""Entry Point 4: Manual Selection → Optimizer"""
|
||||||
|
content = Content.objects.get(id=content_id)
|
||||||
|
return self.optimize(content)
|
||||||
|
|
||||||
|
def optimize(self, content):
|
||||||
|
"""Unified optimization logic"""
|
||||||
|
# Check credits
|
||||||
|
credit_service.check_credits(content.account, 'optimization', content.word_count)
|
||||||
|
|
||||||
|
# Analyze content
|
||||||
|
scores_before = self.analyzer.analyze(content)
|
||||||
|
|
||||||
|
# Optimize content
|
||||||
|
optimized = self.ai_function.optimize(content)
|
||||||
|
|
||||||
|
# Analyze optimized content
|
||||||
|
scores_after = self.analyzer.analyze(optimized)
|
||||||
|
|
||||||
|
# Store optimization task
|
||||||
|
OptimizationTask.objects.create(
|
||||||
|
content=content,
|
||||||
|
scores_before=scores_before,
|
||||||
|
scores_after=scores_after,
|
||||||
|
html_before=content.html_content,
|
||||||
|
html_after=optimized['html_content'],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Update content
|
||||||
|
content.optimizer_version += 1
|
||||||
|
content.optimization_scores = scores_after
|
||||||
|
content.save()
|
||||||
|
|
||||||
|
# Deduct credits
|
||||||
|
credit_service.deduct_credits(content.account, 'optimization', content.word_count)
|
||||||
|
|
||||||
|
return content
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CONTENT PIPELINE SERVICE
|
||||||
|
|
||||||
|
### 4.7 Content Pipeline Service
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **ContentPipelineService** | `domain/content/services/content_pipeline_service.py` | LinkerService, OptimizerService | Orchestrate content pipeline |
|
||||||
|
|
||||||
|
**Pipeline Workflow States**:
|
||||||
|
```
|
||||||
|
Content States:
|
||||||
|
- 'draft' → Generated, not processed
|
||||||
|
- 'linked' → Links added, ready for optimization
|
||||||
|
- 'optimized' → Optimized, ready for review
|
||||||
|
- 'review' → Ready for publishing
|
||||||
|
- 'published' → Published to destination(s)
|
||||||
|
```
|
||||||
|
|
||||||
|
**ContentPipelineService**:
|
||||||
|
```python
|
||||||
|
# domain/content/services/content_pipeline_service.py
|
||||||
|
class ContentPipelineService:
|
||||||
|
def process_writer_content(self, content_id, stages=['linking', 'optimization']):
|
||||||
|
"""Writer → Linker → Optimizer pipeline"""
|
||||||
|
content = Content.objects.get(id=content_id, source='igny8')
|
||||||
|
|
||||||
|
if 'linking' in stages:
|
||||||
|
content = linker_service.process(content.id)
|
||||||
|
|
||||||
|
if 'optimization' in stages:
|
||||||
|
content = optimizer_service.optimize_from_writer(content.id)
|
||||||
|
|
||||||
|
return content
|
||||||
|
|
||||||
|
def process_synced_content(self, content_id, stages=['optimization']):
|
||||||
|
"""Synced Content → Optimizer (skip linking if needed)"""
|
||||||
|
content = Content.objects.get(id=content_id)
|
||||||
|
|
||||||
|
if 'optimization' in stages:
|
||||||
|
content = optimizer_service.optimize_manual(content.id)
|
||||||
|
|
||||||
|
return content
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## LINKER & OPTIMIZER APIs
|
||||||
|
|
||||||
|
### 4.8 Linker & Optimizer APIs
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Linker ViewSet** | `modules/linker/views.py` | LinkerService | API for linker operations |
|
||||||
|
| **Optimizer ViewSet** | `modules/optimizer/views.py` | OptimizerService | API for optimizer operations |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## LINKER & OPTIMIZER UI
|
||||||
|
|
||||||
|
### 4.9 Linker & Optimizer UI
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Linker Dashboard** | `frontend/src/pages/Linker/Dashboard.tsx` | NEW | Linker overview |
|
||||||
|
| **Optimizer Dashboard** | `frontend/src/pages/Optimizer/Dashboard.tsx` | NEW | Optimizer overview |
|
||||||
|
| **Content Selection UI** | `frontend/src/components/optimizer/ContentSelector.tsx` | NEW | Select content for optimization |
|
||||||
|
| **Source Badge Component** | `frontend/src/components/content/SourceBadge.tsx` | NEW | Show content source |
|
||||||
|
|
||||||
|
**Optimizer UI Features**:
|
||||||
|
- Show content source (IGNY8, WordPress, Shopify badge)
|
||||||
|
- Show sync status (Native, Synced, Imported badge)
|
||||||
|
- Entry point selection (from Writer, from Sync, Manual)
|
||||||
|
- Content list with source filters
|
||||||
|
- "Send to Optimizer" button (works for any source)
|
||||||
|
|
||||||
|
### 4.10 Content Filtering & Display
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Content Filter Component** | `frontend/src/components/content/ContentFilter.tsx` | NEW | Filter content by source |
|
||||||
|
| **Source Filter** | `frontend/src/components/content/SourceFilter.tsx` | NEW | Filter by source |
|
||||||
|
| **Sync Status Filter** | `frontend/src/components/content/SyncStatusFilter.tsx` | NEW | Filter by sync status |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TESTING & VALIDATION
|
||||||
|
|
||||||
|
### 4.11 Testing
|
||||||
|
|
||||||
|
**Test Cases**:
|
||||||
|
- ✅ Writer → Linker handover works
|
||||||
|
- ✅ Linker finds appropriate link candidates
|
||||||
|
- ✅ Links inject correctly into content
|
||||||
|
- ✅ Optimizer works from Writer entry point
|
||||||
|
- ✅ Optimizer works from WordPress sync entry point
|
||||||
|
- ✅ Optimizer works from 3rd party sync entry point
|
||||||
|
- ✅ Optimizer works from manual selection
|
||||||
|
- ✅ Synced content stored correctly with source flags
|
||||||
|
- ✅ Content filtering works (by source, sync_status)
|
||||||
|
- ✅ Pipeline orchestrates correctly
|
||||||
|
- ✅ All entry points use same optimization logic
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## IMPLEMENTATION CHECKLIST
|
||||||
|
|
||||||
|
### Backend Tasks
|
||||||
|
|
||||||
|
- [ ] Extend Content model with source/sync fields
|
||||||
|
- [ ] Create `domain/linking/models.py`
|
||||||
|
- [ ] Create LinkerService
|
||||||
|
- [ ] Create `domain/optimization/models.py`
|
||||||
|
- [ ] Create OptimizerService
|
||||||
|
- [ ] Create optimization AI function
|
||||||
|
- [ ] Create ContentPipelineService
|
||||||
|
- [ ] Create Linker ViewSet
|
||||||
|
- [ ] Create Optimizer ViewSet
|
||||||
|
- [ ] Create content sync service (for Phase 6)
|
||||||
|
|
||||||
|
### Frontend Tasks
|
||||||
|
|
||||||
|
- [ ] Create Linker Dashboard
|
||||||
|
- [ ] Create Optimizer Dashboard
|
||||||
|
- [ ] Create content selection UI
|
||||||
|
- [ ] Create source badge component
|
||||||
|
- [ ] Create content filters
|
||||||
|
- [ ] Update content list with filters
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SUCCESS CRITERIA
|
||||||
|
|
||||||
|
- ✅ Writer → Linker handover works
|
||||||
|
- ✅ Optimizer works from all entry points
|
||||||
|
- ✅ Content source tracking works
|
||||||
|
- ✅ Pipeline orchestrates correctly
|
||||||
|
- ✅ UI shows content sources and filters
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**END OF PHASE 4 DOCUMENT**
|
||||||
|
|
||||||
181
docs/planning/phases/PHASE-5-SITES-RENDERER.md
Normal file
181
docs/planning/phases/PHASE-5-SITES-RENDERER.md
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
# PHASE 5: SITES RENDERER
|
||||||
|
**Detailed Implementation Plan**
|
||||||
|
|
||||||
|
**Goal**: Build Sites renderer for hosting public sites.
|
||||||
|
|
||||||
|
**Timeline**: 2-3 weeks
|
||||||
|
**Priority**: MEDIUM
|
||||||
|
**Dependencies**: Phase 3
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TABLE OF CONTENTS
|
||||||
|
|
||||||
|
1. [Overview](#overview)
|
||||||
|
2. [Sites Renderer Container](#sites-renderer-container)
|
||||||
|
3. [Publisher Service](#publisher-service)
|
||||||
|
4. [Publishing Models](#publishing-models)
|
||||||
|
5. [Publisher API](#publisher-api)
|
||||||
|
6. [Multiple Layout Options](#multiple-layout-options)
|
||||||
|
7. [Testing & Validation](#testing--validation)
|
||||||
|
8. [Implementation Checklist](#implementation-checklist)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## OVERVIEW
|
||||||
|
|
||||||
|
### Objectives
|
||||||
|
- ✅ Create Sites renderer container
|
||||||
|
- ✅ Build publisher service
|
||||||
|
- ✅ Support multiple layout options
|
||||||
|
- ✅ Deploy sites to public URLs
|
||||||
|
- ✅ Render sites from site definitions
|
||||||
|
|
||||||
|
### Key Principles
|
||||||
|
- **Component Reuse**: Use shared component library from Phase 3
|
||||||
|
- **Multiple Layouts**: Support 7 layout types
|
||||||
|
- **Public Access**: Sites accessible via public URLs
|
||||||
|
- **User-Friendly**: "My Websites" or "Published Sites" in UI
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SITES RENDERER CONTAINER
|
||||||
|
|
||||||
|
### 5.1 Sites Renderer Container
|
||||||
|
|
||||||
|
**User-Friendly Name**: "My Websites" or "Published Sites"
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Create Sites Container** | `docker-compose.app.yml` | None | Add new container for sites renderer |
|
||||||
|
| **Sites Renderer Frontend** | `sites/src/` | NEW | React app for rendering sites |
|
||||||
|
| **Site Definition Loader** | `sites/src/loaders/loadSiteDefinition.ts` | NEW | Load site definitions from API |
|
||||||
|
| **Layout Renderer** | `sites/src/utils/layoutRenderer.ts` | NEW | Render different layouts |
|
||||||
|
| **Template System** | `sites/src/utils/templateEngine.ts` | NEW | Template rendering system |
|
||||||
|
|
||||||
|
**Docker Compose Configuration**:
|
||||||
|
```yaml
|
||||||
|
# docker-compose.app.yml
|
||||||
|
igny8_sites:
|
||||||
|
build: ./sites
|
||||||
|
ports:
|
||||||
|
- "8024:5176"
|
||||||
|
volumes:
|
||||||
|
- /data/app/igny8/sites:/app
|
||||||
|
- /data/app/sites-data:/sites
|
||||||
|
environment:
|
||||||
|
- VITE_API_URL=http://igny8_backend:8010
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PUBLISHER SERVICE
|
||||||
|
|
||||||
|
### 5.2 Publisher Service
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **PublisherService** | `domain/publishing/services/publisher_service.py` | Phase 1 | Main publishing service |
|
||||||
|
| **SitesRendererAdapter** | `domain/publishing/services/adapters/sites_renderer_adapter.py` | Phase 3 | Adapter for Sites renderer |
|
||||||
|
| **DeploymentService** | `domain/publishing/services/deployment_service.py` | Phase 3 | Deploy sites to renderer |
|
||||||
|
|
||||||
|
**PublisherService**:
|
||||||
|
```python
|
||||||
|
# domain/publishing/services/publisher_service.py
|
||||||
|
class PublisherService:
|
||||||
|
def publish_to_sites(self, site_blueprint):
|
||||||
|
"""Publish site to Sites renderer"""
|
||||||
|
adapter = SitesRendererAdapter()
|
||||||
|
return adapter.deploy(site_blueprint)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PUBLISHING MODELS
|
||||||
|
|
||||||
|
### 5.3 Publishing Models
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **PublishingRecord Model** | `domain/publishing/models.py` | Phase 1 | Track content publishing |
|
||||||
|
| **DeploymentRecord Model** | `domain/publishing/models.py` | Phase 3 | Track site deployments |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PUBLISHER API
|
||||||
|
|
||||||
|
### 5.4 Publisher API
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Publisher ViewSet** | `modules/publisher/views.py` | PublisherService | API for publishing operations |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## MULTIPLE LAYOUT OPTIONS
|
||||||
|
|
||||||
|
### 5.6 Multiple Layout Options
|
||||||
|
|
||||||
|
**Layout Types**:
|
||||||
|
- Default (Standard)
|
||||||
|
- Minimal (Clean, simple)
|
||||||
|
- Magazine (Editorial, content-focused)
|
||||||
|
- Ecommerce (Product-focused)
|
||||||
|
- Portfolio (Showcase)
|
||||||
|
- Blog (Content-first)
|
||||||
|
- Corporate (Business)
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Layout Configuration** | `domain/site_building/models.py` | Phase 3 | Store layout selection |
|
||||||
|
| **Layout Renderer** | `sites/src/utils/layoutRenderer.ts` | Phase 5 | Render different layouts |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TESTING & VALIDATION
|
||||||
|
|
||||||
|
### 5.5 Testing
|
||||||
|
|
||||||
|
**Test Cases**:
|
||||||
|
- ✅ Sites renderer loads site definitions
|
||||||
|
- ✅ Blocks render correctly
|
||||||
|
- ✅ Deployment works end-to-end
|
||||||
|
- ✅ Sites are accessible publicly
|
||||||
|
- ✅ Multiple layouts work correctly
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## IMPLEMENTATION CHECKLIST
|
||||||
|
|
||||||
|
### Backend Tasks
|
||||||
|
|
||||||
|
- [ ] Create PublisherService
|
||||||
|
- [ ] Create SitesRendererAdapter
|
||||||
|
- [ ] Create DeploymentService
|
||||||
|
- [ ] Create PublishingRecord model
|
||||||
|
- [ ] Create DeploymentRecord model
|
||||||
|
- [ ] Create Publisher ViewSet
|
||||||
|
|
||||||
|
### Frontend Tasks
|
||||||
|
|
||||||
|
- [ ] Create Sites container in docker-compose
|
||||||
|
- [ ] Create sites renderer frontend
|
||||||
|
- [ ] Create site definition loader
|
||||||
|
- [ ] Create layout renderer
|
||||||
|
- [ ] Create template system
|
||||||
|
- [ ] Import shared components
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SUCCESS CRITERIA
|
||||||
|
|
||||||
|
- ✅ Sites renderer loads site definitions
|
||||||
|
- ✅ Blocks render correctly
|
||||||
|
- ✅ Deployment works end-to-end
|
||||||
|
- ✅ Sites are accessible publicly
|
||||||
|
- ✅ Multiple layouts supported
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**END OF PHASE 5 DOCUMENT**
|
||||||
|
|
||||||
242
docs/planning/phases/PHASE-6-SITE-INTEGRATION-PUBLISHING.md
Normal file
242
docs/planning/phases/PHASE-6-SITE-INTEGRATION-PUBLISHING.md
Normal file
@@ -0,0 +1,242 @@
|
|||||||
|
# PHASE 6: SITE INTEGRATION & MULTI-DESTINATION PUBLISHING
|
||||||
|
**Detailed Implementation Plan**
|
||||||
|
|
||||||
|
**Goal**: Support multiple publishing destinations (WordPress, Sites, Shopify).
|
||||||
|
|
||||||
|
**Timeline**: 2-3 weeks
|
||||||
|
**Priority**: MEDIUM
|
||||||
|
**Dependencies**: Phase 5
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TABLE OF CONTENTS
|
||||||
|
|
||||||
|
1. [Overview](#overview)
|
||||||
|
2. [Site Integration Models](#site-integration-models)
|
||||||
|
3. [Integration Service](#integration-service)
|
||||||
|
4. [Publishing Adapters](#publishing-adapters)
|
||||||
|
5. [Multi-Destination Publishing](#multi-destination-publishing)
|
||||||
|
6. [Site Model Extensions](#site-model-extensions)
|
||||||
|
7. [Integration API](#integration-api)
|
||||||
|
8. [Integration UI](#integration-ui)
|
||||||
|
9. [Publishing Settings UI](#publishing-settings-ui)
|
||||||
|
10. [Site Management UI](#site-management-ui)
|
||||||
|
11. [Testing & Validation](#testing--validation)
|
||||||
|
12. [Implementation Checklist](#implementation-checklist)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## OVERVIEW
|
||||||
|
|
||||||
|
### Objectives
|
||||||
|
- ✅ Support multiple site integrations per site
|
||||||
|
- ✅ Multi-destination publishing (WordPress, Sites, Shopify)
|
||||||
|
- ✅ Two-way sync with external platforms
|
||||||
|
- ✅ Site management UI (CMS)
|
||||||
|
- ✅ Publishing settings UI
|
||||||
|
|
||||||
|
### Key Principles
|
||||||
|
- **Multiple Integrations**: One site can have multiple integrations
|
||||||
|
- **Adapter Pattern**: Platform-specific adapters for publishing
|
||||||
|
- **Two-Way Sync**: Sync content both ways
|
||||||
|
- **User-Friendly**: "Site Manager" or "Content Manager" in UI
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SITE INTEGRATION MODELS
|
||||||
|
|
||||||
|
### 6.1 Site Integration Models
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **SiteIntegration Model** | `domain/integration/models.py` | Phase 1 | Store integration configs |
|
||||||
|
|
||||||
|
**SiteIntegration Model**:
|
||||||
|
```python
|
||||||
|
# domain/integration/models.py
|
||||||
|
class SiteIntegration(SiteSectorBaseModel):
|
||||||
|
site = models.ForeignKey(Site, on_delete=models.CASCADE)
|
||||||
|
platform = models.CharField(max_length=50) # 'wordpress', 'shopify', 'custom'
|
||||||
|
platform_type = models.CharField(max_length=50) # 'cms', 'ecommerce', 'custom_api'
|
||||||
|
config_json = models.JSONField(default=dict)
|
||||||
|
credentials = models.EncryptedField() # Encrypted API keys
|
||||||
|
is_active = models.BooleanField(default=True)
|
||||||
|
sync_enabled = models.BooleanField(default=False)
|
||||||
|
last_sync_at = models.DateTimeField(null=True, blank=True)
|
||||||
|
sync_status = models.CharField(max_length=20) # 'success', 'failed', 'pending'
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## INTEGRATION SERVICE
|
||||||
|
|
||||||
|
### 6.2 Integration Service
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **IntegrationService** | `domain/integration/services/integration_service.py` | Phase 1 | Manage integrations |
|
||||||
|
| **SyncService** | `domain/integration/services/sync_service.py` | Phase 1 | Handle two-way sync |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PUBLISHING ADAPTERS
|
||||||
|
|
||||||
|
### 6.3 Publishing Adapters
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **BaseAdapter** | `domain/publishing/services/adapters/base_adapter.py` | Phase 5 | Base adapter interface |
|
||||||
|
| **WordPressAdapter** | `domain/publishing/services/adapters/wordpress_adapter.py` | EXISTING (refactor) | WordPress publishing |
|
||||||
|
| **SitesRendererAdapter** | `domain/publishing/services/adapters/sites_renderer_adapter.py` | Phase 5 | IGNY8 Sites deployment |
|
||||||
|
| **ShopifyAdapter** | `domain/publishing/services/adapters/shopify_adapter.py` | Phase 5 (future) | Shopify publishing |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## MULTI-DESTINATION PUBLISHING
|
||||||
|
|
||||||
|
### 6.4 Multi-Destination Publishing
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Extend PublisherService** | `domain/publishing/services/publisher_service.py` | Phase 5 | Support multiple destinations |
|
||||||
|
| **Update PublishingRecord** | `domain/publishing/models.py` | Phase 5 | Track multiple destinations |
|
||||||
|
|
||||||
|
**Multi-Destination Publishing**:
|
||||||
|
```python
|
||||||
|
# domain/publishing/services/publisher_service.py
|
||||||
|
class PublisherService:
|
||||||
|
def publish(self, content, destinations):
|
||||||
|
"""Publish content to multiple destinations"""
|
||||||
|
results = []
|
||||||
|
for destination in destinations:
|
||||||
|
adapter = self.get_adapter(destination)
|
||||||
|
result = adapter.publish(content)
|
||||||
|
results.append(result)
|
||||||
|
return results
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SITE MODEL EXTENSIONS
|
||||||
|
|
||||||
|
### 6.5 Site Model Extensions
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Add site_type field** | `core/auth/models.py` | None | Track site type |
|
||||||
|
| **Add hosting_type field** | `core/auth/models.py` | None | Track hosting type |
|
||||||
|
| **Add integrations relationship** | `core/auth/models.py` | Phase 6.1 | Link to SiteIntegration |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## INTEGRATION API
|
||||||
|
|
||||||
|
### 6.6 Integration API
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Integration ViewSet** | `modules/integration/views.py` | IntegrationService | CRUD for integrations |
|
||||||
|
| **Integration URLs** | `modules/integration/urls.py` | None | Register integration routes |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## INTEGRATION UI
|
||||||
|
|
||||||
|
### 6.7 Integration UI (Update Existing)
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Update Integration Settings** | `frontend/src/pages/Settings/Integration.tsx` | EXISTING (update) | Add SiteIntegration support |
|
||||||
|
| **Multi-Platform Support** | `frontend/src/components/integration/PlatformSelector.tsx` | NEW | Platform selector |
|
||||||
|
| **Integration Status** | `frontend/src/components/integration/IntegrationStatus.tsx` | NEW | Show integration status |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PUBLISHING SETTINGS UI
|
||||||
|
|
||||||
|
### 6.8 Publishing Settings UI
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Publishing Settings Page** | `frontend/src/pages/Settings/Publishing.tsx` | NEW | Publishing configuration |
|
||||||
|
| **Destination Management** | `frontend/src/pages/Settings/Publishing.tsx` | Phase 6 | Manage publishing destinations |
|
||||||
|
| **Publishing Rules** | `frontend/src/components/publishing/PublishingRules.tsx` | NEW | Publishing rules configuration |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SITE MANAGEMENT UI
|
||||||
|
|
||||||
|
### 6.9 Individual Site Management (CMS)
|
||||||
|
|
||||||
|
**User-Friendly Name**: "Site Manager" or "Content Manager"
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Site Management Dashboard** | `frontend/src/pages/Sites/Manage.tsx` | NEW | Site management overview |
|
||||||
|
| **Site Content Editor** | `frontend/src/pages/Sites/Editor.tsx` | NEW | Edit site content |
|
||||||
|
| **Post Editor** | `frontend/src/pages/Sites/PostEditor.tsx` | NEW | Edit posts |
|
||||||
|
| **Page Manager** | `frontend/src/pages/Sites/PageManager.tsx` | NEW | Manage pages |
|
||||||
|
| **Site Settings** | `frontend/src/pages/Sites/Settings.tsx` | NEW | Site settings |
|
||||||
|
|
||||||
|
**Site Management Features**:
|
||||||
|
- View all pages/posts for a site
|
||||||
|
- Add new pages
|
||||||
|
- Remove pages
|
||||||
|
- Edit page content
|
||||||
|
- Manage page order
|
||||||
|
- Change page templates
|
||||||
|
- Update site settings
|
||||||
|
- Preview site
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TESTING & VALIDATION
|
||||||
|
|
||||||
|
### 6.9 Testing
|
||||||
|
|
||||||
|
**Test Cases**:
|
||||||
|
- ✅ Site integrations work correctly
|
||||||
|
- ✅ Multi-destination publishing works
|
||||||
|
- ✅ WordPress sync works (when plugin connected)
|
||||||
|
- ✅ Two-way sync functions properly
|
||||||
|
- ✅ Site management UI works
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## IMPLEMENTATION CHECKLIST
|
||||||
|
|
||||||
|
### Backend Tasks
|
||||||
|
|
||||||
|
- [ ] Create SiteIntegration model
|
||||||
|
- [ ] Create IntegrationService
|
||||||
|
- [ ] Create SyncService
|
||||||
|
- [ ] Create BaseAdapter
|
||||||
|
- [ ] Refactor WordPressAdapter
|
||||||
|
- [ ] Create SitesRendererAdapter
|
||||||
|
- [ ] Extend PublisherService for multi-destination
|
||||||
|
- [ ] Extend Site model
|
||||||
|
- [ ] Create Integration ViewSet
|
||||||
|
|
||||||
|
### Frontend Tasks
|
||||||
|
|
||||||
|
- [ ] Update Integration Settings page
|
||||||
|
- [ ] Create Publishing Settings page
|
||||||
|
- [ ] Create Site Management Dashboard
|
||||||
|
- [ ] Create Site Content Editor
|
||||||
|
- [ ] Create Page Manager
|
||||||
|
- [ ] Create Site Settings page
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SUCCESS CRITERIA
|
||||||
|
|
||||||
|
- ✅ Site integrations work correctly
|
||||||
|
- ✅ Multi-destination publishing works
|
||||||
|
- ✅ WordPress sync works
|
||||||
|
- ✅ Two-way sync functions properly
|
||||||
|
- ✅ Site management UI works
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**END OF PHASE 6 DOCUMENT**
|
||||||
|
|
||||||
205
docs/planning/phases/PHASE-7-UI-COMPONENTS-MODULE-SETTINGS.md
Normal file
205
docs/planning/phases/PHASE-7-UI-COMPONENTS-MODULE-SETTINGS.md
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
# PHASE 7: UI COMPONENTS & MODULE SETTINGS
|
||||||
|
**Detailed Implementation Plan**
|
||||||
|
|
||||||
|
**Goal**: Build comprehensive UI system with shared components, module settings, and site management.
|
||||||
|
|
||||||
|
**Timeline**: 3-4 weeks
|
||||||
|
**Priority**: MEDIUM
|
||||||
|
**Dependencies**: Phase 0, Phase 3, Phase 5
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TABLE OF CONTENTS
|
||||||
|
|
||||||
|
1. [Overview](#overview)
|
||||||
|
2. [Global Component Library](#global-component-library)
|
||||||
|
3. [Module Settings UI](#module-settings-ui)
|
||||||
|
4. [Frontend Module Loader](#frontend-module-loader)
|
||||||
|
5. [Site Management UI](#site-management-ui)
|
||||||
|
6. [Layout & Template System](#layout--template-system)
|
||||||
|
7. [CMS Styling System](#cms-styling-system)
|
||||||
|
8. [Testing & Validation](#testing--validation)
|
||||||
|
9. [Implementation Checklist](#implementation-checklist)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## OVERVIEW
|
||||||
|
|
||||||
|
### Objectives
|
||||||
|
- ✅ Complete global component library
|
||||||
|
- ✅ Implement module settings UI
|
||||||
|
- ✅ Build site management UI
|
||||||
|
- ✅ Create layout and template system
|
||||||
|
- ✅ Implement CMS styling system
|
||||||
|
|
||||||
|
### Key Principles
|
||||||
|
- **No Duplication**: All components shared across apps
|
||||||
|
- **TypeScript**: All components use TypeScript
|
||||||
|
- **Accessibility**: All components accessible (ARIA)
|
||||||
|
- **Responsive**: All components responsive
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## GLOBAL COMPONENT LIBRARY
|
||||||
|
|
||||||
|
### 7.1 Global Component Library
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Component Library Structure** | `frontend/src/components/shared/` | None | Complete component library |
|
||||||
|
| **Block Components** | `frontend/src/components/shared/blocks/` | None | All block components |
|
||||||
|
| **Layout Components** | `frontend/src/components/shared/layouts/` | None | All layout components |
|
||||||
|
| **Template Components** | `frontend/src/components/shared/templates/` | None | All template components |
|
||||||
|
| **Component Documentation** | `frontend/src/components/shared/README.md` | None | Document all components |
|
||||||
|
| **Component Storybook** | `frontend/.storybook/` | Optional | Component documentation |
|
||||||
|
| **Component Tests** | `frontend/src/components/shared/**/*.test.tsx` | None | Test all components |
|
||||||
|
|
||||||
|
**Component Standards**:
|
||||||
|
- All components use TypeScript
|
||||||
|
- All components have props interfaces
|
||||||
|
- All components are responsive
|
||||||
|
- All components support dark mode
|
||||||
|
- All components are accessible (ARIA)
|
||||||
|
- No duplicate components
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## MODULE SETTINGS UI
|
||||||
|
|
||||||
|
### 7.2 Module Settings UI
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Module Settings Page** | `frontend/src/pages/Settings/Modules.tsx` | EXISTING (implement) | Module settings interface |
|
||||||
|
| **Module Toggle Component** | `frontend/src/components/settings/ModuleToggle.tsx` | NEW | Toggle module on/off |
|
||||||
|
| **Module Status Indicator** | `frontend/src/components/settings/ModuleStatus.tsx` | NEW | Show module status |
|
||||||
|
| **Module Configuration** | `frontend/src/components/settings/ModuleConfig.tsx` | NEW | Module configuration UI |
|
||||||
|
|
||||||
|
**Module Settings Features**:
|
||||||
|
- Enable/disable modules per account
|
||||||
|
- Module-specific configuration
|
||||||
|
- Module status display
|
||||||
|
- Module usage statistics
|
||||||
|
- Module dependencies check
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## FRONTEND MODULE LOADER
|
||||||
|
|
||||||
|
### 7.3 Frontend Module Loader
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Module Config** | `frontend/src/config/modules.config.ts` | Phase 0 | Module configuration |
|
||||||
|
| **Module Guard** | `frontend/src/components/common/ModuleGuard.tsx` | Phase 0 | Route guard component |
|
||||||
|
| **Conditional Route Loading** | `frontend/src/App.tsx` | Phase 0 | Conditional routes |
|
||||||
|
| **Sidebar Module Filter** | `frontend/src/layout/AppSidebar.tsx` | Phase 0 | Filter disabled modules |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SITE MANAGEMENT UI
|
||||||
|
|
||||||
|
### 7.4 Site Management UI
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Site List View** | `frontend/src/pages/Sites/List.tsx` | NEW | List all sites |
|
||||||
|
| **Site Dashboard** | `frontend/src/pages/Sites/Dashboard.tsx` | NEW | Site overview |
|
||||||
|
| **Site Content Manager** | `frontend/src/pages/Sites/Content.tsx` | NEW | Manage site content |
|
||||||
|
| **Post Editor** | `frontend/src/pages/Sites/PostEditor.tsx` | NEW | Edit posts |
|
||||||
|
| **Page Manager** | `frontend/src/pages/Sites/Pages.tsx` | NEW | Manage pages |
|
||||||
|
| **Site Settings** | `frontend/src/pages/Sites/Settings.tsx` | NEW | Site settings |
|
||||||
|
| **Site Preview** | `frontend/src/pages/Sites/Preview.tsx` | NEW | Preview site |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## LAYOUT & TEMPLATE SYSTEM
|
||||||
|
|
||||||
|
### 7.5 Layout & Template System
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Layout Selector** | `frontend/src/components/sites/LayoutSelector.tsx` | NEW | Select layout |
|
||||||
|
| **Template Library** | `frontend/src/components/sites/TemplateLibrary.tsx` | NEW | Template library |
|
||||||
|
| **Layout Preview** | `frontend/src/components/sites/LayoutPreview.tsx` | NEW | Preview layouts |
|
||||||
|
| **Template Customizer** | `frontend/src/components/sites/TemplateCustomizer.tsx` | NEW | Customize templates |
|
||||||
|
| **Style Editor** | `frontend/src/components/sites/StyleEditor.tsx` | NEW | Edit styles |
|
||||||
|
|
||||||
|
**Layout Options**:
|
||||||
|
- Default Layout
|
||||||
|
- Minimal Layout
|
||||||
|
- Magazine Layout
|
||||||
|
- Ecommerce Layout
|
||||||
|
- Portfolio Layout
|
||||||
|
- Blog Layout
|
||||||
|
- Corporate Layout
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CMS STYLING SYSTEM
|
||||||
|
|
||||||
|
### 7.6 CMS Styling System
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **CMS Theme System** | `frontend/src/styles/cms/` | NEW | Theme system |
|
||||||
|
| **Style Presets** | `frontend/src/styles/cms/presets.ts` | NEW | Style presets |
|
||||||
|
| **Color Schemes** | `frontend/src/styles/cms/colors.ts` | NEW | Color schemes |
|
||||||
|
| **Typography System** | `frontend/src/styles/cms/typography.ts` | NEW | Typography system |
|
||||||
|
| **Component Styles** | `frontend/src/styles/cms/components.ts` | NEW | Component styles |
|
||||||
|
|
||||||
|
**CMS Features**:
|
||||||
|
- Theme customization
|
||||||
|
- Color palette management
|
||||||
|
- Typography settings
|
||||||
|
- Component styling
|
||||||
|
- Responsive breakpoints
|
||||||
|
- Dark/light mode
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TESTING & VALIDATION
|
||||||
|
|
||||||
|
### 7.7 Testing
|
||||||
|
|
||||||
|
**Test Cases**:
|
||||||
|
- ✅ All components render correctly
|
||||||
|
- ✅ Module settings enable/disable modules
|
||||||
|
- ✅ Disabled modules don't load
|
||||||
|
- ✅ Site management works end-to-end
|
||||||
|
- ✅ Layout system works
|
||||||
|
- ✅ Template system works
|
||||||
|
- ✅ No duplicate components
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## IMPLEMENTATION CHECKLIST
|
||||||
|
|
||||||
|
### Frontend Tasks
|
||||||
|
|
||||||
|
- [ ] Complete component library
|
||||||
|
- [ ] Implement module settings UI
|
||||||
|
- [ ] Create module loader
|
||||||
|
- [ ] Create site management UI
|
||||||
|
- [ ] Create layout system
|
||||||
|
- [ ] Create template system
|
||||||
|
- [ ] Create CMS styling system
|
||||||
|
- [ ] Write component tests
|
||||||
|
- [ ] Write component documentation
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SUCCESS CRITERIA
|
||||||
|
|
||||||
|
- ✅ All components render correctly
|
||||||
|
- ✅ Module settings enable/disable modules
|
||||||
|
- ✅ Disabled modules don't load
|
||||||
|
- ✅ Site management works end-to-end
|
||||||
|
- ✅ Layout system works
|
||||||
|
- ✅ Template system works
|
||||||
|
- ✅ No duplicate components
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**END OF PHASE 7 DOCUMENT**
|
||||||
|
|
||||||
156
docs/planning/phases/PHASE-8-UNIVERSAL-CONTENT-TYPES.md
Normal file
156
docs/planning/phases/PHASE-8-UNIVERSAL-CONTENT-TYPES.md
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
# PHASE 8: UNIVERSAL CONTENT TYPES
|
||||||
|
**Detailed Implementation Plan**
|
||||||
|
|
||||||
|
**Goal**: Extend content system to support products, services, taxonomies.
|
||||||
|
|
||||||
|
**Timeline**: 2-3 weeks
|
||||||
|
**Priority**: LOW
|
||||||
|
**Dependencies**: Phase 4
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TABLE OF CONTENTS
|
||||||
|
|
||||||
|
1. [Overview](#overview)
|
||||||
|
2. [Content Model Extensions](#content-model-extensions)
|
||||||
|
3. [Content Type Prompts](#content-type-prompts)
|
||||||
|
4. [Content Service Extensions](#content-service-extensions)
|
||||||
|
5. [Linker & Optimizer Extensions](#linker--optimizer-extensions)
|
||||||
|
6. [Testing & Validation](#testing--validation)
|
||||||
|
7. [Implementation Checklist](#implementation-checklist)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## OVERVIEW
|
||||||
|
|
||||||
|
### Objectives
|
||||||
|
- ✅ Support product content generation
|
||||||
|
- ✅ Support service page generation
|
||||||
|
- ✅ Support taxonomy generation
|
||||||
|
- ✅ Extend linker for all content types
|
||||||
|
- ✅ Extend optimizer for all content types
|
||||||
|
|
||||||
|
### Key Principles
|
||||||
|
- **Unified Model**: All content types use same Content model
|
||||||
|
- **Type-Specific Prompts**: Different prompts per content type
|
||||||
|
- **Universal Processing**: Linker and Optimizer work on all types
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CONTENT MODEL EXTENSIONS
|
||||||
|
|
||||||
|
### 8.1 Content Model Extensions
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Add entity_type field** | `domain/content/models.py` | Phase 1 | Content type field |
|
||||||
|
| **Add json_blocks field** | `domain/content/models.py` | Phase 1 | Structured content blocks |
|
||||||
|
| **Add structure_data field** | `domain/content/models.py` | Phase 1 | Content structure data |
|
||||||
|
|
||||||
|
**Content Model Extensions**:
|
||||||
|
```python
|
||||||
|
# domain/content/models.py
|
||||||
|
class Content(SiteSectorBaseModel):
|
||||||
|
# Existing fields...
|
||||||
|
|
||||||
|
# NEW: Entity type
|
||||||
|
entity_type = models.CharField(
|
||||||
|
max_length=50,
|
||||||
|
choices=[
|
||||||
|
('blog_post', 'Blog Post'),
|
||||||
|
('article', 'Article'),
|
||||||
|
('product', 'Product'),
|
||||||
|
('service', 'Service Page'),
|
||||||
|
('taxonomy', 'Taxonomy Page'),
|
||||||
|
('page', 'Page'),
|
||||||
|
],
|
||||||
|
default='blog_post'
|
||||||
|
)
|
||||||
|
|
||||||
|
# NEW: Structured content
|
||||||
|
json_blocks = models.JSONField(default=list)
|
||||||
|
structure_data = models.JSONField(default=dict)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CONTENT TYPE PROMPTS
|
||||||
|
|
||||||
|
### 8.2 Content Type Prompts
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Product Prompts** | `infrastructure/ai/prompts.py` | Existing prompt system | Product generation prompts |
|
||||||
|
| **Service Page Prompts** | `infrastructure/ai/prompts.py` | Existing prompt system | Service page prompts |
|
||||||
|
| **Taxonomy Prompts** | `infrastructure/ai/prompts.py` | Existing prompt system | Taxonomy prompts |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## CONTENT SERVICE EXTENSIONS
|
||||||
|
|
||||||
|
### 8.3 Content Service Extensions
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Product Content Generation** | `domain/content/services/content_generation_service.py` | Phase 1 | Generate product content |
|
||||||
|
| **Service Page Generation** | `domain/content/services/content_generation_service.py` | Phase 1 | Generate service pages |
|
||||||
|
| **Taxonomy Generation** | `domain/content/services/content_generation_service.py` | Phase 1 | Generate taxonomy pages |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## LINKER & OPTIMIZER EXTENSIONS
|
||||||
|
|
||||||
|
### 8.4 Linker & Optimizer Extensions
|
||||||
|
|
||||||
|
| Task | File | Dependencies | Implementation |
|
||||||
|
|------|------|--------------|----------------|
|
||||||
|
| **Product Linking** | `domain/linking/services/linker_service.py` | Phase 4 | Link products |
|
||||||
|
| **Taxonomy Linking** | `domain/linking/services/linker_service.py` | Phase 4 | Link taxonomies |
|
||||||
|
| **Product Optimization** | `domain/optimization/services/optimizer_service.py` | Phase 4 | Optimize products |
|
||||||
|
| **Taxonomy Optimization** | `domain/optimization/services/optimizer_service.py` | Phase 4 | Optimize taxonomies |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## TESTING & VALIDATION
|
||||||
|
|
||||||
|
### 8.5 Testing
|
||||||
|
|
||||||
|
**Test Cases**:
|
||||||
|
- ✅ Product content generates correctly
|
||||||
|
- ✅ Service pages work
|
||||||
|
- ✅ Taxonomy pages work
|
||||||
|
- ✅ Linking works for all types
|
||||||
|
- ✅ Optimization works for all types
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## IMPLEMENTATION CHECKLIST
|
||||||
|
|
||||||
|
### Backend Tasks
|
||||||
|
|
||||||
|
- [ ] Extend Content model with entity_type, json_blocks, structure_data
|
||||||
|
- [ ] Add product prompts
|
||||||
|
- [ ] Add service page prompts
|
||||||
|
- [ ] Add taxonomy prompts
|
||||||
|
- [ ] Extend ContentService for product generation
|
||||||
|
- [ ] Extend ContentService for service page generation
|
||||||
|
- [ ] Extend ContentService for taxonomy generation
|
||||||
|
- [ ] Extend LinkerService for products
|
||||||
|
- [ ] Extend LinkerService for taxonomies
|
||||||
|
- [ ] Extend OptimizerService for products
|
||||||
|
- [ ] Extend OptimizerService for taxonomies
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SUCCESS CRITERIA
|
||||||
|
|
||||||
|
- ✅ Product content generates correctly
|
||||||
|
- ✅ Service pages work
|
||||||
|
- ✅ Taxonomy pages work
|
||||||
|
- ✅ Linking works for all types
|
||||||
|
- ✅ Optimization works for all types
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**END OF PHASE 8 DOCUMENT**
|
||||||
|
|
||||||
141
docs/planning/phases/README.md
Normal file
141
docs/planning/phases/README.md
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
# PHASE IMPLEMENTATION DOCUMENTS
|
||||||
|
**Complete Phase-by-Phase Implementation Plans**
|
||||||
|
|
||||||
|
This folder contains detailed implementation plans for each phase of the IGNY8 Phase 2 development.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PHASE DOCUMENTS
|
||||||
|
|
||||||
|
| Phase | Document | Timeline | Priority | Dependencies |
|
||||||
|
|-------|----------|----------|----------|-------------|
|
||||||
|
| **Phase 0** | [PHASE-0-FOUNDATION-CREDIT-SYSTEM.md](./PHASE-0-FOUNDATION-CREDIT-SYSTEM.md) | 1-2 weeks | HIGH | None |
|
||||||
|
| **Phase 1** | [PHASE-1-SERVICE-LAYER-REFACTORING.md](./PHASE-1-SERVICE-LAYER-REFACTORING.md) | 2-3 weeks | HIGH | Phase 0 |
|
||||||
|
| **Phase 2** | [PHASE-2-AUTOMATION-SYSTEM.md](./PHASE-2-AUTOMATION-SYSTEM.md) | 2-3 weeks | HIGH | Phase 1 |
|
||||||
|
| **Phase 3** | [PHASE-3-SITE-BUILDER.md](./PHASE-3-SITE-BUILDER.md) | 3-4 weeks | HIGH | Phase 1, Phase 2 |
|
||||||
|
| **Phase 4** | [PHASE-4-LINKER-OPTIMIZER.md](./PHASE-4-LINKER-OPTIMIZER.md) | 4-5 weeks | MEDIUM | Phase 1 |
|
||||||
|
| **Phase 5** | [PHASE-5-SITES-RENDERER.md](./PHASE-5-SITES-RENDERER.md) | 2-3 weeks | MEDIUM | Phase 3 |
|
||||||
|
| **Phase 6** | [PHASE-6-SITE-INTEGRATION-PUBLISHING.md](./PHASE-6-SITE-INTEGRATION-PUBLISHING.md) | 2-3 weeks | MEDIUM | Phase 5 |
|
||||||
|
| **Phase 7** | [PHASE-7-UI-COMPONENTS-MODULE-SETTINGS.md](./PHASE-7-UI-COMPONENTS-MODULE-SETTINGS.md) | 3-4 weeks | MEDIUM | Phase 0, Phase 3, Phase 5 |
|
||||||
|
| **Phase 8** | [PHASE-8-UNIVERSAL-CONTENT-TYPES.md](./PHASE-8-UNIVERSAL-CONTENT-TYPES.md) | 2-3 weeks | LOW | Phase 4 |
|
||||||
|
|
||||||
|
**Total Estimated Time**: 20-29 weeks (5-7 months)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PHASE OVERVIEW
|
||||||
|
|
||||||
|
### Phase 0: Foundation & Credit System
|
||||||
|
- Migrate to credit-only model
|
||||||
|
- Implement module enable/disable
|
||||||
|
- Add credit cost tracking
|
||||||
|
- Remove plan limit fields
|
||||||
|
|
||||||
|
### Phase 1: Service Layer Refactoring
|
||||||
|
- Create domain structure
|
||||||
|
- Move models to domain
|
||||||
|
- Extract business logic to services
|
||||||
|
- Refactor ViewSets to thin wrappers
|
||||||
|
|
||||||
|
### Phase 2: Automation System
|
||||||
|
- Create AutomationRule and ScheduledTask models
|
||||||
|
- Build AutomationService
|
||||||
|
- Implement Celery Beat scheduled tasks
|
||||||
|
- Create automation UI
|
||||||
|
|
||||||
|
### Phase 3: Site Builder
|
||||||
|
- Build Site Builder wizard
|
||||||
|
- Generate site structure using AI
|
||||||
|
- Create shared component library
|
||||||
|
- Support multiple layouts and templates
|
||||||
|
|
||||||
|
### Phase 4: Linker & Optimizer
|
||||||
|
- Add internal linking to content
|
||||||
|
- Add content optimization
|
||||||
|
- Support multiple entry points
|
||||||
|
- Create content pipeline service
|
||||||
|
|
||||||
|
### Phase 5: Sites Renderer
|
||||||
|
- Create Sites renderer container
|
||||||
|
- Build publisher service
|
||||||
|
- Support multiple layout options
|
||||||
|
- Deploy sites to public URLs
|
||||||
|
|
||||||
|
### Phase 6: Site Integration & Multi-Destination Publishing
|
||||||
|
- Support multiple site integrations
|
||||||
|
- Multi-destination publishing
|
||||||
|
- Two-way sync with external platforms
|
||||||
|
- Site management UI (CMS)
|
||||||
|
|
||||||
|
### Phase 7: UI Components & Module Settings
|
||||||
|
- Complete global component library
|
||||||
|
- Implement module settings UI
|
||||||
|
- Build site management UI
|
||||||
|
- Create layout and template system
|
||||||
|
|
||||||
|
### Phase 8: Universal Content Types
|
||||||
|
- Support product content generation
|
||||||
|
- Support service page generation
|
||||||
|
- Support taxonomy generation
|
||||||
|
- Extend linker and optimizer for all types
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## IMPLEMENTATION ORDER
|
||||||
|
|
||||||
|
**Sequential Phases** (must be done in order):
|
||||||
|
1. Phase 0 → Phase 1 → Phase 2
|
||||||
|
2. Phase 1 → Phase 3
|
||||||
|
3. Phase 3 → Phase 5
|
||||||
|
4. Phase 5 → Phase 6
|
||||||
|
5. Phase 1 → Phase 4
|
||||||
|
6. Phase 4 → Phase 8
|
||||||
|
|
||||||
|
**Parallel Phases** (can be done in parallel):
|
||||||
|
- Phase 2 and Phase 3 (after Phase 1)
|
||||||
|
- Phase 4 and Phase 5 (after Phase 1/3)
|
||||||
|
- Phase 6 and Phase 7 (after Phase 5)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## KEY SUCCESS CRITERIA
|
||||||
|
|
||||||
|
- ✅ All existing features continue working
|
||||||
|
- ✅ Credit system is universal and consistent
|
||||||
|
- ✅ Automation system is functional
|
||||||
|
- ✅ Site Builder creates and deploys sites
|
||||||
|
- ✅ Sites Renderer hosts sites
|
||||||
|
- ✅ Linker and Optimizer improve content
|
||||||
|
- ✅ Multi-destination publishing works
|
||||||
|
- ✅ Module settings enable/disable modules
|
||||||
|
- ✅ Global component library (no duplicates)
|
||||||
|
- ✅ Multiple layout options for sites
|
||||||
|
- ✅ Site management UI (CMS) functional
|
||||||
|
- ✅ All content types supported
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## DOCUMENT STRUCTURE
|
||||||
|
|
||||||
|
Each phase document includes:
|
||||||
|
1. **Overview** - Goals, objectives, principles
|
||||||
|
2. **Detailed Tasks** - All tasks with files, dependencies, implementation details
|
||||||
|
3. **Code Examples** - Implementation examples where relevant
|
||||||
|
4. **Testing & Validation** - Test cases and success criteria
|
||||||
|
5. **Implementation Checklist** - Complete checklist of all tasks
|
||||||
|
6. **Risk Assessment** - Risks and mitigation strategies
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## USAGE
|
||||||
|
|
||||||
|
1. **Start with Phase 0** - Foundation must be completed first
|
||||||
|
2. **Follow Dependencies** - Complete dependencies before starting a phase
|
||||||
|
3. **Use Checklists** - Each document has a complete implementation checklist
|
||||||
|
4. **Test Thoroughly** - Each phase includes testing requirements
|
||||||
|
5. **Update Documentation** - Update main docs as phases complete
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Last Updated**: 2025-01-XX
|
||||||
|
|
||||||
Reference in New Issue
Block a user