From 9bc5d0c784bf745508070444ff35d710143cabd9 Mon Sep 17 00:00:00 2001 From: dongmucat <1127093059@qq.com> Date: Mon, 27 Apr 2026 16:51:40 +0800 Subject: [PATCH] feat(subscription): notify subscribers on skill publish and version yank --- .../listener/NotificationEventListener.java | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/server/skillhub-app/src/main/java/com/iflytek/skillhub/listener/NotificationEventListener.java b/server/skillhub-app/src/main/java/com/iflytek/skillhub/listener/NotificationEventListener.java index 5134e4dd..74ad10d8 100644 --- a/server/skillhub-app/src/main/java/com/iflytek/skillhub/listener/NotificationEventListener.java +++ b/server/skillhub-app/src/main/java/com/iflytek/skillhub/listener/NotificationEventListener.java @@ -7,6 +7,7 @@ import com.iflytek.skillhub.domain.namespace.NamespaceRepository; import com.iflytek.skillhub.domain.skill.Skill; import com.iflytek.skillhub.domain.skill.SkillRepository; import com.iflytek.skillhub.domain.skill.SkillVersionRepository; +import com.iflytek.skillhub.domain.social.SkillSubscriptionService; import com.iflytek.skillhub.notification.domain.NotificationCategory; import com.iflytek.skillhub.notification.service.NotificationDispatcher; import org.slf4j.Logger; @@ -29,6 +30,7 @@ public class NotificationEventListener { private final NamespaceRepository namespaceRepository; private final RecipientResolver recipientResolver; private final NotificationDispatcher dispatcher; + private final SkillSubscriptionService skillSubscriptionService; private final ObjectMapper objectMapper; public NotificationEventListener(SkillRepository skillRepository, @@ -36,12 +38,14 @@ public class NotificationEventListener { NamespaceRepository namespaceRepository, RecipientResolver recipientResolver, NotificationDispatcher dispatcher, + SkillSubscriptionService skillSubscriptionService, ObjectMapper objectMapper) { this.skillRepository = skillRepository; this.skillVersionRepository = skillVersionRepository; this.namespaceRepository = namespaceRepository; this.recipientResolver = recipientResolver; this.dispatcher = dispatcher; + this.skillSubscriptionService = skillSubscriptionService; this.objectMapper = objectMapper; } @@ -61,6 +65,50 @@ public class NotificationEventListener { }); } + @Async("skillhubEventExecutor") + @TransactionalEventListener + public void onSkillPublishedForSubscribers(SkillPublishedEvent event) { + skillRepository.findById(event.skillId()).ifPresent(skill -> { + List subscribers = skillSubscriptionService.findSubscribersBySkillId(event.skillId()); + if (subscribers.isEmpty()) { + return; + } + String title = "Skill updated: " + skillDisplayName(skill); + Map body = bodyWithSkill(skill); + versionLabel(event.versionId(), body); + String json = toJson(body); + for (String subscriberId : subscribers) { + if (subscriberId.equals(event.publisherId())) { + continue; // skip the publisher + } + dispatcher.dispatch(subscriberId, NotificationCategory.PUBLISH, + "SUBSCRIPTION_NEW_VERSION", title, json, "SKILL", event.skillId()); + } + }); + } + + @Async("skillhubEventExecutor") + @TransactionalEventListener + public void onSkillVersionYankedForSubscribers(SkillVersionYankedEvent event) { + skillRepository.findById(event.skillId()).ifPresent(skill -> { + List subscribers = skillSubscriptionService.findSubscribersBySkillId(event.skillId()); + if (subscribers.isEmpty()) { + return; + } + String title = "Skill version yanked: " + skillDisplayName(skill); + Map body = bodyWithSkill(skill); + versionLabel(event.versionId(), body); + String json = toJson(body); + for (String subscriberId : subscribers) { + if (subscriberId.equals(event.actorUserId())) { + continue; // skip the actor + } + dispatcher.dispatch(subscriberId, NotificationCategory.PUBLISH, + "SUBSCRIPTION_VERSION_YANKED", title, json, "SKILL", event.skillId()); + } + }); + } + @Async("skillhubEventExecutor") @TransactionalEventListener public void onReviewSubmitted(ReviewSubmittedEvent event) {