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

# Difactu: aclaración de líneas pendientes

> Contrato aditivo para completar o añadir conceptos sin duplicarlos silenciosamente

## Estado y alcance

Contrato candidato R4-C4, con pruebas conectadas dirigidas aprobadas y pendiente
de aceptación completa e integración.
La protección pertenece al consumidor Difactu; no cambia el contrato de
adición del perfil MCP público ni el editor manual de Nubidoc.

## Añadido protegido

`POST /api/difactu/draft-add-lines-v2` (`addDraftLinesV2`) recibe las mismas
entradas de línea que el endpoint legado, junto con `conversation_key` obligatorio.
Si una entrada coincide exactamente
por identidad de catálogo o nombre normalizado con una línea incompleta,
conserva el lote como propuesta pendiente y no aplica ninguna entrada.

La vista pública contiene `draft.line_addition.proposal_ref` y
`draft.line_addition.conflicts`, con
índice de entrada desde 1, concepto y refs candidatas (`L1`, `L2`, etc.). No
expone IDs de negocio ni tokens de confirmación. La referencia de propuesta
no sustituye autenticación ni permisos.

## Resolución del lote

`POST /api/difactu/draft-resolve-line-addition`
(`resolveDraftLineAddition`) recibe `conversation_key`, `proposal_ref` y
`choices`, todos obligatorios. Cada entrada
en conflicto exige una elección:

* `complete_existing`, con `ref` candidata: rellena solo datos faltantes y
  conserva precio, cantidad y campos ya resueltos.
* `append_new`: añade la entrada como otra línea independiente.

El lote se aplica completo o no se aplica; decisiones incompletas o refs
ajenas no producen cambios parciales. La persistencia se serializa con bloqueo
de fila y recuerda la propuesta consumida para que su repetición no vuelva a
añadir líneas. Otra mutación invalida una propuesta pendiente; una elección
obsoleta se rechaza sin escribir.

Mientras exista una decisión pendiente, el borrador permanece en recogida de
datos y no puede obtener resumen confirmable ni crear el documento.

## Contrato del consumidor y publicación

El gateway conserva el nombre `addDraftLines`, pero llama siempre a v2.
El aviso corta el turno y la resolución solo se habilita para una propuesta
que ya estuviera presente al inicio de otro turno. El modelo aporta elecciones,
no la referencia autorizada. Una lectura fría muestra primero la pregunta.

Publicar el backend antes que el gateway: si falta v2, el consumidor muestra
un error y no vuelve al añadido legado. El endpoint anterior conserva su
comportamiento; este cambio no certifica otros clientes MCP.

No hay migración: la propuesta cabe en el payload JSON existente. No se deben
borrar propuestas pendientes durante un rollback ni tratarlas como resúmenes
confirmados. Esta protección no detecta todas las paráfrasis ni fusiona líneas
completas parecidas.

## Evidencia de aceptación parcial (07/09/2026)

Backend `0b8fa251a` comprobado en el banner DEV `:466`, gateway `75883bb` y
MCP propio apuntando al mismo candidato. Sin migraciones pendientes ni DDL.
Seis comprobaciones HTTP/MariaDB aprobaron, incluidas dos resoluciones concurrentes
con respuestas 200/409 y una sola aplicación del lote. El borrador sintético
propio se canceló y se verificó; su cuenta de prueba permanece.

Dos evals individuales con el modelo configurado verificaron una línea y 121 €
al completar, y dos líneas y 242 € al añadir otra deliberadamente. Preparan
el conflicto mediante API; no afirman que el modelo haya generado esa precondición.
La repetición de las suites completas sigue siendo necesaria: los pases dirigidos
no certifican el lanzamiento ni todos los comportamientos del modelo.

## Cliente ya seleccionado en Difactu

`POST /api/difactu/draft-set-client` admite `selected_patient_id` como parámetro
opcional aditivo, junto con `conversation_key`. Es el randomcode del cliente ya
seleccionado, exclusivo con todos los demás campos de identidad. La operación
conserva autenticación, scopes, bloqueo del borrador y confirmación final.

Valida que el cliente exista, no esté eliminado y pertenezca a la cuenta
autenticada. Puede resolver un cliente todavía vacío, seleccionar una identidad
presente en los candidatos o repetir la misma selección ya resuelta. Rechaza
identidades duplicadas pendientes, candidatos distintos y sustituciones de otro
cliente ya resuelto, sin guardar cambios. Devuelve `invalid_selected_client`
(400), `patient_not_found` (404) o `selected_client_conflict` (409), según el caso.
La vista continúa sin exponer el identificador; las líneas se conservan.

El gateway de Difactu obtiene este identificador del contexto de un cliente
registrado y confirmado, no de texto libre del modelo. Así puede continuar con
un presupuesto para «ese cliente» sin repetir la elección de una única opción,
incluso si el cliente no tiene NIF. Aportar otro cliente o datos fiscales nuevos
mantiene el flujo de resolución habitual. No cambia el editor manual de Nubidoc.
