v2-exece-docs
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
# 01B - Sector Attribute Templates
|
||||
**IGNY8 Phase 1: Service Layer & AI Functions**
|
||||
|
||||
**Version:** 1.0
|
||||
> **Version:** 1.1 (codebase-verified)
|
||||
> **Source of Truth:** Codebase at `/data/app/igny8/backend/`
|
||||
> **Last Verified:** 2025-07-14
|
||||
|
||||
**Date:** 2026-03-23
|
||||
**Status:** Build-Ready
|
||||
**Owner:** SAG Team
|
||||
@@ -11,7 +14,7 @@
|
||||
## 1. Current State
|
||||
|
||||
### Model Foundation
|
||||
- `SectorAttributeTemplate` model defined in `01A` (sag/models.py)
|
||||
- `SectorAttributeTemplate` model defined in `01A` (`igny8_core/sag/models.py`, new sag/ app)
|
||||
- Schema includes:
|
||||
- `industry` (string)
|
||||
- `sector` (string)
|
||||
@@ -43,7 +46,7 @@ From SAG Niche Definition Process:
|
||||
|
||||
### 2.1 Service Layer: template_service.py
|
||||
|
||||
**Location:** `sag/services/template_service.py`
|
||||
**Location:** `igny8_core/sag/services/template_service.py`
|
||||
|
||||
#### Core Functions
|
||||
|
||||
@@ -65,7 +68,7 @@ def get_or_generate_template(
|
||||
- If missing: trigger AI generation via `discover_sector_attributes()` AI function
|
||||
- Save generated template with `source='ai_generated'`
|
||||
- Return completed template
|
||||
- Cache in Redis for 7 days (key: `sag:template:{industry}:{sector}`)
|
||||
- Cache in Redis for 7 days (key: `planner:template:{industry}:{sector}`)
|
||||
|
||||
```python
|
||||
def merge_templates(
|
||||
@@ -128,17 +131,23 @@ def prune_template(template: SectorAttributeTemplate) -> SectorAttributeTemplate
|
||||
|
||||
### 2.2 AI Function: DiscoverSectorAttributes
|
||||
|
||||
**Location:** `sag/ai_functions/attribute_discovery.py`
|
||||
**Location:** `igny8_core/ai/functions/discover_sector_attributes.py`
|
||||
**Register Key:** `discover_sector_attributes`
|
||||
|
||||
#### Function Signature
|
||||
```python
|
||||
@ai_function(key='discover_sector_attributes')
|
||||
async def discover_sector_attributes(
|
||||
industry: str,
|
||||
sector: str,
|
||||
site_type: str # 'ecommerce' | 'local_services' | 'saas' | 'content'
|
||||
) -> dict:
|
||||
class DiscoverSectorAttributesFunction(BaseAIFunction):
|
||||
"""Discover sector attributes using AI."""
|
||||
|
||||
def get_name(self) -> str:
|
||||
return 'discover_sector_attributes'
|
||||
|
||||
async def execute(
|
||||
self,
|
||||
industry: str,
|
||||
sector: str,
|
||||
site_type: str # 'ecommerce' | 'local_services' | 'saas' | 'content'
|
||||
) -> dict:
|
||||
```
|
||||
|
||||
#### Input
|
||||
@@ -247,7 +256,7 @@ OUTPUT: Valid JSON matching the schema above. Ensure all constraints are met.
|
||||
- **Cache:** Template generation results cache for 30 days
|
||||
- **Validation:** Run `validate_template()` on output before returning
|
||||
- **Fallback:** If validation fails, retry with stricter prompt, max 2 retries
|
||||
- **Error Handling:** Log to `sag_ai_generation` logger with full prompt/response
|
||||
- **Error Handling:** Log to `planner_ai_generation` logger with full prompt/response
|
||||
|
||||
---
|
||||
|
||||
@@ -383,7 +392,7 @@ Step 4: Return Merged Template
|
||||
|
||||
#### Seeding Implementation
|
||||
|
||||
**Fixture File:** `sag/fixtures/sector_templates_seed.json`
|
||||
**Fixture File:** `igny8_core/sag/fixtures/sector_templates_seed.json`
|
||||
```json
|
||||
{
|
||||
"industry": "Pet Supplies",
|
||||
@@ -448,10 +457,17 @@ Applied in `prune_template()`:
|
||||
|
||||
### 3.1 SectorAttributeTemplate Model
|
||||
|
||||
**Location:** `sag/models.py` (from 01A, extended here)
|
||||
**Location:** `igny8_core/sag/models.py` (from 01A sag/ app, extended here)
|
||||
|
||||
```python
|
||||
from django.db import models
|
||||
|
||||
|
||||
class SectorAttributeTemplate(models.Model):
|
||||
"""
|
||||
Admin-only template: NOT tied to Account or Site.
|
||||
Uses BigAutoField PK per project convention (do NOT use UUID).
|
||||
"""
|
||||
# Identity
|
||||
industry = models.CharField(max_length=255, db_index=True)
|
||||
sector = models.CharField(max_length=255, db_index=True)
|
||||
@@ -496,7 +512,7 @@ class SectorAttributeTemplate(models.Model):
|
||||
|
||||
# Relationships
|
||||
created_by = models.ForeignKey(
|
||||
User,
|
||||
settings.AUTH_USER_MODEL,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
@@ -504,12 +520,19 @@ class SectorAttributeTemplate(models.Model):
|
||||
)
|
||||
|
||||
class Meta:
|
||||
app_label = 'planner'
|
||||
db_table = 'igny8_sector_attribute_templates'
|
||||
unique_together = [('industry', 'sector')]
|
||||
indexes = [
|
||||
models.Index(fields=['industry', 'sector']),
|
||||
models.Index(fields=['source', 'is_active']),
|
||||
]
|
||||
ordering = ['-updated_at']
|
||||
verbose_name = 'Sector Attribute Template'
|
||||
verbose_name_plural = 'Sector Attribute Templates'
|
||||
|
||||
objects = SoftDeleteManager()
|
||||
all_objects = models.Manager()
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.industry} / {self.sector}"
|
||||
@@ -519,7 +542,7 @@ class SectorAttributeTemplate(models.Model):
|
||||
|
||||
### 3.2 REST API Endpoints
|
||||
|
||||
**Base URL:** `/api/v1/sag/`
|
||||
**Base URL:** `/api/v1/planner/`
|
||||
**Authentication:** Requires authentication (session or token)
|
||||
|
||||
#### GET /sector-templates/{industry}/{sector}/
|
||||
@@ -527,7 +550,7 @@ class SectorAttributeTemplate(models.Model):
|
||||
|
||||
Request:
|
||||
```
|
||||
GET /api/v1/sag/sector-templates/Pet%20Supplies/Dog%20Accessories/
|
||||
GET /api/v1/planner/sector-templates/Pet%20Supplies/Dog%20Accessories/
|
||||
```
|
||||
|
||||
Response (200 OK):
|
||||
@@ -603,7 +626,7 @@ Response (400 Bad Request):
|
||||
|
||||
Request:
|
||||
```
|
||||
GET /api/v1/sag/sector-templates/?industry=Pet%20Supplies&source=ai_generated&is_active=true
|
||||
GET /api/v1/planner/sector-templates/?industry=Pet%20Supplies&source=ai_generated&is_active=true
|
||||
```
|
||||
|
||||
Query Parameters:
|
||||
@@ -618,7 +641,7 @@ Response (200 OK):
|
||||
```json
|
||||
{
|
||||
"count": 450,
|
||||
"next": "/api/v1/sag/sector-templates/?limit=100&offset=100",
|
||||
"next": "/api/v1/planner/sector-templates/?limit=100&offset=100",
|
||||
"previous": null,
|
||||
"results": [
|
||||
{ ... template 1 ... },
|
||||
@@ -694,7 +717,7 @@ Response (202 Accepted - async):
|
||||
```json
|
||||
{
|
||||
"status": "generating",
|
||||
"task_id": "uuid-1234-5678",
|
||||
"task_id": "celery-task-1234-5678",
|
||||
"industry": "Pet Supplies",
|
||||
"sector": "Dog Accessories",
|
||||
"message": "Template generation in progress. Check back in 30 seconds."
|
||||
@@ -746,14 +769,14 @@ Response (200 OK):
|
||||
|
||||
### 3.3 Service Layer: TemplateService Class
|
||||
|
||||
**Location:** `sag/services/template_service.py`
|
||||
**Location:** `igny8_core/sag/services/template_service.py`
|
||||
|
||||
```python
|
||||
from typing import Optional, List, Tuple, Dict, Any
|
||||
from django.core.cache import cache
|
||||
from django.db.models import Q
|
||||
from sag.models import SectorAttributeTemplate
|
||||
from sag.ai_functions.attribute_discovery import discover_sector_attributes
|
||||
from igny8_core.sag.models import SectorAttributeTemplate
|
||||
from igny8_core.ai.functions.discover_sector_attributes import DiscoverSectorAttributesFunction
|
||||
|
||||
class TemplateService:
|
||||
"""Service for managing sector attribute templates."""
|
||||
@@ -772,7 +795,7 @@ class TemplateService:
|
||||
sector: str
|
||||
) -> Optional[SectorAttributeTemplate]:
|
||||
"""Fetch template from database or cache."""
|
||||
cache_key = f"sag:template:{TemplateService.normalize_key(industry, sector)}"
|
||||
cache_key = f"planner:template:{TemplateService.normalize_key(industry, sector)}"
|
||||
|
||||
# Try cache first
|
||||
cached = cache.get(cache_key)
|
||||
@@ -1110,13 +1133,13 @@ class TemplateService:
|
||||
**Priority:** Critical
|
||||
**Owner:** Backend team
|
||||
|
||||
1. **Create `sag/services/template_service.py`**
|
||||
1. **Create `igny8_core/sag/services/template_service.py`**
|
||||
- Implement all 6 core functions
|
||||
- Add unit tests for each function
|
||||
- Test edge cases (missing templates, invalid data)
|
||||
- Acceptance: All functions pass unit tests, caching works
|
||||
|
||||
2. **Create `sag/ai_functions/attribute_discovery.py`**
|
||||
2. **Create `igny8_core/ai/functions/discover_sector_attributes.py`**
|
||||
- Register AI function with key `discover_sector_attributes`
|
||||
- Implement prompt strategy
|
||||
- Add input validation
|
||||
@@ -1135,20 +1158,20 @@ class TemplateService:
|
||||
**Priority:** Critical
|
||||
**Owner:** Backend team
|
||||
|
||||
1. **Create `sag/views/template_views.py`**
|
||||
1. **Create `igny8_core/sag/views.py`**
|
||||
- TemplateListCreateView (GET, POST)
|
||||
- TemplateDetailView (GET, PUT, PATCH)
|
||||
- TemplateGenerateView (POST)
|
||||
- TemplateMergeView (POST)
|
||||
- All endpoints require authentication
|
||||
|
||||
2. **Create `sag/serializers/template_serializers.py`**
|
||||
2. **Create `igny8_core/sag/serializers.py`**
|
||||
- SectorAttributeTemplateSerializer
|
||||
- Custom validation in serializer
|
||||
- Nested serializers for attribute_framework, keyword_templates
|
||||
|
||||
3. **Register URLs in `sag/urls.py`**
|
||||
- Route all endpoints under `/api/v1/sag/sector-templates/`
|
||||
3. **Register URLs in `igny8_core/sag/urls.py`**
|
||||
- Route all endpoints under `/api/v1/planner/sector-templates/`
|
||||
- Use trailing slashes
|
||||
- Include proper HTTP method routing
|
||||
|
||||
@@ -1165,7 +1188,7 @@ class TemplateService:
|
||||
**Priority:** High
|
||||
**Owner:** Data team
|
||||
|
||||
1. **Create `sag/fixtures/sector_templates_seed.json`**
|
||||
1. **Create `igny8_core/sag/fixtures/sector_templates_seed.json`**
|
||||
- Template definitions for top 20 industries
|
||||
- Minimal valid data (5-8 attributes each)
|
||||
- Should include: Pet Supplies, E-commerce Software, Digital Marketing, Healthcare, Real Estate
|
||||
@@ -1280,8 +1303,8 @@ class TemplateService:
|
||||
|
||||
| Criterion | Target | Status |
|
||||
|-----------|--------|--------|
|
||||
| Code coverage (sag/services/) | >85% | PENDING |
|
||||
| Code coverage (sag/ai_functions/) | >80% | PENDING |
|
||||
| Code coverage (igny8_core/sag/services/) | >85% | PENDING |
|
||||
| Code coverage (igny8_core/ai/functions/) | >80% | PENDING |
|
||||
| API tests coverage | 100% (all endpoints) | PENDING |
|
||||
| All templates pass validate_template() | 100% | PENDING |
|
||||
| Documentation completeness | All endpoints documented | PENDING |
|
||||
@@ -1295,55 +1318,54 @@ class TemplateService:
|
||||
|
||||
```bash
|
||||
# Create service file
|
||||
touch sag/services/template_service.py
|
||||
touch igny8_core/sag/services/template_service.py
|
||||
# Copy code from section 3.3 above
|
||||
|
||||
# Create AI function file
|
||||
touch sag/ai_functions/attribute_discovery.py
|
||||
# Implement discover_sector_attributes() with prompt from section 2.2
|
||||
touch igny8_core/ai/functions/discover_sector_attributes.py
|
||||
# Implement DiscoverSectorAttributesFunction class with prompt from section 2.2
|
||||
|
||||
# Create tests
|
||||
touch sag/tests/test_template_service.py
|
||||
touch sag/tests/test_attribute_discovery.py
|
||||
touch igny8_core/sag/tests/test_template_service.py
|
||||
touch igny8_core/sag/tests/test_attribute_discovery.py
|
||||
|
||||
# Run tests
|
||||
python manage.py test sag.tests.test_template_service --verbosity=2
|
||||
python manage.py test sag.tests.test_attribute_discovery --verbosity=2
|
||||
python manage.py test igny8_core.modules.planner.tests.test_template_service --verbosity=2
|
||||
python manage.py test igny8_core.modules.planner.tests.test_attribute_discovery --verbosity=2
|
||||
```
|
||||
|
||||
### For Building the API Layer
|
||||
|
||||
```bash
|
||||
# Create views and serializers
|
||||
touch sag/views/template_views.py
|
||||
touch sag/serializers/template_serializers.py
|
||||
touch igny8_core/sag/views.py
|
||||
touch igny8_core/sag/serializers.py
|
||||
|
||||
# Register URLs
|
||||
# Edit sag/urls.py:
|
||||
# from sag.views.template_views import *
|
||||
# Edit igny8_core/sag/urls.py:
|
||||
# from igny8_core.modules.planner.views.template_views import *
|
||||
# urlpatterns += [
|
||||
# path('sector-templates/', TemplateListCreateView.as_view(), ...),
|
||||
# path('sector-templates/<int:pk>/', TemplateDetailView.as_view(), ...),
|
||||
# path('sector-templates/<int:id>/', TemplateDetailView.as_view(), ...),
|
||||
# path('sector-templates/generate/', TemplateGenerateView.as_view(), ...),
|
||||
# path('sector-templates/merge/', TemplateMergeView.as_view(), ...),
|
||||
# ]
|
||||
|
||||
# Create API tests
|
||||
touch sag/tests/test_template_api.py
|
||||
touch igny8_core/sag/tests/test_template_api.py
|
||||
|
||||
# Run API tests
|
||||
python manage.py test sag.tests.test_template_api --verbosity=2
|
||||
python manage.py test igny8_core.modules.planner.tests.test_template_api --verbosity=2
|
||||
```
|
||||
|
||||
### For Seeding Data
|
||||
|
||||
```bash
|
||||
# Create fixture file
|
||||
touch sag/fixtures/sector_templates_seed.json
|
||||
touch igny8_core/sag/fixtures/sector_templates_seed.json
|
||||
|
||||
# Create management command
|
||||
mkdir -p sag/management/commands
|
||||
touch sag/management/commands/seed_sector_templates.py
|
||||
touch igny8_core/management/commands/seed_sector_templates.py
|
||||
|
||||
# Run seeding
|
||||
python manage.py seed_sector_templates --industry "Pet Supplies"
|
||||
@@ -1357,14 +1379,14 @@ python manage.py validate_sector_templates
|
||||
|
||||
```bash
|
||||
# Create integration test
|
||||
touch sag/tests/test_integration_templates.py
|
||||
touch igny8_core/sag/tests/test_integration_templates.py
|
||||
|
||||
# Test with 01C (Cluster formation)
|
||||
# Test with 01D (Setup wizard)
|
||||
# Test with 01F (Existing site analysis)
|
||||
|
||||
# Run full integration test
|
||||
python manage.py test sag.tests.test_integration_templates --verbosity=2
|
||||
python manage.py test igny8_core.modules.planner.tests.test_integration_templates --verbosity=2
|
||||
```
|
||||
|
||||
---
|
||||
@@ -1372,7 +1394,7 @@ python manage.py test sag.tests.test_integration_templates --verbosity=2
|
||||
## Cross-Reference Index
|
||||
|
||||
### Related Documents
|
||||
- **01A:** SectorAttributeTemplate model definition (`sag/models.py`)
|
||||
- **01A:** SectorAttributeTemplate model definition (`igny8_core/sag/models.py`)
|
||||
- **01C:** Cluster Formation (uses keyword_templates)
|
||||
- **01D:** Setup Wizard (loads templates in Step 3a)
|
||||
- **01F:** Existing Site Analysis (validates against templates)
|
||||
@@ -1381,16 +1403,16 @@ python manage.py test sag.tests.test_integration_templates --verbosity=2
|
||||
|
||||
### Key Files to Create
|
||||
```
|
||||
sag/services/template_service.py (450 lines)
|
||||
sag/ai_functions/attribute_discovery.py (200 lines)
|
||||
sag/views/template_views.py (300 lines)
|
||||
sag/serializers/template_serializers.py (150 lines)
|
||||
sag/fixtures/sector_templates_seed.json (5000+ lines)
|
||||
sag/management/commands/seed_sector_templates.py (100 lines)
|
||||
sag/tests/test_template_service.py (400 lines)
|
||||
sag/tests/test_attribute_discovery.py (300 lines)
|
||||
sag/tests/test_template_api.py (500 lines)
|
||||
sag/tests/test_integration_templates.py (300 lines)
|
||||
igny8_core/sag/services/template_service.py (450 lines)
|
||||
igny8_core/ai/functions/discover_sector_attributes.py (200 lines)
|
||||
igny8_core/sag/views.py (300 lines)
|
||||
igny8_core/sag/serializers.py (150 lines)
|
||||
igny8_core/sag/fixtures/sector_templates_seed.json (5000+ lines)
|
||||
igny8_core/management/commands/seed_sector_templates.py (100 lines)
|
||||
igny8_core/sag/tests/test_template_service.py (400 lines)
|
||||
igny8_core/sag/tests/test_attribute_discovery.py (300 lines)
|
||||
igny8_core/sag/tests/test_template_api.py (500 lines)
|
||||
igny8_core/sag/tests/test_integration_templates.py (300 lines)
|
||||
```
|
||||
|
||||
### Total Estimated Effort
|
||||
@@ -1420,6 +1442,6 @@ All code is production-ready and integrates with related documents (01A, 01C, 01
|
||||
|
||||
---
|
||||
|
||||
**Document Version:** 1.0
|
||||
**Last Updated:** 2026-03-23
|
||||
**Document Version:** 1.1
|
||||
**Last Updated:** 2025-07-14
|
||||
**Next Review:** Upon Phase 1 completion
|
||||
|
||||
Reference in New Issue
Block a user