> ## 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.

# Acciones clínicas (Extras)

> Extrae las acciones que surgen de la consulta —peticiones, citas, pruebas, derivaciones— y entrégalas a tu HIS por categoría

Los **extras** son un segundo canal de salida junto al informe. Mientras `handleReport` te entrega la **nota** clínica, los extras te entregan las **acciones** que surgen de la consulta —peticiones, citas, pruebas, derivaciones— listas para que tu HIS las ejecute.

El sistema lo define tu esquema. Declaras las categorías en la prop `templateExtras` y el SDK muestra un botón por categoría. Al pulsarlo, SofIA extrae **solo esa categoría** de la transcripción y te entrega los items **tal como los produjo contra tu esquema, sin renombrar ni transformar campos**. La forma de cada item la decides tú en el esquema.

<Info>
  Extras e informes son canales independientes. Puedes usar `template` + `handleReport`, `templateExtras` + `handleExtras`, o ambos a la vez.
</Info>

## Las dos props

| Propiedad          | Tipo                   | Cómo se asigna                                                                       |
| ------------------ | ---------------------- | ------------------------------------------------------------------------------------ |
| **templateExtras** | `object` (JSON Schema) | Propiedad JS `el.templateExtras`. Como atributo del web component: `template-extras` |
| **handleExtras**   | `function`             | **Solo propiedad JS** (`el.handleExtras = fn`)                                       |

Ambas siguen la misma convención que `handleReport`: **propiedad JS en camelCase, atributo HTML en kebab-case**. En React la prop es `templateExtras`; en el web component se asigna como `el.templateExtras` o como el atributo `template-extras` (que se elimina del DOM tras leerse, por ser un dato sensible). `handleExtras` es un callback: solo propiedad JS, sin atributo HTML.

```typescript theme={null}
handleExtras: (extras: Extra[]) => void   //  Extra = Record<string, unknown>
```

Se invoca al pulsar un botón de categoría —y, si el [modal de vista previa](/sofia/es/sdk/insertion-preview) está activo, tras pulsar **Aplicar**—. Recibe el array de items de esa categoría, sin capa de normalización de por medio.

## Del esquema a los botones

Las **propiedades de primer nivel** de `templateExtras` son las categorías. Cada una genera un botón:

```jsonc theme={null}
{
  "type": "object",
  "properties": {
    "peticiones":   { "type": "array", "items": { /* { type, description } */ } },
    "citas":        { "type": "array", "items": { /* ... */ } },
    "pruebas":      { "type": "array", "items": { /* ... */ } },
    "derivaciones": { "type": "array", "items": { /* ... */ } }
  }
}
```

Las dos primeras categorías se muestran inline; el resto queda tras un menú de tres puntos (`…`). La etiqueta de cada botón se traduce cuando la clave existe en el idioma activo; si no, se muestra el nombre de la propiedad capitalizado, de modo que **cualquier categoría que definas se renderiza**. Vienen traducidas `peticiones` (Petitions), `citas` (Appointments), `pruebas` (Tests) y `derivaciones` (Referrals).

## El flujo

<Steps>
  <Step title="Aparecen los botones">
    Cuando hay `templateExtras`, existe una transcripción y `handleExtras` está cableado. No dependen del contenido del informe.
  </Step>

  <Step title="El médico pulsa una categoría">
    El SDK extrae esa categoría bajo demanda: construye un sub-esquema con esa única propiedad y lo envía a la API de extracción. Solo se procesa una categoría a la vez; el botón muestra "Generando…" mientras tanto.
  </Step>

  <Step title="Revisión o entrega directa">
    Con el [modal de vista previa](/sofia/es/sdk/insertion-preview) activo, los items se abren en el modal para que el médico los revise y cure. Si no, pasan directos a `handleExtras`.
  </Step>
</Steps>

