# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Overview

TimelineSvg is a browser-based system for generating multi-lane timelines as SVG graphics from CSV data. It processes everything client-side using vanilla JavaScript, with no build pipeline or backend required. The system uses a template-based architecture where SVG templates define the visual appearance and data is mapped through a project configuration file.

**Troubleshooting**: If you encounter issues during development, check `TROUBLESHOOTING.md` first. It contains solutions for common problems including npm installation failures, CORS errors, template validation issues, and more.

## Commands

### Installation
```bash
make install             # Install development dependencies
```

**Important - Node.js v24 on WSL**: If you encounter `ERR_SSL_CIPHER_OPERATION_FAILED` errors during `npm install`, this is a known issue with Node.js v24 and OpenSSL 3.x in WSL environments. The Makefile automatically applies the workaround using `NODE_OPTIONS="--openssl-legacy-provider"`. If installing manually without make:
```bash
export NODE_OPTIONS="--openssl-legacy-provider" && npm install
```

### Testing
```bash
npm test                  # Run all tests once
npm run test:watch       # Run tests in watch mode
npm run test:coverage    # Generate coverage report
npm run test:ui          # Run Vitest UI
```

The project uses Vitest with jsdom for testing. Tests are located in `/test/` and cover the generator, engine, and integration scenarios.

### Development
```bash
make serve               # Start local development server (auto-detects Python/npx)
# or manually:
python3 -m http.server 8000

# Then open http://localhost:8000
```

The application must be served via HTTP (not opened as file://) due to CORS restrictions when loading CSV, CSS, and SVG files.

### Distribution
```bash
make dist                # Build distribution package in dist/
make dist-zip            # Build distribution and create archive
```

The distribution package includes:
- All runtime files (HTML, JS, CSS)
- Example projects (example/, example-1/, my-project/)
- Documentation (README.md, TEMPLATE_V2_GUIDE.md, TROUBLESHOOTING.md)
- Startup scripts for Windows (start-server.bat) and Linux/Mac (start-server.sh)

Use this to deploy the application to Windows or other environments. The distribution is self-contained and requires only a web browser and Python (for the local server).

**For Windows deployment from WSL**: See `WINDOWS_USAGE.md` for detailed instructions on building the distribution in WSL, transferring to Windows, and running the application on Windows OS.

## Architecture

### Core Components

**1. engine.js** - Application controller and data loading
- Manages project configuration loading (auto-loads from `binect/`, `my-project/`, or `example/` folders)
- Handles CSV parsing using PapaParse library
- Manages file uploads and overrides
- Provides debug information panel
- Controls view modes (internal vs external)
- Implements zoom functionality for SVG viewer

**2. generator.js** - Timeline rendering engine
- Implements template-v2 architecture
- Extracts template elements from `<defs>` section: `month-template`, `lane-template`, `item-template`
- Replaces placeholders with calculated values and CSV data
- Handles layout calculations (positioning months, lanes, items)
- Generates final SVG by cloning templates and replacing `{{MONTHS}}` and `{{LANES}}` macros

**3. index.html** - UI and browser entry point
- Loads PapaParse from CDN for CSV parsing
- Provides file upload controls
- Contains viewer with zoom controls
- Shows debug information panel with field mappings and data preview

### Data Flow

1. **Project Configuration** (`project.json`) defines:
   - Data source (CSV file path)
   - Stylesheet (CSS file path)
   - SVG template (template-v2.svg file path)
   - Field mappings (CSV columns → timeline fields)
   - Optional placeholder mappings (override default `ITEM_*` convention)
   - Settings (timeline duration, etc.)

2. **CSV Data** is parsed and mapped to timeline items:
   - Required fields: `id`, `title`, `due`, `lane`
   - Date parsing supports multiple formats: `YYYY-MM-DD`, `YYYY/MM/DD`, `DD.MM.YYYY`
   - Items without valid title or due date are filtered out

3. **Template System** (template-v2 architecture):
   - Templates are standard SVG files editable in Inkscape, Illustrator, or Figma
   - Three required template elements in `<defs>` section:
     - `<g id="month-template">` - Defines month column rendering
     - `<g id="lane-template">` - Defines lane/epic row rendering
     - `<g id="item-template">` - Defines individual task rendering
   - Templates contain placeholders like `{{MONTH_X}}`, `{{LANE_NAME}}`, `{{ITEM_TITLE}}`
   - Generator extracts templates, replaces placeholders, and injects into main SVG

4. **Placeholder System**:
   - Layout placeholders: `{{MONTH_X}}`, `{{LANE_Y}}`, `{{ITEM_X}}`, etc. (calculated by generator)
   - Data placeholders: Automatically created from CSV columns using `ITEM_{PROPERTY}` convention
   - Custom mappings: Use `placeholderMapping` in project.json to override default names (e.g., `TASK_ID` instead of `ITEM_ID`)
   - All CSV properties (except `due`) are available as placeholders in templates

### Key Concepts

**Template-v2 Architecture**: The current system (migrated from older macro-based approach) uses proper SVG template elements that are cloned and customized. This makes templates more maintainable and editable in visual SVG editors.

**Field Mapping**: CSV columns don't need to match exact names. The `fieldMapping` object in project.json maps CSV column names to the internal timeline model:
```json
{
  "fieldMapping": {
    "id": "ID",           // CSV column "ID" maps to item.id
    "title": "Title",     // CSV column "Title" maps to item.title
    "lane": "Lane",       // CSV column "Lane" maps to item.lane
    "due": ["Due"]        // CSV column "Due" maps to item.due (array for fallbacks)
  }
}
```

**Placeholder Mapping**: When templates use non-standard placeholder names (common when migrating from other tools), use `placeholderMapping` to override the default `ITEM_*` convention:
```json
{
  "placeholderMapping": {
    "id": "TASK_ID",       // Use {{TASK_ID}} instead of {{ITEM_ID}}
    "title": "TASK_NAME"   // Use {{TASK_NAME}} instead of {{ITEM_TITLE}}
  }
}
```

**Layout Constants** (generator.js:41-45): Control overall positioning
- `left: 220` - Left margin
- `top: 140` - Top margin
- `monthWidth: 120` - Width of each month column
- `laneHeight: 80` - Height of each lane/epic row
- `laneGap: 16` - Vertical gap between lanes

**View Modes**:
- Internal view: Shows item IDs (for development/review)
- External view: Hides item IDs (for presentations/exports)

**Project Loading Methods**:
- Auto-load: When served via HTTP, attempts to load from binect/, my-project/, or example/ folders
- Folder picker: User selects entire project folder - all files load automatically (uses webkitdirectory attribute)
- Individual files: User manually uploads project.json, then CSV/SVG/CSS separately

The folder picker was added to solve the browser security limitation where uploading a single project.json doesn't allow automatic access to other files in the same directory.

## Project Structure

```
/
├── index.html              # Main application entry point
├── engine.js               # Application controller & data loading
├── generator.js            # SVG generation & template processing
├── vitest.config.js        # Test configuration
├── test/
│   ├── setup.js           # Test environment setup
│   ├── generator.test.js  # Generator unit tests
│   ├── engine.test.js     # Engine unit tests
│   └── integration.test.js # End-to-end tests
├── example/               # Example project
│   ├── project.json       # Project configuration
│   ├── sample.csv         # Sample data
│   ├── style.css          # Custom styling
│   └── template-v2.svg    # SVG template
└── TEMPLATE_V2_GUIDE.md   # Comprehensive template documentation
```

## Testing Guidelines

When writing tests:
- Use Vitest's `describe()` and `it()` structure
- Mock browser APIs (localStorage, fetch) using jsdom
- Test template validation separately from rendering
- Test date parsing for all supported formats
- Test field mapping edge cases (missing fields, null values)
- Integration tests should cover full project loading → CSV parsing → SVG generation flow

## Important Implementation Details

**Template Validation** (generator.js:54-70): Always validate templates before attempting to generate SVG. Check for all three required template IDs.

**Template Extraction** (generator.js:73-82): Use regex to extract template elements from `<defs>`. Throws error if extraction fails (indicates malformed template).

**XML Escaping** (generator.js:216-223): Always escape user data (titles, lane names) when injecting into SVG to prevent malformed XML.

**Date Parsing** (engine.js:385-408): Supports multiple formats with fallback to `new Date()`. Returns null for invalid dates, which causes items to be filtered out.

**Project Base Path Resolution** (engine.js:148-157): Relative paths in project.json are resolved relative to the project folder (e.g., `example/`). This enables projects to reference their own resources.

**Debug Information Panel**: Shows field mappings, template placeholders, and CSV preview to help diagnose configuration issues. Automatically displayed when project loads.

## Common Development Tasks

When adding new placeholder types:
1. Add to placeholder documentation in TEMPLATE_V2_GUIDE.md
2. Update generator.js placeholder replacement logic if needed
3. Update example templates to demonstrate usage
4. Add tests for the new placeholder type

When modifying layout:
1. Update layout constants in generator.js:41-45
2. Update placeholder value calculations in generateFromTemplates()
3. Update TEMPLATE_V2_GUIDE.md with new dimensions
4. Regenerate example SVGs to verify

When adding CSV field support:
1. Update fieldMapping documentation in README.md
2. Update example project.json files
3. Add to processCsv() in engine.js
4. Update generator to expose as placeholder
5. Add tests for field mapping

## Template Development

See TEMPLATE_V2_GUIDE.md for comprehensive template creation and customization documentation. Key points:

- Templates must have all three required `<g id="*-template">` elements in `<defs>`
- Use `style="display:none"` on template elements to hide them
- All placeholders use `{{UPPERCASE_NAME}}` format
- Templates are standard SVG - edit in any SVG editor
- Test templates by loading them in the UI and checking debug panel

## Migration Notes

The codebase uses template-v2 architecture. Legacy template-v1 (macro-based) is deprecated. When working with old projects:
- Convert macro-based templates to template-v2 format
- Move template definitions into `<defs>` section
- Update placeholder names to match conventions
- Use `placeholderMapping` if preserving legacy placeholder names
