Skip to content

Garantizar atomicidad entre cambio de estado y registro en historial#78

Merged
daniel89fg merged 1 commit into
masterfrom
4715-historial-estado-servicio
Jun 4, 2026
Merged

Garantizar atomicidad entre cambio de estado y registro en historial#78
daniel89fg merged 1 commit into
masterfrom
4715-historial-estado-servicio

Conversation

@daniel89fg

Copy link
Copy Markdown
Member

Descripción

Se han detectado casos en los que un cambio de estado de un ServicioAT se guardaba en la base de datos sin dejar ningún registro en el historial (serviciosat_logs). El mecanismo de log estaba bien diseñado, pero la implementación tenía un fallo silencioso.

Adicionalmente, se mejora el mensaje de creación de servicio para incluir el estado inicial, de modo que quede constancia del estado predeterminado con el que se creó.

Tarea relacionada

Tarea #4715

El problema

En ServicioAT::onChange(), el método log() era llamado pero su valor de retorno no se comprobaba:

// Antes — retorno ignorado
$this->log($messageLog);

Si la escritura en serviciosat_logs fallaba por cualquier motivo (error temporal de BD, fallo de codificación JSON, etc.), onChange() devolvía true igualmente y el save() continuaba. El resultado: el estado cambiaba en la BD pero no quedaba ninguna entrada en el historial.

El mismo patrón de retorno ignorado también estaba presente en delete() y onInsert().

Solución

onChange('idestado') — operación atómica (cambio crítico)

// Después — si el log falla, se aborta el cambio de estado
if (false === $this->log($messageLog)) {
    return false;
}

Si log() devuelve false, onChange() devuelve false, lo que provoca que save() aborte toda la operación. Ahora o se graban tanto el cambio de estado como el log, o no se graba ninguno.

delete() y onInsert() — aviso de fallo

En estos dos métodos, la operación principal ya se ha ejecutado antes de llamar a log(), por lo que no se puede revertir. En su lugar se registra un error visible en el log del sistema:

if (false === $this->log($messageLog)) {
    Tools::log()->error('record-save-error', ['%modelo%' => 'ServicioATLog']);
}

Log de creación con estado inicial

El mensaje de creación de un servicio ahora incluye el estado con el que se creó:

  • Antes: "Servicio creado"
  • Después: "Servicio creado con el estado En proceso"

Esto es especialmente útil porque el estado predeterminado puede cambiar con el tiempo, y antes no quedaba constancia del estado inicial.

Cambios realizados

  • Model/ServicioAT.phponChange(): devolver false si log() falla (garantía de atomicidad)
  • Model/ServicioAT.phpdelete(): registrar error si log() falla tras el borrado
  • Model/ServicioAT.phponInsert(): registrar error si log() falla tras la inserción; incluir estado en el mensaje
  • Translation/es_ES.json: actualizar clave new-service-created con el parámetro %status%

Cómo probar

  1. Crear un nuevo servicio y comprobar que el historial muestra el mensaje con el estado inicial (ej. "Servicio creado con el estado En proceso").
  2. Cambiar el estado de un servicio existente y verificar que aparece una entrada en el historial con el estado anterior y el nuevo.
  3. Para verificar la atomicidad: renombrar temporalmente la tabla serviciosat_logs y comprobar que al intentar cambiar el estado, la operación es rechazada completamente (ni el estado ni el log se graban) en lugar de guardarse el estado sin log.

🤖 Generado con Claude Code

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

…el historial

- En onChange('idestado'): si log() falla se retorna false, evitando que el
  estado se guarde sin dejar registro en el historial
- En delete(): si log() falla se registra un error en el log del sistema
- En onInsert(): si log() falla se registra un error en el log del sistema
- El mensaje de creación de servicio ahora incluye el estado inicial

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@daniel89fg daniel89fg merged commit 0403976 into master Jun 4, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant