# Validate: Incremental Interactive HTML Deployment

> Reference for step-03d-validate.md — section 11-bis incremental HTML deploy after each module.

## Why Incremental?

The client doesn't have to wait until handoff to start reviewing.
While module 2 is being specified, the client can already give feedback on module 1.
Each incremental deployment OVERWRITES the previous HTML (latest state always).
The FINAL deployment at step-05 (handoff) will include consolidation and handoff data.

## Deployment Steps

**Source:** `html/ba-interactive.html` (relative to skill root = `~/.claude/skills/business-analyse/html/`)

**Destination:** `docs/business/{app}/business-analyse/v{version}/ba-interactive.html`

### Step 1: Read Sources

- Read the HTML template from skill directory
- Read the master feature.json (application level — now updated with current module status)
- Read EACH completed module's feature.json (including the one just specified)

### Step 2: Build FEATURE_DATA Object

> **Use the EXACT SAME mapping defined in step-05b-deploy.md and references/html-data-mapping.md.**
> The mapping is identical — the only difference is that `moduleSpecs` only includes completed modules.
> Modules not yet specified will NOT appear in `moduleSpecs` (their entry in `modules[]` will show `status: "pending"`).

Follow step-05 section 9d "Step 2: Build FEATURE_DATA object" for the complete mapping pseudocode:
- `metadata`, `cadrage`, `modules[]`, `dependencies[]` → from master feature.json
- `moduleSpecs[moduleCode]` → only for modules with status "specified" (completed so far)
- `consolidation` → empty `{ interactions: [], e2eFlows: [] }` (not yet consolidated)
- `handoff` → empty `{}` (not yet handed off)

### Step 3: Build EMBEDDED_ARTIFACTS Object

> **CRITICAL: Without EMBEDDED_ARTIFACTS, the Maquettes tab will show EMPTY mockups.**
> Use the EXACT SAME mapping defined in references/deploy-data-build.md and references/html-data-mapping.md.

Build EMBEDDED_ARTIFACTS with wireframes for completed modules only:

```javascript
const EMBEDDED_ARTIFACTS = {
  wireframes: {
    // FOR EACH completed module: extract wireframes with RENAMED fields
    // SAFETY NET: check BOTH key names (agent may use either)
    [moduleCode]: (moduleFeature.specification.uiWireframes || moduleFeature.specification.wireframes || []).map(wf => ({
      screen: wf.screen || wf.name || wf.title || wf.id || "",  // SAFETY NET: fallback name/title/id → screen
      section: wf.section || "",
      format: wf.mockupFormat || "ascii",   // RENAME: mockupFormat → format
      content: wf.mockup || wf.ascii || wf.content || "",  // SAFETY NET: mockup/ascii/content → content
      svgContent: null,  // Populated by Step 3-bis SVG generation
      description: wf.description || "",
      elements: wf.elements || [],
      actions: wf.actions || [],
      componentMapping: wf.componentMapping || [],
      layout: wf.layout || null,
      permissionsRequired: wf.permissionsRequired || []
    }))
  },
  e2eFlows: [],           // Empty — not yet consolidated
  dependencyGraph: {
    nodes: (master.modules || []).map(m => ({
      id: m.code, label: m.code, type: m.featureType || "data-centric"
    })),
    edges: (master.dependencyGraph?.edges || []).map(e => ({
      from: e.from, to: e.to, description: e.description || ""
    }))
  }
};
```

> **FIELD RENAME WARNING:** feature.json uses `mockupFormat` and `mockup`.
> The HTML renderer reads `format` and `content`. You MUST rename these fields.
> Failure to rename = empty mockup display in the browser.

### Step 3-bis: Generate SVG Wireframes (Parallel Task Agents)

> **Purpose:** Enrich each ASCII wireframe with a professional SVG version for dual-view rendering.
> **Cost:** ~$0.01 per wireframe (Sonnet model). Negligible for 2-6 wireframes per module.
> **Fallback:** If ANY SVG generation fails, proceed with ASCII only (svgContent stays null).

See [references/wireframe-svg-style-guide.md](wireframe-svg-style-guide.md) for the complete SVG style specification, prompt template, and orchestration process.

**Process summary:**

1. **Read** `references/wireframe-svg-style-guide.md` to get the prompt template
2. **Collect** all wireframes in `EMBEDDED_ARTIFACTS.wireframes` where `content` exists and `svgContent` is null
3. **Spawn parallel Task(sonnet) agents** — ONE per wireframe, ALL in a single message
4. **Collect and validate** results: strip markdown fences if present, verify SVG starts with `<svg` and contains `</svg>`
5. **Inject** valid SVGs into `EMBEDDED_ARTIFACTS.wireframes[moduleCode][index].svgContent`
6. **Display** summary: `SVG wireframes: {generated}/{total} generated successfully`

> **CRITICAL:** This step is NEVER blocking. If all SVG generations fail, deployment
> continues with ASCII-only wireframes. The HTML renderer checks for `svgContent` before
> showing the SVG view. SVG is an enhancement, not a requirement.

### Step 4: Replace Placeholders in Template

- Serialize the FEATURE_DATA object as JSON (2-space indentation)
- Serialize the EMBEDDED_ARTIFACTS object as JSON (2-space indentation)
- Replace `{{FEATURE_DATA}}` with the serialized FEATURE_DATA JSON
- Replace `{{EMBEDDED_ARTIFACTS}}` with the serialized EMBEDDED_ARTIFACTS JSON
- Replace `{{APPLICATION_NAME}}` → `{application_name}`
- Replace `{{APPLICATION_ID}}` → `{feature_id}`
- Replace `{{VERSION}}` → `{version}`
- Replace `{{CREATED_AT}}` → `{ISO timestamp}`

### Step 5: Write and Confirm

```
✓ Interactive HTML updated (incremental):
  Path: docs/business/{app}/business-analyse/v{version}/ba-interactive.html
  Modules included: {completedModules.length}/{totalModules} specified
    - {completedModule1}: {uc_count} UCs, {br_count} BRs, {wireframe_count} wireframes
    - {completedModule2}: ...
  Visual artifacts: {total_wireframes} wireframes embedded ({svg_count} with SVG, {ascii_only_count} ASCII only)
  Remaining: {pendingModules.join(', ')} (will be added after specification)
  → Client can open in browser to review completed modules now.
```
