Add the product-review-approved earning trigger + channel resolver#30
Add the product-review-approved earning trigger + channel resolver#30loevgaard wants to merge 2 commits into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## pr/29-action-trigger-registration #30 +/- ##
=======================================================================
- Coverage 94.53% 94.40% -0.13%
- Complexity 443 447 +4
=======================================================================
Files 70 69 -1
Lines 1280 1270 -10
=======================================================================
- Hits 1210 1199 -11
- Misses 70 71 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
| ], | ||
| ], | ||
| ], | ||
| ProductReviewTransitions::GRAPH => [ |
There was a problem hiding this comment.
Add listener on Symfony workflow also
33d13ff to
754912b
Compare
The second action trigger, plus the channel-resolution the context-less triggers need. - TriggerChannelResolverInterface (+ DefaultTriggerChannelResolver) resolves the channels a context-less trigger awards on: the customer's existing loyalty-account channels. It's an extension point, and LoyaltyAccountRepository gained findByCustomer for it. - ReviewApprovedStateMachineListener awards the `product_review_approved` rules when a product review is accepted, on each resolved channel. Approval happens in admin (no shop channel), so the resolver is used instead of the current channel. Bridges both state-machine adapters like the order-award listener (workflow tag + winzou callback via the extension prepend); the ledger's idempotency covers overlap and the per-(review,channel) source identifier. Tests: DefaultTriggerChannelResolverTest (functional) + ReviewApprovedStateMachineListenerTest (unit, both adapters + guards); the extension test now asserts the review winzou callback. Unit 126 + functional 55 green. No new dependencies (ProductReviewInterface is Core).
754912b to
e1c1a2c
Compare
| <service id="Setono\SyliusLoyaltyPlugin\Earning\Trigger\ReviewApprovedStateMachineListener" public="true"> | ||
| <argument type="service" id="Setono\SyliusLoyaltyPlugin\Earning\ActionPointsAwarderInterface" /> | ||
| <argument type="service" id="Setono\SyliusLoyaltyPlugin\Earning\TriggerChannelResolverInterface" /> | ||
| <tag name="kernel.event_listener" event="workflow.sylius_product_review.completed.accept" method="onWorkflowReviewAccepted" /> |
There was a problem hiding this comment.
Should this event be added as an event subscriber instead?
There was a problem hiding this comment.
It intentionally matches the order-award and redemption state-machine listeners: an event_listener tag for the workflow transition (workflow.sylius_product_review.completed.accept) plus a winzou callback registered in the extension prepend. Making only this one a subscriber would diverge from those two. If you'd prefer subscribers for all the state-machine bridges, I'm happy to convert the three together as a separate cleanup — let me know.
| /** | ||
| * @return iterable<ChannelInterface> | ||
| */ | ||
| public function resolve(CustomerInterface $customer): iterable; |
There was a problem hiding this comment.
I guess we miss more implementations than the DefaultTriggerChannelResolver. It should probably be a composite service? See https://github.com/Setono/composite-compiler-pass
There was a problem hiding this comment.
Done — TriggerChannelResolverInterface is now a composite via setono/composite-compiler-pass. CompositeTriggerChannelResolver merges every service tagged setono_sylius_loyalty.trigger_channel_resolver (de-duplicated by channel code); DefaultTriggerChannelResolver is one tagged contributor, the interface aliases the composite, and the interface is registered for autoconfiguration so a project's own resolver is tagged automatically.
The second action trigger — a product-review-approved bonus — plus the channel resolver that context-less triggers need. Stacked on #29 (reuses
ActionPointsAwarder).What it adds
TriggerChannelResolverInterface(+DefaultTriggerChannelResolver) — resolves which channels a trigger without a shop-channel context awards on: the customer's existing loyalty-account channels (your call). An extension point;LoyaltyAccountRepositorygainedfindByCustomer.ReviewApprovedStateMachineListener— awards theproduct_review_approvedrules when a review is accepted, on each resolved channel. Approval is an admin transition (no shop channel), so it uses the resolver. Bridges both state-machine adapters like the order-award listener (workflow tag + winzou callback via the extension prepend); idempotency + a per-(review, channel) source identifier cover overlap.Tests
DefaultTriggerChannelResolverTest(resolves account channels; empty for no account).ReviewApprovedStateMachineListenerTest(both adapters + non-review/non-customer guards); the extension test now asserts the review winzou callback.ProductReviewInterfaceis Core). Green locally: PHPStan max, ECS, Rector, unit 126 + functional 55, lint:container, normalize/validate.