# SVG Template Refactoring Plan

## ✅ STATUS: COMPLETED

**Completion Date**: 2025-11-27
**Final Architecture**: Template-only SVG generation with no fallback mechanisms

All phases have been successfully completed:
- ✅ Phase 1: Template-v2.svg files created and working
- ✅ Phase 2: Template-based generation fully implemented
- ✅ Phase 3: Old templates removed, hardcoded generation eliminated
- ✅ Comprehensive test coverage: 40+ tests (unit + integration)
- ✅ Documentation complete (see TEMPLATE_V2_GUIDE.md)

---

## Original Architecture Problems (Resolved)

### The Issue
While `template.svg` files exist in `example/` and `my-project/`, they only contain:
- Outer SVG wrapper with styling
- Two macros: `{{MONTHS}}` and `{{LANES}}`

The actual SVG generation is hardcoded in `generator.js`:
- **Lines 40-69**: Month grid generation (lines, labels, styling)
- **Lines 78-129**: Lane generation (backgrounds, labels, task items)

This makes templates non-editable in SVG tools - users can only change colors/styling in the wrapper, not the actual timeline structure.

## Goals

1. **Move SVG structure to templates**: Extract hardcoded SVG patterns from JavaScript to template files
2. **Use placeholders for dynamic data**: Replace actual values with `{{VARIABLE}}` placeholders
3. **Make templates editable**: Users should be able to open templates in Inkscape/Adobe Illustrator and modify the timeline layout
4. **Maintain flexibility**: Keep the ability to handle varying numbers of months, lanes, and items

## Proposed Template Structure

### Month Template Section
Instead of generating months in JS, the template should contain a **sample month element** with placeholders:

```svg
<!-- Sample month element - will be cloned for each month -->
<g class="month-template" id="month-template">
  <line x1="{{MONTH_X}}" y1="{{GRID_TOP}}" x2="{{MONTH_X}}" y2="{{GRID_BOTTOM}}"
        stroke="#E3E8EF" />
  <text x="{{MONTH_X}}" y="{{MONTH_Y}}" fill="#5C6B7A" font-size="12">
    {{MONTH_LABEL}}
  </text>
</g>
```

### Lane Template Section
Similarly, lanes should be defined once:

```svg
<!-- Sample lane element - will be cloned for each lane -->
<g class="lane-template" id="lane-template">
  <rect x="{{LANE_X}}" y="{{LANE_Y}}" width="{{LANE_WIDTH}}" height="{{LANE_HEIGHT}}"
        fill="#FFFFFF" stroke="#E3E8EF" rx="10" />
  <text x="{{LABEL_X}}" y="{{LABEL_Y}}" fill="#0B1F3B" font-size="14" font-weight="600">
    {{LANE_NAME}}
  </text>
</g>
```

### Task Item Template
Task items within lanes:

```svg
<!-- Sample task item - will be cloned for each task -->
<g class="task-template" id="task-template">
  <circle cx="{{TASK_X}}" cy="{{TASK_Y}}" r="5" fill="#0A4D8C" />
  <text x="{{TEXT_X}}" y="{{TEXT_Y}}" font-size="12" fill="#0B1F3B">
    <tspan class="item-id">{{TASK_ID}}: </tspan>
    <tspan class="item-title">{{TASK_TITLE}}</tspan>
  </text>
</g>
```

## Generator Refactoring

The `generator.js` should:

1. **Load and parse template**: Read template SVG
2. **Extract template elements**: Find elements with `id="*-template"`
3. **Clone and populate**: For each data item, clone the template and replace placeholders
4. **Position elements**: Calculate positions based on layout constants
5. **Inject into template**: Replace `{{MONTHS}}` and `{{LANES}}` macros with generated content

## Variables Dictionary

### Layout Constants
- `{{GRID_LEFT}}`, `{{GRID_TOP}}`, `{{GRID_BOTTOM}}` - Grid boundaries
- `{{MONTH_WIDTH}}` - Width of each month column
- `{{LANE_HEIGHT}}` - Height of each lane row
- `{{LANE_GAP}}` - Spacing between lanes

