---
name: 02-mapping-tables
description: Complete mapping tables for FEATURE_DATA object fields from master and collected_data sources
---

# Mapping Tables

This reference documents all field mappings used when constructing the FEATURE_DATA object from collected BA data sources.

---

## Metadata Mapping

**Source:** `master.metadata` and root `master` fields

**Mapping:**
```javascript
metadata: {
  applicationName: master.metadata.application,      // application name
  applicationId: master.id,                           // application unique ID
  version: master.version,                            // version string
  createdAt: master.metadata.createdAt,              // ISO timestamp
  lastModified: master.metadata.updatedAt,           // ISO timestamp
  analysisMode: master.metadata.analysisMode || "interactive"  // default: interactive
}
```

---

## Cadrage Context Mapping

**Source:** `master.cadrage` object

**Mapping:**
```javascript
cadrage.context: {
  problem: master.cadrage.problem || "",              // problem statement
  trigger: master.cadrage.trigger || "",              // what triggered the project
  currentSituation: master.cadrage.asIs || "",        // current state (AS-IS)
  desiredSituation: master.cadrage.toBe || "",        // desired state (TO-BE)
  painPoints: (master.cadrage.stakeholders || [])     // extracted from stakeholders
    .flatMap(s => s.painPoints || [])
    .join("\n"),
  acceptanceCriteria: (master.cadrage.acceptanceCriteria || [])  // AC list
    .map(ac => ac.criterion)
    .join("\n")
}
```

**Validation:** Warn if `problem` or `currentSituation/desiredSituation` are empty — these are MANDATORY for the HTML viewer.

---

## Cadrage Stakeholders Mapping

**Source:** `master.cadrage.stakeholders[]`

**Mapping:**
```javascript
cadrage.stakeholders: master.cadrage.stakeholders.map(s => ({
  role: s.role,                                        // role name
  function: s.function || "",                          // job function
  tasks: Array.isArray(s.tasks)
    ? s.tasks                                          // already an array
    : typeof s.tasks === 'string'
      ? s.tasks.split(',').map(t => t.trim()).filter(Boolean)  // parse CSV string
      : [],
  frequency: mapFrequency(s.frequency),               // frequency conversion
  access: mapAccess(s.involvement),                   // involvement → access level conversion
  frustrations: (s.painPoints || []).join("\n")       // stakeholder pain points
}))
```

**Helper: `mapFrequency(freq)`**

Maps user frequency to standardized values:
```
"Quotidien" | "Journalière" | "daily" → "daily"
"Hebdomadaire" | "weekly" → "weekly"
"Mensuel" | "monthly" → "monthly"
"Trimestriel" | "quarterly" → "quarterly"
"Annuel" | "yearly" → "yearly"
default → freq (as-is)
```

**Helper: `mapAccess(involvement)`**

Maps user involvement/role to access level:
```
"decision-maker" | "approver" | "responsable" → "admin"
"end-user" | "user" | "utilisateur" → "contributor"
"observer" | "lecteur" | "stakeholder" → "viewer"
default → "viewer"
```

---

## Cadrage Scope Mapping

**Source:** `master.cadrage.globalScope` and fallback `master.cadrage.coverageMatrix`

**Key Challenge:** Scope items can be strings, simple objects `{name, description}`, or complex objects `{feature, priority, module, app}`.

**Normalization Helper:**
```javascript
function normalizeScopeItem(item) {
  // Case 1: string value
  if (typeof item === 'string') return { name: item, description: "" };

  // Case 2: already in {name, description} format
  if (item.name) return { name: item.name, description: item.description || "" };

  // Case 3: {feature, priority, module, app} format (from globalScope)
  var name = item.feature || item.label || item.title || JSON.stringify(item);
  var parts = [];
  if (item.priority) parts.push(item.priority.toUpperCase());      // priority → upper
  if (item.module) parts.push("Module: " + item.module);           // module reference
  if (item.app) parts.push("App: " + item.app);                    // app reference
  return { name: name, description: parts.join(" — ") };           // parts → description
}
```

**Mapping:**
```javascript
cadrage.scope: {
  inscope: (master.cadrage.globalScope?.inScope || [])
    .map(normalizeScopeItem),
  outofscope: (master.cadrage.globalScope?.outOfScope || [])
    .map(normalizeScopeItem)
}
```

**Fallback:** If `globalScope` is missing/empty but `coverageMatrix` exists, build `inscope` from coverageMatrix entries.

---

## Cadrage Criteria Mapping

**Source:** `master.cadrage.acceptanceCriteria[]` with fallback to `collected_data.master.validation.acceptanceCriteria[]`

