pediatric-ai-scribe-v3/docs/MODULE_CONVENTIONS.md

2.5 KiB

Module Conventions

Ped-AI currently uses mixed JavaScript module styles. This is intentional during incremental modernization.

Current Convention

Area Module Style Notes
Backend server.js, src/** CommonJS Use require and module.exports for now
New frontend modules ESM Use import and export
Older frontend files Classic browser globals Convert only when touching the feature intentionally
Dual browser/test files Case-by-case Keep classic style only when tests or browser globals require it

Do not add root-level "type": "module" without a full backend migration plan. It would change how every .js file is interpreted by Node.

CommonJS Example

var express = require('express');
var router = express.Router();

module.exports = router;

ESM Example

import { escapeHtml } from './assistant/citations.js';

export function renderSourcesList(sources) {
  return '';
}

Frontend Modernization Path

  1. New frontend code should be ESM where possible.
  2. Existing globals can remain until that feature is refactored.
  3. Keep browser script load order stable while refactoring.
  4. Export pure helper functions so Node tests can import them.
  5. Use CustomEvent or explicit imports instead of adding new global APIs when practical.

Acceptable Globals

Globals are acceptable when they are part of the current shell contract.

Examples:

  • window.activateTab,
  • window.getAuthHeaders,
  • shared UI helpers still consumed by legacy feature files.

Do not add new globals when an import or event would be clearer.

Rendering And innerHTML

innerHTML is allowed only when one of these is true:

  • the HTML is a static template controlled by the app,
  • all dynamic values are escaped before insertion,
  • the HTML has passed through the approved sanitizer,
  • the content is a trusted app component fetched from public/components/.

Prefer textContent for plain text.

Unsafe:

el.innerHTML = userText;
el.innerHTML = modelOutput;

Safer:

el.textContent = userText;
el.innerHTML = escapeHtml(userText).replace(/\n/g, '<br>');
el.innerHTML = sanitizeHtml(renderMarkdown(modelOutput));

Test Expectations

When converting a frontend file to ESM, add or update tests for:

  • exported helper functions,
  • expected globals still present if legacy code needs them,
  • no browser-native prompt, alert, or confirm,
  • no unescaped dynamic text inserted through innerHTML.