Skip to content

Commit 4ac4167

Browse files
authored
Merge pull request #103 from techdiary-dev/kingrayhan/socket
Kingrayhan/socket
2 parents 45a04c3 + 9f59d15 commit 4ac4167

5 files changed

Lines changed: 61 additions & 35 deletions

File tree

src/backend/models/domain-models.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ export enum DIRECTORY_NAME {
196196
}
197197

198198
export interface Reaction {
199+
id?: string;
199200
resource_id: string;
200201
resource_type: "ARTICLE" | "COMMENT" | "GIST";
201202
reaction_type: REACTION_TYPE;

src/backend/services/comment.action.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,11 @@ export const createMyComment = async (
4747

4848
await assertCommentResourceExists(resource_id, resource_type);
4949

50+
const commentId = input.comment_id ?? crypto.randomUUID();
51+
5052
const created = await persistenceRepository.comment.insert([
5153
{
52-
id: input.comment_id ?? crypto.randomUUID(),
54+
id: commentId,
5355
body,
5456
resource_id,
5557
resource_type,
@@ -59,6 +61,7 @@ export const createMyComment = async (
5961

6062
inngest
6163
.send({
64+
id: `notif:comment:${commentId}`,
6265
name: "app/notification.requested",
6366
data: {
6467
actor_id: sessionId,
@@ -72,7 +75,7 @@ export const createMyComment = async (
7275
console.error("[inngest] Failed to send notification event:", err);
7376
});
7477

75-
void publishMessage(
78+
await publishMessage(
7679
`resource.${resource_type}.${resource_id}`,
7780
REALTIME_PUSHER_EVENTS.COMMENT_CREATED,
7881
{ scope: "comments" },
@@ -107,7 +110,7 @@ export const updateMyComment = async (
107110
data: { body: input.body, updated_at: new Date() },
108111
});
109112

110-
void publishMessage(
113+
await publishMessage(
111114
`resource.${existing.resource_type}.${existing.resource_id}`,
112115
REALTIME_PUSHER_EVENTS.COMMENT_UPDATED,
113116
{ scope: "comments" },
@@ -165,7 +168,7 @@ export const deleteMyComment = async (
165168
where: inArray("id", ids),
166169
});
167170

168-
void publishMessage(
171+
await publishMessage(
169172
`resource.${root.resource_type}.${root.resource_id}`,
170173
REALTIME_PUSHER_EVENTS.COMMENT_DELETED,
171174
{ scope: "comments" },

src/backend/services/reaction.actions.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,12 @@ export async function toogleReaction(
6969
};
7070
}
7171

72+
const reactionId = crypto.randomUUID();
73+
7274
// If reaction does not exist, create it
7375
await persistenceRepository.reaction.insert([
7476
{
77+
id: reactionId,
7578
resource_id: input.resource_id,
7679
resource_type: input.resource_type,
7780
reaction_type: input.reaction_type,
@@ -83,6 +86,7 @@ export async function toogleReaction(
8386
// Send notification event for insert path only (log errors, don't fail mutation)
8487
inngest
8588
.send({
89+
id: `notif:reaction:${reactionId}`,
8690
name: "app/notification.requested",
8791
data: {
8892
actor_id: sessionUserId,

src/lib/inngest.ts

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,13 @@ export const persistNotificationFn = inngest.createFunction(
122122
id: "persist-notification",
123123
triggers: [{ event: "app/notification.requested" }],
124124
},
125-
async ({ event }: { event: { data: NotificationEventData } }) => {
125+
async ({ event, step }) => {
126126
const parsed = notificationEventSchema.safeParse(event.data);
127127
if (!parsed.success) {
128128
return { skipped: true, reason: "invalid-notification-payload" };
129129
}
130130

131-
let data = parsed.data;
131+
let data: NotificationEventData = parsed.data;
132132

133133
if (data.reaction_request && data.actor_id) {
134134
const built = await buildPersistableNotification({
@@ -182,23 +182,46 @@ export const persistNotificationFn = inngest.createFunction(
182182
return { skipped: true, reason: "self-notification" };
183183
}
184184

185-
await persistenceRepository.notification.insert([
186-
{
187-
recipient_id: data.recipient_id,
188-
actor_id: data.actor_id ?? null,
189-
type: data.type as NotificationType,
190-
payload: (data.payload ?? null) as NotificationPayload | null,
191-
created_at: new Date(),
192-
},
193-
]);
185+
const row = {
186+
recipient_id: data.recipient_id,
187+
actor_id: data.actor_id ?? null,
188+
type: data.type as NotificationType,
189+
payload: (data.payload ?? null) as NotificationPayload | null,
190+
created_at: new Date(),
191+
};
194192

195-
// Broadcast a lightweight signal so the recipient's browser can invalidate
196-
// its TanStack Query caches without polling.
197-
await publishMessage(
198-
`private-user.${data.recipient_id}`,
199-
REALTIME_PUSHER_EVENTS.NOTIFICATION_NEW,
200-
{ scope: "notifications" },
201-
);
193+
await step.run("insert-notification-row", async () => {
194+
try {
195+
const result = await persistenceRepository.notification.insert([row]);
196+
return {
197+
insertedRow: result?.rows?.[0],
198+
};
199+
} catch (err) {
200+
return {
201+
insertedRow: null,
202+
message: "Failed to insert notification row",
203+
};
204+
}
205+
});
206+
207+
await step.run("publish-notification-realtime", async () => {
208+
try {
209+
await publishMessage(
210+
`private-user.${data.recipient_id}`,
211+
REALTIME_PUSHER_EVENTS.NOTIFICATION_NEW,
212+
{ scope: "notifications" },
213+
);
214+
return {
215+
published: true,
216+
message: "Notification published successfully",
217+
};
218+
} catch (err) {
219+
return {
220+
published: false,
221+
message: "Failed to publish notification",
222+
};
223+
}
224+
});
202225

203226
return { success: true };
204227
},

src/lib/pusher/pusher.server.ts

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,12 @@ export async function publishMessage(
3636
channel: string,
3737
event: RealtimePusherEvent,
3838
data: Record<string, unknown> = {},
39-
): Promise<void> {
40-
console.log(`
41-
[pusher] Publishing message to channel ${channel} with event ${event} and data ${JSON.stringify(data)}
42-
`);
43-
44-
pusherServer
45-
?.trigger(channel, event, data)
46-
.then((data) => {
47-
console.log("[pusher] Published message successfully");
48-
})
49-
.catch((err) => {
50-
console.error("[pusher] Failed to publish message:", JSON.stringify(err));
51-
});
39+
) {
40+
if (!pusherServer) return;
41+
try {
42+
return await pusherServer.trigger(channel, event, data);
43+
} catch (err) {
44+
console.error("[pusher] Failed to publish message:", JSON.stringify(err));
45+
return null;
46+
}
5247
}

0 commit comments

Comments
 (0)