Есть статья Article(id, name, status_id) которая поступила на модерацию. При этом у нее меняется статус: была в черновиках, потом отправлена на ревью, потом либо возвращена либо принята.
Статус - поле в модели статьи, но помимо этого пишется история смены статусов. Типа ArticleEvent(id, article_id, old_status_id, new_status_id).
Также на ревью к статье могут быть установлены ошибки, ну в смысле пометки об ошибках в статье. Это отдельная моделька связанная с ивентом ArticleError(id, event_id, field_id, message). Но ошибки есть только у "ошибочных" ивентов - которые записаны при изменении статуса на "возвращено".
Проблема в следующем: чтобы создать ошибку на этапе ревью мне нужен созданный ивент о возврате статьи чтобы эту ошибку к нему привязать. Но статья то еще не возвращена!!! И не факт что ее вернут, возможно примут. Т.е. мне не к чему привязывать ошибку при установке.
Я пытался делать так: при переходе статьи в статус "ревью" создаю ивент "возвращено" с отдельным полем is_status_changed - действительно ли уже изменился статус. Но потом если ошибок все же нет то его надо еще удалять при переходе статьи в статус "принято". И не забывать включать/выключать этот флаг. А еще есть старые статьи со старой историей (раньше это немного по другому было сделано) у которых при статусе "ревью" нет ивента о возврате. Вообщем это чрезвычайно запутано выходит. Очень много багов.
Еще можно наверное создавать ивент о возврате при создании первой ошибки, но ошибки могут еще и удалять (вдруг ошибочно создали), а значит и ивент надо удалять. Так что это еще запутаннее выйдет.
Вообще подобный workflow обычно реализуется через конечные автоматы. Для PHP есть как минимум две популярные реализации: finite и компонент Symfony Workflow. В последнем точно поддерживаются event'ы.