# 2. Configuration & Whitelabelling

Whitelabelling ("which brand does this report look like") is driven entirely by a **runtime string** — a `client` (or, for the corporate report, `clientName`) field in the request payload. There is no environment variable, no CLI flag, and no central "client registry" module. Each generator independently maps that string to a config JSON file and a template folder, and — this is the single most important thing to understand about this system — **the four generators do it four slightly different, inconsistent ways.**

## 2.1 The `config/` directory

One JSON file per brand, named after the client string, plus `config/default.json` as the fallback:

```
config/
  default.json
  Mediclinic.json
  Pha.json
  Najeeb.ai.json
  bionext.json
  diagnostikare.json
  maisonsante.json
  nasco.json          (referenced by filename convention; see 2.2 for how "nasco" resolves)
  sanitas.json
  sanusx.json
```

### Common schema (present in most/all files)

- **`logo`** — Logo image, URL or base64 data-URI
- **`body_icon`, `lifestyle_icon`, `mind_icon`, `bulb_icon`** — Section icons, URL or base64 data-URI
- **`first-level-color` … `fifth-level-color`** — 5-step color ramp used for score/chart coloring
- **`general-font-color`, `disclaimer-text-color`, `top-box-background`, `footer-background`** — Theme colors
- **`body_font_color`, `list_icons_font_color`, `insights_font_color`** — More theme colors
- **`signature`** — Free text signed off in emails/footers, e.g. `"Team Medicus"`, `"Team Sanitas"`
- **`corporate_report`** — Nested object, see 2.1.1

### Brand-specific keys

- `title` — only `Mediclinic.json`, `Pha.json`, `maisonsante.json` (`"HealthRiskAssessment"`).
- `score-header-color`, `score-description-color`, `svg-icon-color`, `low-score-text-color`, `section-title-border-color`, `first-section-scores-border-color`, `footer-border-color` — only `Mediclinic.json`, `Pha.json`, `maisonsante.json`.
- `labs-logo` / `labs-logo-aliases` — **only `Pha.json`**. `labs-logo` maps a canonical lab key (e.g. `"labcorp"`, `"wp"`) to a base64 logo image. `labs-logo-aliases` maps the same keys to arrays of alternate spellings (e.g. `["lab corp", "lab_corp", ...]`) used to match whatever spelling the caller sends in `selectedLabs` (see doc 4, wellbeing SmartReport header logos).
- `big_integral_questionnaire` — only `Pha.json` and `maisonsante.json`: `{ title, showHormonalFemale, showHormonalMale, colors: { headerBg, subheaderBg, headerText, rowBorder, elevatedText } }`. Consumed by `lib/big_integral_questionnaire.js` (see doc 5 — this module currently renders 100% mock data).

#### 2.1.1 The nested `corporate_report` object

```json
"corporate_report": {
  "logo": "...",
  "main_color": "rgb(0, 0, 153)",
  "report_date_color": "rgb(139, 139, 167)",
  "section_title_color": "rgb(0, 0, 153)",
  "section_title_border_color": "rgb(0, 158, 226)",
  "chart_title": "rgb(139, 139, 167)",
  "summary_background": "#e5f5fc",
  "relation_content_border_color": "rgba(0, 0, 153, 0.3)",
  "relation_content_bg": "#f2f2ff",
  "table_tr_even_bg": "rgb(237, 237, 248)",
  "recommends_bg": "rgba(0, 0, 153, 0.05)",
  "recommends_title": "Moxie",
  "show_medicus_logo": true,
  "show_second_footer_logo": true
}
```

`show_second_footer_logo` is missing from `sanusx.json` and `diagnostikare.json`. `bionext.json`'s `corporate_report` block additionally has its own `body_font_color`, unique to that one file.

`Najeeb.ai.json` is essentially a duplicate of `default.json` (same colors, `signature: "Team Medicus"`) — a placeholder brand with no real customization yet. `sanitas.json` overrides `signature` ("Team Sanitas"), the color ramp, and `corporate_report.recommends_title` ("Sanitas") but otherwise mirrors the default.

## 2.2 How `client`/`clientName` resolves to a config file — and why it's inconsistent

There is no shared config-loader. Each generator reimplements the lookup:

- **`wellbeing_report_generator.js`** (`loadClientConfig`) — Resolution logic: `'pha'` (any case) → `'Pha'`; otherwise uses the string as-is to build `config/{name}.json`; falls back to `config/default.json` via `fs.existsSync`. *Gotcha:* only `pha` gets special-cased; every other brand must be passed with exact on-disk casing.
- **`corporate_report_generator.js`** — Resolution logic: `client = data.clientName.toLowerCase()`, then `config/{client}.json`. *Gotcha:* **lower-cases before lookup**, but the actual files are capitalized (`Mediclinic.json`, `Pha.json`, `Najeeb.ai.json`). This only works on case-insensitive filesystems (Windows/macOS default). On a case-sensitive Linux filesystem, `clientName: "Mediclinic"` silently falls back to `default.json`.
- **`lib/sendEmail.js`** (`sendNascoEmail`) — Resolution logic: uses the **raw, unmodified** client string, no lower-casing, no `pha`→`Pha` mapping. *Gotcha:* caller must pass the exact on-disk filename casing, a different rule than the wellbeing generator it's normally called alongside.
- **`sanusx_report_generator.js`** — Resolution logic: **ignores `clientName` for config entirely** — unconditionally `require('../config/sanusx.json')`. *Gotcha:* the `client` parameter this generator accepts is only used later to add a CSS class (`$(".score-main").addClass(client)`), which currently matches no CSS rule — effectively a no-op. SanusX is single-brand in practice.
- **`lib/pdf_generator.js` / `.min.js`** (core report) — Resolution logic: does not touch `config/` at all. *Gotcha:* branding for the core report must arrive pre-baked inside the data payload from the host app — there is no per-client config file in this pipeline.

**Practical consequence:** if you're onboarding a new brand, check *which* generator you're using before assuming "just add `config/NewBrand.json`" is enough — confirm the exact casing rule for that specific generator, and remember `sanusx_report_generator.js` won't pick it up at all without a code change.

One more special case: `wellbeing_report_generator.js:1341-1353` hard-codes a feature gate — when `client.toLowerCase() === 'maisonsante' && data.IsDoctor`, it re-reads `config/maisonsante.json` a second time (bypassing the already-resolved config object) specifically to feed `big_integral_questionnaire.js`.

## 2.3 Config → colors/branding, not template choice, in most flows

Loading `config/{client}.json` gives you colors/logos/icons that get injected as inline `<style>` overrides or `{{token}}` substitutions into whatever HTML template was already chosen (see 2.4) — it does **not**, by itself, choose which template folder is used. Two exceptions: the corporate report and SanusX generators always use one fixed template folder regardless of config; only the wellbeing "extended" (SmartReport) flow ties template folder selection directly to the client string.

## 2.4 Template folder selection — no blocks-level fallback

`templates/` has full per-brand subfolders for **`Mediclinic`**, **`Pha`**, and **`maisonsante`** (each with `ltr_no_pages.html`, `rtl_no_pages.html`, `wellbeing_template.html` and its own `blocks/`), a generic **`wellbeing`** folder used as the default, a **`sanusx`** folder, plus non-brand folders `corporate_report/`, `imc/`, `popup/`, and the shared top-level `templates/blocks/`.

- **Core report** (`pdf_generator.min.js`) — always `templates/blocks/*` (+ `templates/imc/first-header-template.html` for one specific lab type). No per-brand folder is ever consulted; all differentiation happens through the data payload, not through swapped templates.
- **Wellbeing, plain** (`generateHTMLWellbeingReport` → `loadWellbeingTemplates`) — always `templates/wellbeing/` regardless of client. Brands going through this flow are differentiated purely by injected config colors/logo.
- **Wellbeing, extended/SmartReport** (`generateHTMLWellbeingReportWithSmartReport` → `loadExtendedTemplates`) — derives the folder name **directly from the client string** (`'pha'→'Pha'`, `'mediclinic'→'Mediclinic'`, else used as-is) → `templates/{ClientName}/`. Reads every block with `fs.readFileSync` and **no existence check** — if the folder or a block inside it is missing, it throws `ENOENT`. Only works today for clients with a dedicated folder: `Mediclinic`, `Pha`, `maisonsante`.
- **Corporate report** — always `templates/corporate_report/*`, regardless of client.
- **SanusX** — always `templates/sanusx/*`, regardless of client.

There is **no fallback from a brand folder to the shared `templates/blocks/`** for an individual missing block — brand folders are complete, parallel copies, not overrides layered on a shared base. If you add a fourth brand to the "extended" wellbeing flow, you must create a full `templates/{Brand}/` folder with every block file the existing three have, or the render will crash.

## 2.5 Brand asset directories

`assets/Mediclinic/`, `assets/pha/labcrop-logo.png`, `assets/sanusx/`, `assets/imc/`, `assets/corporate_report/`, `assets/wellbeing/`, `assets/medicus_pdf/*.css`.

Notable: **`templates/Pha/*.html` and `templates/maisonsante/*.html` both reference `../assets/Mediclinic/css/...` and `../assets/Mediclinic/js/js.js`** — Pha and Maison Sante do not have their own CSS/JS bundle; they reuse the Mediclinic bundle wholesale and rely entirely on the `config/{Client}.json` color values for visual differentiation. `templates/corporate_report/cover_page.html` also hard-codes a Nasco logo image path regardless of client, unless overridden by config.

## 2.6 Environment variables

There is exactly **one** environment variable read anywhere in the codebase: `SHOW_QR_BOX` (`lib/template.js`), which toggles whether the in-report PIN/QR box renders. It has nothing to do with whitelabelling. **No environment variable selects a client, config, or template.**

## 2.7 Step-by-step trace: "given `client = X`, what actually loads?"

1. Host app calls an `index.js` export with `client: X` (or `clientName: X` for the corporate report) inside the payload.
2. The generator resolves `X` to `config/{mapped X}.json` if it exists, else `config/default.json` — using whichever mapping rule from §2.2 applies to that generator.
3. Config values (colors, logo, icons, `corporate_report`/`big_integral_questionnaire` sub-objects) get inlined into the HTML as `<style>` overrides / `{{token}}` substitutions.
4. The template folder is chosen per §2.4 — for three of the four generators this is *independent* of `X`; only the "extended" wellbeing flow ties folder choice to `X`.
5. Assets are pulled in via relative `<link>`/`<script>` tags baked into whichever template was chosen — mostly `assets/Mediclinic`, `assets/wellbeing`, `assets/sanusx`, `assets/corporate_report`, or `assets/imc` — independent of `X` except for the config-driven inline color overrides.