**Primary Mapping:**
```javascript
let criteria = (master.cadrage.acceptanceCriteria || []).map(ac => ({
  text: ac.criterion || ac.text || "",
  validated: false
}));
```

**Fallback (if criteria is empty):**
```javascript
if (criteria.length === 0 && collected_data.master.validation) {
  const valAC = collected_data.master.validation.acceptanceCriteria || [];
  criteria = valAC.map(ac => ({
    text: (ac.module ? '[' + ac.module + '] ' : '') + (ac.criteria || ac.criterion || ac.text || ""),
    validated: false,
    module: ac.module || null,
    type: ac.type || null
  }));
}
```

---

## Modules and Applications Mapping

**Source:** `master.modules[]` and `master.applications[]` (with fallback to `collected_data.navigation?.applications`)

**Applications Mapping:**
```javascript
applications: (collected_data.navigation?.applications || master.applications || []).map(app => ({
  code: app.code,                    // unique application code
  name: app.name || app.code,        // display name (fallback to code)
  icon: app.icon || ""               // icon reference
}))
```

**Modules Mapping:**
```javascript
modules: master.modules.map(m => ({
  code: m.code,                      // unique module code
  name: m.name || m.code,            // display name (MANDATORY)
  applicationCode: m.applicationCode || "",  // multi-app grouping
  description: m.description || "",
  featureType: m.featureType || "data-centric",  // component type
  entities: m.entities || [],        // entity references
  anticipatedSections: (m.anticipatedSections || []).map(s =>
    typeof s === 'string'
      ? { code: s, name: s, description: "", resources: [] }
      : {
          code: s.code || s.name || "",
          name: s.label || s.name || s.code || "",
          description: s.description || "",
          resources: s.resources || [],
          route: s.route || "",
          permission: s.permission || ""
        }
  ),
  dependencies: m.dependencies || [],     // module dependencies
  dependents: m.dependents || [],         // dependent modules
  estimatedComplexity: m.estimatedComplexity || "medium",
  status: m.status || "handed-off"       // handoff status
}))
```

---

## Dependencies Mapping (Top-Level)

**Source:** `master.consolidation?.crossModuleInteractions` or `master.dependencyGraph?.edges`

**CRITICAL:** This array is used by HTML sidebar navigation, module rendering, consolidation views, handoff summary, and export. If missing, the HTML page crashes with a TypeError.

**Mapping:**
```javascript
dependencies: (master.consolidation?.crossModuleInteractions || master.dependencyGraph?.edges || []).map(i => ({
  from: i.fromModule || i.from || "",
  to: i.toModule || i.to || "",
  description: i.description || ""
}))
```

**Always include**, even if empty: `dependencies: []`

---

## Consolidation Mapping

**Source:** `master.consolidation` object

**Mapping:**
```javascript
consolidation: {
  interactions: (master.consolidation?.crossModuleInteractions || []).map(i => ({
    from: i.fromModule,
    to: i.toModule,
    description: i.description || ""
  })),
  sharedEntities: master.consolidation?.sharedEntities || [],
  e2eFlows: (master.consolidation?.e2eFlows || []).map(f => ({
    name: f.name,
    steps: (f.steps || []).map(s => ({ module: s.module, action: s.action })),
    actors: (f.steps || []).map(s => s.permission).join(", ")
  }))
}
```

---

## Handoff Mapping

**Source:** `master.handoff` object

**Mapping:**
```javascript
handoff: {
  complexity: master.handoff?.complexity,
  implementationStrategy: master.handoff?.implementationStrategy,
  moduleOrder: master.handoff?.moduleOrder,
  filesToCreate: master.handoff?.filesToCreate,
  brToCodeMapping: master.handoff?.brToCodeMapping,
  apiEndpointSummary: master.handoff?.apiEndpointSummary
}
```

---

## Module Specifications: useCases Mapping

**Source:** `collected_data.modules[moduleCode].usecases`

**Normalization Notes:**
- Field may be `useCases` (camelCase) or `usecases` (lowercase)
- Steps may be strings[] or objects[] with `{step, action}` structure
- Alternative flows may be `alternativeScenarios` or `alternativeFlows`

**Mapping:**
```javascript
const rawUCs = mod.usecases?.useCases || mod.usecases?.usecases || [];

useCases: rawUCs.map(uc => ({
  name: uc.name || uc.title || uc.id || "",
  sectionCode: uc.sectionCode || "",
  actor: uc.primaryActor || uc.actor || "",
  steps: (uc.mainScenario || uc.steps || []).map(s =>
    typeof s === 'string' ? s : (s.action || s.description || "")
  ).join("\n"),
  alternative: (uc.alternativeScenarios || uc.alternativeFlows || []).map(a =>
    (a.name || a.trigger || "") + ": " + (a.steps || a.actions || []).map(s =>
      typeof s === 'string' ? s : (s.action || s.description || "")
    ).join(", ")
  ).join("\n")
}))
```