### Month Variables
- `{{MONTH_X}}` - X position
- `{{MONTH_Y}}` - Y position for label
- `{{MONTH_LABEL}}` - Month name (e.g., "Jan 25")

### Lane Variables
- `{{LANE_X}}`, `{{LANE_Y}}` - Lane position
- `{{LANE_WIDTH}}`, `{{LANE_HEIGHT}}` - Lane dimensions
- `{{LANE_NAME}}` - Lane/Epic name
- `{{LABEL_X}}`, `{{LABEL_Y}}` - Label position

### Task Variables
- `{{TASK_X}}`, `{{TASK_Y}}` - Task marker position
- `{{TEXT_X}}`, `{{TEXT_Y}}` - Text position
- `{{TASK_ID}}` - Task ID (e.g., "T-1")
- `{{TASK_TITLE}}` - Task title

## Migration Strategy

### Phase 1: Extract to Simple Templates
1. Create new `template-v2.svg` files with template elements
2. Update generator to use template-based approach
3. Keep existing templates as fallback
4. Test with both approaches

### Phase 2: Enhance Template Editing
1. Add template validation
2. Document template variables
3. Create template editing guide
4. Provide example templates with different layouts

### Phase 3: Remove Hardcoded SVG
1. Migrate existing templates to new format
2. Remove hardcoded SVG generation
3. Update tests
4. Update documentation

## Test Updates Needed

- Tests for template parsing and validation
- Tests for variable substitution
- Tests for template cloning logic
- Integration tests with real templates
- Tests for backward compatibility with old templates

## Benefits

1. **User-editable templates**: Can modify in any SVG editor
2. **Visual template design**: See actual layout while editing
3. **Reusable patterns**: Template elements can be copied/modified
4. **Separation of concerns**: Presentation (SVG) vs. logic (JS)
5. **Easier customization**: Change fonts, colors, shapes without touching code

## Risks

- **Complexity**: More complex generator logic
- **Performance**: Template parsing and cloning overhead
- **Compatibility**: Need to support both old and new templates
- **Testing**: More edge cases to test

## Final Implementation Summary

### Code Changes
1. **generator.js**: Reduced from 326 to 210 lines (-36%)
   - Removed `generateHardcoded()` method entirely (~125 lines)
   - Added `validateTemplate()` for strict validation
   - Simplified `generate()` to call `generateFromTemplates()` directly
   - Updated `extractTemplate()` to throw errors instead of returning null

2. **Templates**: Removed old v1 templates
   - Deleted `example/template.svg`
   - Deleted `my-project/template.svg`
   - Updated project.json files to reference template-v2.svg exclusively

3. **Tests**: Refactored for template-only architecture
   - **engine.test.js**: 16 tests kept (unchanged)
   - **generator.test.js**: 23 tests (removed 11 hardcoded tests, kept template tests)
   - **integration.test.js**: 15 comprehensive e2e tests (added 8 new scenarios)
   - **testHelpers.js**: Updated with template-v2 helpers, malformed template generator, large dataset generator

### Test Coverage
**Unit Tests (39 total)**:
- 16 engine business logic tests
- 23 generator tests (3 escapeXml, 5 validation, 3 extraction, 4 placeholder, 8 generation)

**Integration Tests (15 total)**:
- Basic e2e workflow
- CSV override handling
- Large dataset (60+ items)
- Date range edge cases (24+ months)
- Special character handling
- Empty CSV handling
- Malformed template error handling (3 tests)
- Template styling preservation
- File upload handling (2 tests)
- Export functionality (2 tests)

### Architecture Benefits Achieved
1. **Single clear path**: Template-v2.svg format is required, no fallbacks
2. **Clear error messages**: Immediate feedback when templates are malformed
3. **Reduced complexity**: No branching logic, no backward compatibility code
4. **Visual editing**: Users can edit templates in SVG tools
5. **Maintainability**: ~235 lines of code removed, simpler architecture

### Breaking Changes
- Old template.svg format no longer supported
- Must use template-v2.svg with proper `<g id="*-template">` elements
- No silent fallbacks - errors thrown immediately

### Migration Notes
All existing projects already had template-v2.svg files created during Phase 1, so migration was seamless with only project.json updates needed.
