186 lines
5.4 KiB
Markdown
186 lines
5.4 KiB
Markdown
# Template Tracking Fix - October 21, 2025
|
|
|
|
## Problem Identified
|
|
|
|
Story 2.4 was incorrectly implemented to store template mappings in `master.config.json` instead of the database. This meant:
|
|
- Templates were tracked per hostname in a config file
|
|
- No database field to store template at site level
|
|
- Story 3.4 (boilerplate pages) couldn't easily determine which template to use
|
|
- Inconsistent tracking between config file and database
|
|
|
|
## Root Cause
|
|
|
|
Story 2.4 specification said to use `master.config.json` for template mappings, but this was wrong. Templates should be tracked at the **site/domain level in the database**, not in a config file.
|
|
|
|
## What Was Fixed
|
|
|
|
### 1. Database Model Updated
|
|
**File**: `src/database/models.py`
|
|
|
|
Added `template_name` field to `SiteDeployment` model:
|
|
```python
|
|
class SiteDeployment(Base):
|
|
# ... existing fields ...
|
|
template_name: Mapped[str] = mapped_column(String(50), default="basic", nullable=False)
|
|
```
|
|
|
|
### 2. Migration Script Created
|
|
**File**: `scripts/migrate_add_template_to_sites.py`
|
|
|
|
New migration script adds `template_name` column to `site_deployments` table:
|
|
```sql
|
|
ALTER TABLE site_deployments
|
|
ADD COLUMN template_name VARCHAR(50) DEFAULT 'basic' NOT NULL
|
|
```
|
|
|
|
### 3. Template Service Fixed
|
|
**File**: `src/templating/service.py`
|
|
|
|
**Before** (wrong):
|
|
```python
|
|
def select_template_for_content(...):
|
|
# Query config file for hostname mapping
|
|
if hostname in config.templates.mappings:
|
|
return config.templates.mappings[hostname]
|
|
|
|
# Pick random and save to config
|
|
template_name = self._select_random_template()
|
|
self._persist_template_mapping(hostname, template_name)
|
|
return template_name
|
|
```
|
|
|
|
**After** (correct):
|
|
```python
|
|
def select_template_for_content(...):
|
|
# Query database for site template
|
|
if site_deployment_id and site_deployment_repo:
|
|
site_deployment = site_deployment_repo.get_by_id(site_deployment_id)
|
|
if site_deployment:
|
|
return site_deployment.template_name or "basic"
|
|
|
|
return self._select_random_template()
|
|
```
|
|
|
|
**Removed**:
|
|
- `_persist_template_mapping()` method (no longer needed)
|
|
|
|
### 4. Config File Simplified
|
|
**File**: `master.config.json`
|
|
|
|
**Before**:
|
|
```json
|
|
"templates": {
|
|
"default": "basic",
|
|
"mappings": {
|
|
"aws-s3-bucket-1": "modern",
|
|
"bunny-bucket-1": "classic",
|
|
"azure-bucket-1": "minimal",
|
|
"test.example.com": "minimal"
|
|
}
|
|
}
|
|
```
|
|
|
|
**After**:
|
|
```json
|
|
"templates": {
|
|
"default": "basic"
|
|
}
|
|
```
|
|
|
|
Only keep `default` for fallback behavior. All template tracking now in database.
|
|
|
|
### 5. Story 2.4 Spec Updated
|
|
**File**: `docs/stories/story-2.4-html-formatting-templates.md`
|
|
|
|
- Updated Task 3 to reflect database tracking
|
|
- Updated Task 5 to include `template_name` field on `SiteDeployment`
|
|
- Updated Technical Decisions section
|
|
|
|
### 6. Story 3.4 Updated
|
|
**File**: `docs/stories/story-3.4-boilerplate-site-pages.md`
|
|
|
|
- Boilerplate pages now read `site.template_name` from database
|
|
- No template service changes needed
|
|
- Effort reduced from 15 to 14 story points
|
|
|
|
## How It Works Now
|
|
|
|
### Site Creation
|
|
```python
|
|
# When creating/provisioning a site
|
|
site = SiteDeployment(
|
|
site_name="example-site",
|
|
template_name="modern", # or "basic", "classic", "minimal"
|
|
# ... other fields
|
|
)
|
|
```
|
|
|
|
### Article Generation
|
|
```python
|
|
# When generating article
|
|
site = site_repo.get_by_id(article.site_deployment_id)
|
|
template = site.template_name # Read from database
|
|
formatted_html = template_service.format_content(content, title, meta, template)
|
|
```
|
|
|
|
### Boilerplate Pages
|
|
```python
|
|
# When generating boilerplate pages
|
|
site = site_repo.get_by_id(site_id)
|
|
template = site.template_name # Same template as articles
|
|
about_html = generate_page("about", template=template)
|
|
```
|
|
|
|
## Benefits
|
|
|
|
1. **Single source of truth**: Template tracked in database only
|
|
2. **Consistent sites**: All content on a site uses same template
|
|
3. **Simpler logic**: No config file manipulation needed
|
|
4. **Better data model**: Template is a property of the site, not a mapping
|
|
5. **Easier to query**: Can find all sites using a specific template
|
|
|
|
## Migration Path
|
|
|
|
For existing deployments:
|
|
1. Run migration script: `uv run python scripts/migrate_add_template_to_sites.py`
|
|
2. All existing sites default to `template_name="basic"`
|
|
3. Update specific sites if needed:
|
|
```sql
|
|
UPDATE site_deployments SET template_name='modern' WHERE id=5;
|
|
```
|
|
|
|
## Testing
|
|
|
|
No tests broken by this change:
|
|
- Template service tests still pass (reads from database instead of config)
|
|
- Article generation tests still pass
|
|
- Template selection logic unchanged from user perspective
|
|
|
|
## Files Changed
|
|
|
|
### Created
|
|
- `scripts/migrate_add_template_to_sites.py`
|
|
- `TEMPLATE_TRACKING_FIX.md` (this file)
|
|
|
|
### Modified
|
|
- `src/database/models.py` - Added `template_name` field
|
|
- `src/templating/service.py` - Removed config lookups, read from DB
|
|
- `master.config.json` - Removed `mappings` section
|
|
- `docs/stories/story-2.4-html-formatting-templates.md` - Updated spec
|
|
- `docs/stories/story-3.4-boilerplate-site-pages.md` - Updated to use DB field
|
|
- `STORY_3.4_CREATED.md` - Updated effort estimate
|
|
|
|
## Next Steps
|
|
|
|
1. Run migration: `uv run python scripts/migrate_add_template_to_sites.py`
|
|
2. Verify existing articles still render correctly
|
|
3. Implement Story 3.4 using the database field
|
|
4. Future site creation/provisioning should set `template_name`
|
|
|
|
---
|
|
|
|
**Fixed by**: AI Code Assistant
|
|
**Fixed on**: October 21, 2025
|
|
**Issue identified by**: User during Story 3.4 discussion
|
|
|