---

## Module Specifications: businessRules Mapping

**Source:** `collected_data.modules[moduleCode].rules`

**Normalization Notes:**
- Field may be `rules` or `businessRules`

**Mapping:**
```javascript
const rawBRs = mod.rules?.rules || mod.rules?.businessRules || [];

businessRules: rawBRs.map(br => ({
  name: br.name || br.id || "",
  sectionCode: br.sectionCode || "",
  category: br.category || "",
  statement: br.statement || br.description || "",
  example: (br.examples || []).map(e =>
    typeof e === 'string' ? e : ((e.input || "") + " → " + (e.expected || ""))
  ).join("; ")
}))
```

---

## Module Specifications: Entities Mapping

**Source:** `collected_data.modules[moduleCode].entities`

**Normalization Notes:**
- Attributes may be `attributes[]` or `fields[]` (fallback if attributes missing)

**Mapping:**
```javascript
entities: (mod.entities?.entities || []).map(ent => ({
  name: ent.name,
  description: ent.description || "",
  attributes: (ent.attributes || []).length > 0
    ? ent.attributes.map(a => ({
        name: a.name,
        type: a.type || "string",
        required: a.required || false,
        description: a.description || ""
      }))
    : (ent.fields || []).map(f => ({           // fallback to fields[]
        name: f.name,
        type: f.type || "string",
        required: f.required || false,
        description: f.description || ""
      })),
  relationships: (ent.relationships || []).map(r =>
    typeof r === 'string' ? r : r.target + " (" + r.type + ") - " + (r.description || "")
  )
}))
```

---

## Wireframes Mapping

**Source:** `collected_data.modules[moduleCode].screens` with wireframe data

**Field Rename CRITICAL:** Module JSON uses `mockupFormat`/`mockup`. HTML reads `format`/`content`.

**Mapping:**
```javascript
wireframes: {
  [moduleCode]: rawWireframes.map(wf => ({
    screen: wf.screen || wf.name || wf.title || wf.id || "",
    section: wf.section || "",
    format: wf.mockupFormat || "ascii",                   // RENAME: mockupFormat → format
    content: wf.mockup || wf.ascii || wf.content || "",   // RENAME: mockup → content
    svgContent: null,                                      // populated later if SVG generated
    description: wf.description || "",
    elements: wf.elements || [],
    actions: wf.actions || [],
    componentMapping: Array.isArray(wf.componentMapping)
      ? wf.componentMapping.map(entry => ...)   // see below
      : typeof wf.componentMapping === 'object' && wf.componentMapping !== null
        ? Object.entries(wf.componentMapping).map(([k, v]) => ({ wireframeElement: k, reactComponent: v }))
        : [],
    layout: typeof wf.layout === 'object' ? wf.layout : null,
    permissionsRequired: wf.permissionsRequired || []
  }))
}
```

**componentMapping Normalization:**

Handles three formats:
```javascript
// Format 1: Array of canonical entries {wireframeElement, reactComponent}
[{wireframeElement: "Button1", reactComponent: "Button"}]

// Format 2: Shorthand [{key: value}]
[{"Button1": "Button"}] → {wireframeElement: "Button1", reactComponent: "Button"}

// Format 3: Object {key: value}
{"Button1": "Button"} → [{wireframeElement: "Button1", reactComponent: "Button"}]
```

---

## E2E Flows Mapping

**Source:** `master.consolidation?.e2eFlows`

**Mapping:**
```javascript
e2eFlows: (master.consolidation?.e2eFlows || []).map(flow => ({
  name: flow.name,
  diagram: flow.steps.map(s => s.action + "(" + s.module + ")").join(" ──→ "),
  steps: flow.steps || [],
  actors: [...new Set(flow.steps.map(s => s.permission?.split(".")[0]).filter(Boolean))].join(", "),
  modules: [...new Set(flow.steps.map(s => s.module))].join(" → ")
}))
```

---

## Dependency Graph Mapping

**Source:** `master.modules[]` and `master.dependencyGraph?.edges`

**Mapping:**
```javascript
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 || ""
  }))
}
```

---

## Permission Keys Helper

**Source:** `collected_data.modules[moduleCode].permissions`

**Implementation:** See `references/data-mapping.md` for `buildPermissionKeys()` function implementation.
