feat: implement real-time dashboard updates via WebSockets

This commit is contained in:
syntaxbullet
2026-01-08 21:01:33 +01:00
parent fff90804c0
commit 1251df286e
7 changed files with 267 additions and 73 deletions

View File

@@ -153,4 +153,33 @@ describe("dashboardService", () => {
);
});
});
describe("recordEvent", () => {
test("should emit NEW_EVENT to systemEvents", async () => {
const mockEmit = mock(() => { });
mock.module("@shared/lib/events", () => ({
systemEvents: {
emit: mockEmit,
},
EVENTS: {
DASHBOARD: {
NEW_EVENT: "dashboard:new_event",
}
}
}));
await dashboardService.recordEvent({
type: 'info',
message: 'Test Event',
icon: '🚀'
});
expect(mockEmit).toHaveBeenCalled();
const [eventName, data] = mockEmit.mock.calls[0] as any;
expect(eventName).toBe("dashboard:new_event");
expect(data.message).toBe("Test Event");
expect(data.timestamp).toBeDefined();
});
});
});

View File

@@ -126,6 +126,27 @@ export const dashboardService = {
return allEvents;
},
/**
* Records a new internal event and broadcasts it via WebSocket
*/
recordEvent: async (event: Omit<RecentEvent, 'timestamp'>): Promise<void> => {
const fullEvent: RecentEvent = {
...event,
timestamp: new Date(),
};
// Broadcast to WebSocket clients
try {
const { systemEvents, EVENTS } = await import("@shared/lib/events");
systemEvents.emit(EVENTS.DASHBOARD.NEW_EVENT, {
...fullEvent,
timestamp: fullEvent.timestamp.toISOString()
});
} catch (e) {
console.error("Failed to emit system event:", e);
}
},
};
/**

View File

@@ -61,6 +61,14 @@ export const economyService = {
description: `Transfer from ${fromUserId}`,
});
// Record dashboard event
const { dashboardService } = await import("@shared/modules/dashboard/dashboard.service");
dashboardService.recordEvent({
type: 'info',
message: `${sender.username} transferred ${amount.toLocaleString()} AU to User ID ${toUserId}`,
icon: '💸'
});
return { success: true, amount };
}, tx);
},
@@ -149,6 +157,14 @@ export const economyService = {
description: `Daily reward (Streak: ${streak})`,
});
// Record dashboard event
const { dashboardService } = await import("@shared/modules/dashboard/dashboard.service");
dashboardService.recordEvent({
type: 'success',
message: `${user.username} claimed daily reward: ${totalReward.toLocaleString()} AU`,
icon: '☀️'
});
return { claimed: true, amount: totalReward, streak, nextReadyAt, isWeekly: isWeeklyCurrent, weeklyBonus: weeklyBonusAmount };
}, tx);
},