El modal es el mismo que cura los informes, por un canal paralelo: se activa cuando el flag `showInsertionPreview` (por API key) está en `true` **y** hay `templateExtras`. Con el gate activo, `handleExtras` recibe los items al pulsar **Aplicar**; con el gate inactivo, los recibe directamente. La extracción nunca toca la nota clínica.

<Info>
  La PII se anonimiza antes de salir y se restaura en la respuesta, igual que en el resto del SDK ([datos del paciente](/sofia/es/sdk/patient-data)). Los items se extraen en el idioma de la sesión.
</Info>

## Los campos los define tu esquema

El SDK entrega los items tal como salieron de tu `templateExtras`, sin mapear ni renombrar nada. Con un esquema cuyos items son `{ type, description }`, recibes:

```typescript theme={null}
handleExtras([
  { type: '3', description: 'Solicitar TAC con contraste.' },
  { type: '1', description: 'Solicitar analítica completa.' },
  { type: '2', description: 'Revisión dentro de un mes.' },
]);
```

Lee el campo que definiste (aquí `type`) para enrutar cada acción a su endpoint. Si necesitas otra forma, cámbiala en el esquema —no añadas una capa de conversión en tu integración.

## Cómo usarlo

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

  const EXTRAS_TEMPLATE = {
    type: 'object',
    properties: {
      peticiones: {
        type: 'array',
        items: {
          type: 'object',
          properties: {
            type: { type: 'string', description: 'Código del tipo de petición' },
            description: { type: 'string', description: 'Texto de la petición' },
          },
        },
      },
      citas: {
        type: 'array',
        items: {
          type: 'object',
          properties: {
            type: { type: 'string' },
            description: { type: 'string' },
          },
        },
      },
    },
  };

  <Omniscribe
    apikey={API_KEY}
    userid={USER_ID}
    patientid={PATIENT_ID}
    templateExtras={EXTRAS_TEMPLATE}
    handleExtras={(extras) => {
      extras.forEach((item) => myHis.dispatchAction(item.type, item.description));
    }}
  />
  ```

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

  <script>
    customElements.whenDefined('sofia-sdk').then(() => {
      const el = document.getElementById('sofia');

      // Prop JSON — propiedad JS camelCase (atributo HTML: template-extras)
      el.templateExtras = {
        type: 'object',
        properties: {
          peticiones: { type: 'array', items: { type: 'object',
            properties: { type: { type: 'string' }, description: { type: 'string' } } } },
          citas: { type: 'array', items: { type: 'object',
            properties: { type: { type: 'string' }, description: { type: 'string' } } } },
        },
      };

      // Prop de función — solo propiedad JS
      el.handleExtras = (extras) => extras.forEach(sendToHis);
    });
  </script>
  ```
</CodeGroup>

<Tip>
  Para esquemas grandes, asigna la prop como propiedad JS (`templateExtras` en React, `el.templateExtras` en el web component) en lugar de como atributo HTML inline, para evitar problemas de escape de JSON.
</Tip>

## Referencia de props

| Prop             | Tipo                        | Propósito                                                                                                                                 |
| ---------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `templateExtras` | JSON Schema (`object`)      | Define las categorías (una propiedad, un botón). Requerida para activar los extras. En el web component el atributo es `template-extras`. |
| `handleExtras`   | `(extras: Extra[]) => void` | Recibe los items de la categoría pulsada, sin transformar. `Extra = Record<string, unknown>`.                                             |

Los botones aparecen solo cuando coinciden los tres: `templateExtras` con al menos una categoría, una transcripción en curso y `handleExtras` cableado.

## Próximos pasos

* **[Modal de vista previa de inserción](/sofia/es/sdk/insertion-preview)** — deja que el médico cure los items antes de que lleguen a tu app
* **[Esquemas de datos clínicos](/sofia/es/sdk/templates)** — cómo diseñar el JSON Schema
* **[Propiedades opcionales](/sofia/es/sdk/optional-properties)** — referencia completa de callbacks
