> ## Documentation Index
> Fetch the complete documentation index at: https://omniloy.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Pre-cargar desde tu EMR (updateTemplate)

> Alimenta lo que el médico ya escribió en tu propio formulario a la generación del informe para que las notas integren el contenido existente

`updateTemplate` es un callback del host que le permite a tu EMR (SINA/HIS) entregarle a SofIA **lo que el médico ya escribió en tus propios campos del formulario**. SofIA mergea ese contenido en la plantilla de extracción como contexto, para que la nota clínica generada **integre lo ya documentado** en lugar de:

* producir una **copia idéntica** al pulsar **Regenerar**, o
* **ignorar** las notas que el médico tomó durante la consulta.

Tú provees una función; el SDK la llama (un "pull") en los momentos correctos y se encarga del resto — el merge, la anonimización y la de-anonimización pasan todo dentro del SDK.

Esta página explica el **contrato**, **cuándo se llama** y **cómo cablearlo**.

## Cómo encaja en el flujo

El SDK **llama** (pull) tu callback en cuatro momentos y mergea el resultado en la plantilla que envía al backend de extracción:

<Steps>
  <Step title="Empieza la grabación">
    `updateTemplate()` alimenta la extracción parcial en vivo — una nota puede llevar contexto **antes** incluso de empezar a grabar.
  </Step>

  <Step title="Para la grabación">
    `updateTemplate()` alimenta el borrador automático de fondo.
  </Step>

  <Step title="Click en Generar">
    `updateTemplate()` se vuelve a llamar para el informe generado.
  </Step>

  <Step title="Click en Regenerar">
    `updateTemplate()` se vuelve a llamar para que la nota regenerada refleje el contenido más reciente del formulario.
  </Step>
</Steps>

Cada valor devuelto se mergea en la plantilla como `properties.<campo>.existingValue`, y se envía al backend de extracción como contexto de generación. Tú **no llamas nada** — solo asignas la función, y el SDK la invoca cuando necesita el contenido más fresco.

## El contrato

```typescript theme={null}
type UpdateTemplateCallback = () =>
  | Record<string, unknown>            // el contenido existente, por id de campo
  | null                               // o "nada para agregar"
  | undefined
  | Promise<Record<string, unknown> | null | undefined>; // puede ser async
```

Devuelve un objeto cuyas **claves sean los ids de las properties de la plantilla** y cuyos valores sean el contenido actual de esos campos en tu EMR:

| Tipo de campo en la plantilla                                               | Valor que devuelves                                                         |
| --------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| Prosa / escalar (`chief_complaint`, `hpi`, `plan`, `assessment`, …)         | un **string**                                                               |
| Secciones multi-opción / array (`diagnoses`, `medications`, `allergies`, …) | un **array de entradas** (objetos), con la forma de `items` de la plantilla |

```json theme={null}
{
  "chief_complaint": "Dolor torácico de 2 días",
  "plan": "Solicitar ECG y analítica",
  "diagnoses": [
    { "icd10_code": "I10", "name": "Hipertensión esencial" }
  ]
}
```

Reglas:

* **Las claves deben coincidir exactamente con los ids de las properties.** Las claves que no matcheen ninguna property se ignoran.
* **Los valores vacíos se descartan.** Strings vacíos, strings solo con espacios, arrays vacíos, `null` y `undefined` se omiten — ese campo cae a generación normal solo desde la transcripción (**sin degradación**).
* La función **puede ser sync o async**. Devuelve `null`/`undefined`/`{}` cuando no haya nada para aportar.
* Devuelve solo los campos de los que tengas contenido — no hace falta mandar todas las claves.

## Cómo usarlo

<CodeGroup>
  ```tsx React theme={null}
  import { Omniscribe } from '@omniloy/sofia-sdk/react';
  import '@omniloy/sofia-sdk/react/index.css';

  <Omniscribe
    apikey={API_KEY}
    userid={USER_ID}
    patientid={PATIENT_ID}
    template={REPORT_TEMPLATE}

    // El SDK lo llama cuando necesita el contenido existente del EMR.
    updateTemplate={() => ({
      chief_complaint: form.chiefComplaint,
      hpi: form.hpi,
      plan: form.plan,
      diagnoses: form.diagnoses, // [{ icd10_code, name }, ...]
    })}
  />
  ```

  ```html Web Component theme={null}
  <sofia-sdk id="sofia" apikey="your-api-key" userid="doctor-123" patientid="patient-456"></sofia-sdk>

  <script>
    const el = document.querySelector('#sofia');

    // updateTemplate es un function prop — asígnalo como propiedad JS, no como atributo HTML
    el.updateTemplate = () => ({
      chief_complaint: readField('chief_complaint'),
      plan: readField('plan'),
      diagnoses: readRows('diagnoses'), // [{ icd10_code, name }, ...]
    });
  </script>
  ```
