Skip to content

fix(update-event-handler): persist attributes column on update#1197

Open
saimonhowlader wants to merge 5 commits into
HiEventsDev:developfrom
saimonhowlader:fix/update-event-handler-persists-attributes
Open

fix(update-event-handler): persist attributes column on update#1197
saimonhowlader wants to merge 5 commits into
HiEventsDev:developfrom
saimonhowlader:fix/update-event-handler-persists-attributes

Conversation

@saimonhowlader
Copy link
Copy Markdown

Summary

UpdateEventHandler::updateEventAttributes() silently drops the attributes JSONB column on every event update. EventRules validates attributes.* and UpdateEventDTO accepts the field, but the handler's updateWhere() payload omitted it entirely — so the SQL UPDATE never touched the column.

CreateEventHandler persists attributes correctly via setAttributes(); only the UPDATE path was broken.

Fix

Add attributes to the updateWhere() payload. When the update payload omits attributes ($eventData->attributes === null), fall back to the existing event's stored attributes. This matches the partial-update pattern already used for category, timezone, and currency in the same handler.

'attributes' => $eventData->attributes
    ? $eventData->attributes->map(fn(AttributesDTO \$a) => \$a->toArray())->all()
    : \$existingEvent->getAttributes(),

The explicit ->map(...)->all() (rather than ?->toArray()) is intentional: BaseDTO does not implement Illuminate\Contracts\Support\Arrayable, so Collection::toArray() would leave AttributesDTO instances un-converted at the array layer. Production today produces correct DB JSON only via PHP's implicit object→json_encode serialization — this PR removes that implicit dependency.

Tests

  • testPersistsAttributesWhenUpdatingEvent — non-empty attributes payload is persisted in the expected scalar-array shape.
  • testPreservesExistingAttributesWhenUpdateOmitsThemattributes=null does NOT null out existing attributes (regression guard).
  • Queue::fake() in setUp to prevent the handler's DispatchEventWebhookJob::dispatch() from hitting a live DB in the unit-test environment.

Verified locally: vendor/bin/phpunit tests/Unit/Services/Application/Handlers/Event/UpdateEventHandlerTest.phpOK (2 tests, 11 assertions).

Repro

  1. Create an event with attributes via the API.
  2. PATCH the event with any field change.
  3. Reload the event — attributes is empty.

Discovered against v1.9.0-beta; reproduces on current develop.

daveearley and others added 5 commits April 7, 2026 18:04
…ventsDev#1169) (HiEventsDev#1176)

Co-authored-by: Manas Kumar <141910018+manaskumar3003@users.noreply.github.com>
UpdateEventHandler::updateEventAttributes() was silently dropping the
`attributes` JSONB column on every event update. Although EventRules
validates `attributes.*` and UpdateEventDTO accepts it, the handler's
updateWhere() payload omitted the field entirely. CreateEventHandler
correctly persists it via setAttributes(); only the UPDATE path was
broken.

Fix: add 'attributes' to the updateWhere() payload, falling back to the
existing event's attributes when the update omits the field. This
matches the partial-update pattern already used for category, timezone,
and currency in the same handler, and guards against an incomplete
client payload nulling out previously-saved values.

Tests:
- testPersistsAttributesWhenUpdatingEvent: confirms a non-empty
  attributes payload is persisted via the repository.
- testPreservesExistingAttributesWhenUpdateOmitsThem: confirms
  attributes=null on the DTO does NOT null out existing attributes.

Refs: discovered in v1.9.0-beta; verified bug reproduces on current main.
…tes array)

Two iterations on the original fix commit (9e2ea5e), surfaced by running phpunit
locally for the first time:

1. UpdateEventHandler::updateEventAttributes — change the attributes mapping
   from `$eventData->attributes?->toArray()` to an explicit
   `->map(fn(AttributesDTO $a) => $a->toArray())->all()`.

   BaseDTO does NOT implement Illuminate\Contracts\Support\Arrayable, so
   Collection::toArray() leaves AttributesDTO instances un-converted at the
   array layer. The original code accidentally produced correct DB JSON via
   PHP's implicit object→json_encode behavior, but the in-memory shape that
   gets passed to the repository's updateWhere() is `[AttributesDTO obj, ...]`
   not `[['name' => ..., 'value' => ..., 'is_public' => ...], ...]`. The
   explicit map makes the conversion intent obvious to reviewers and removes
   reliance on implicit serialization.

2. UpdateEventHandlerTest::setUp — add `Queue::fake()`.

   UpdateEventHandler::getUpdateEvent dispatches DispatchEventWebhookJob,
   which under the default sync queue tries to actually run the webhook
   logic, hits the real EventRepository, and fails with `Connection refused`
   in the unit-test environment. `Queue::fake()` short-circuits the dispatch
   without needing a live Postgres.

Verified locally: `vendor/bin/phpunit
tests/Unit/Services/Application/Handlers/Event/UpdateEventHandlerTest.php`
→ OK (2 tests, 11 assertions).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor


Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

@saimonhowlader
Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants