> ## 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: contrato del registro público

> Alta independiente del catálogo de Nubidoc, evidencia de aceptación y ajuste pendiente en QA

## Comportamiento

El alta pública de Difactu guarda sus condiciones versionadas en
`hpc_difactu_privacy_acceptance`. No necesita una fila con ID 3 en el catálogo
`hpc_contractmodel` de Nubidoc. La creación administrativa de clientes conserva
su aceptación de contrato anterior.

Las validaciones de aceptación siguen siendo obligatorias. Si falla la escritura
de la evidencia, el alta se revierte. No se modifican los textos contractuales.

## Incidente de PROD — 16 de septiembre de 2026

A las 00:18:03, el alta falló con «Error al crear cliente» porque el catálogo de
contratos legado estaba vacío. Cliente y usuario se revirtieron. Se aplicó un
parche limitado a `Api_CustomerController::createAction()`, con copia previa,
validación PHP 7.4 y comprobación del archivo desplegado. No se escribieron datos
de clientes ni se crearon cuentas de prueba durante la intervención.

La comprobación aislada supera el fallo original y conserva la llamada de evidencia.
PROD también rechaza por HTTP 400 una petición pública sin aceptación de condiciones.
Juan confirmó posteriormente que la cuenta se creó. El siguiente ajuste unifica
la confirmación con el PIN que solicita la app.

## QA pendiente

QA no se ha modificado en esta intervención. Su próxima actualización debe incluir
la corrección del registro público. Antes de aplicarla, comprobar su versión y
crear su propia copia de seguridad; no trasladar hashes ni configuración de PROD.

* Verificar que el bloque de `hpc_usercontract` está condicionado a
  `!$isPublicDifactuRegistration`.
* Conservar `recordOnboardingTermsAcceptance()` dentro de la transacción.
* Ejecutar el test `difactu-signup-contract-acceptance.php` y PHP lint.
* Completar un alta con una cuenta de prueba autorizada y comprobar evidencia,
  módulo y acceso por PIN, además del rechazo cuando falta la aceptación.

No insertar una plantilla de Nubidoc para sortear este fallo. El procedimiento,
hashes y copia de PROD constan en
`docs/fixes/FIX_DIFACTU_REGISTRATION_LEGACY_CONTRACT.md` del repositorio de código.

## Confirmación y acceso por PIN

Las nuevas altas públicas quedan pendientes (`status=0`), sin código de enlace y
sin el correo de Nubidoc. El correo «Tu PIN de Difactu» indica el código que se
introduce en la app para confirmar el correo y entrar. No pide una contraseña.
Las cuentas existentes pueden solicitar otro PIN sin repetir el registro.

La entrega es directa, sin esperar al despachador de notificaciones. Un fallo de
SMTP responde `auth_pin_delivery_failed`. La validación consume el PIN y activa
la cuenta con una actualización SQL condicional antes de emitir JWT; un reenvío,
consumo simultáneo, bloqueo o borrado impide reutilizar la lectura anterior.
Los controles de cliente activo y módulo Difactu permanecen obligatorios.

**QA pendiente:** desplegar primero AuthController y después CustomerController.
Verificar entrega, estado pendiente hasta introducir el PIN, activación y acceso,
reenvío, caducidad, reutilización y fallo SMTP. El arnés de controlador/SQLite pasa,
pero la entrega real y el ciclo en el móvil requieren comprobación del usuario.
Detalle: `docs/fixes/FIX_DIFACTU_PIN_ONBOARDING.md` del repositorio de código.

El envío por WhatsApp es una mejora pendiente en
[el issue #89 de Difactu](https://github.com/Treebole-Services-Computing/tbl-difactu/issues/89).

Las rutas antiguas que puede seleccionar MCP (`/api/requestpin`, `/api/verifypin`
y `/api/refresh`) se reenvían internamente al mismo controlador en instalaciones
Difactu. Incluir también `application/controllers/ApiController.php` en QA, tras
AuthController, y comprobar las rutas antiguas además de `/api/auth/*`.
`confirmcode` es `NOT NULL` en PROD: la ausencia de enlace se representa con una
cadena vacía, sin migración de esquema.