</CodeGroup>

<Tip>
  El callback se lee fresco en cada pull, así que puedes devolver valores en vivo del estado actual de tu formulario — no hace falta re-asignarlo cuando el formulario cambia.
</Tip>

### Referencia de props

| Prop             | Tipo                                                               | Propósito                                                                                                                                              |
| ---------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `updateTemplate` | `() => Record<string, unknown> \| null \| undefined \| Promise<…>` | Devuelve el contenido existente de los campos del EMR, por id de property. El SDK lo llama al empezar/parar la grabación y antes de generar/regenerar. |
| `template`       | JSON Schema (`object`)                                             | La estructura del informe. Las claves de `updateTemplate` mapean a `template.properties.*`.                                                            |

## Qué hace el SDK con eso

1. **Pull** — llama a `updateTemplate()` (esperándolo si devuelve una Promise).
2. **Merge** — por cada clave devuelta que matchee una property y tenga contenido no vacío, la inyecta como `template.properties.<campo>.existingValue`. La plantilla que pasaste **nunca se muta** — se envía una copia.
3. **Anonimización (saliente)** — el `existingValue` inyectado se scrubea con el mismo mapa real→placeholder que ya se aplica a la transcripción, antes de salir hacia el transcriptor (WebSocket) y el LLM de extracción (HTTP). **No** necesitas anonimizar nada por tu cuenta.
4. **De-anonimización (entrante)** — cuando el modelo devuelve tu contenido en el resultado, el SDK restaura los valores reales, así el médico ve **exactamente lo que escribió** — nunca un placeholder.

Tu backend lee el contenido desde `properties.<campo>.existingValue` en el `json_schema` que recibe. **No hace falta cambiar la forma del payload** — el contenido viaja dentro de la plantilla que ya se envía.

<Info>
  La anonimización aquí espeja el flujo de [datos del paciente](/sofia/es/sdk/patient-data#anonimización-automática): los identificadores directos de `patientdata` y el `existingValue` inyectado se enmascaran antes de salir del navegador y se restauran en el resultado final.
</Info>

## Comportamiento cuando no hay nada para agregar

Este camino es seguro a propósito:

* `updateTemplate` **no provisto** → el SDK se comporta igual que antes.
* Devuelve `null` / `undefined` / `{}` → no se inyecta nada; generación normal.
* Un campo está **vacío** o su clave **no matchea** una property → ese campo se omite; los demás campos igual se usan.

En todos estos casos la generación procede normal desde la transcripción — no hay degradación ni error.

## Checklist rápido

* [ ] Pasas una `template` (JSON Schema) al SDK.
* [ ] `updateTemplate` devuelve un objeto por **ids de properties de la plantilla**.
* [ ] Los campos de prosa son **strings**; las secciones array son **arrays de entradas**.
* [ ] Los campos vacíos/desconocidos se omiten (o se dejan vacíos — el SDK los saltea).
* [ ] Tu backend lee `properties.<campo>.existingValue` del `json_schema`.
* [ ] (Sin acción por PII) — el SDK anonimiza al salir y restaura al volver.

<Warning>
  Si las notas regeneradas siguen saliendo idénticas, verifica que las claves de tu `updateTemplate` coincidan con los ids de las properties de la plantilla y que los valores no estén vacíos — las claves que no matchean o están vacías se saltean por diseño.
</Warning>

## Próximos pasos

* **[Esquemas de datos clínicos](/sofia/es/sdk/templates)** — la `template` con cuyos ids de property deben coincidir tus claves
* **[Modal de vista previa de inserción](/sofia/es/sdk/insertion-preview)** — deja que el médico cure el informe generado antes de que llegue a tu app
* **[Datos del paciente](/sofia/es/sdk/patient-data)** — cómo se anonimizan los datos contextuales
