refactor: replace dynamic imports with event bus pattern

Replace 12 dynamic `await import()` calls with domain events emitted
through the existing systemEvents bus, breaking circular dependencies
between services (economy/inventory/leveling -> quest, * -> dashboard).

- Add `emitAsync` to SystemEventEmitter for sequential listener awaiting,
  preserving DB transaction atomicity for quest progress tracking
- Add DOMAIN event constants (BALANCE_CHANGED, XP_GAINED, ITEM_COLLECTED,
  ITEM_USED, TRANSFER_COMPLETED, DAILY_CLAIMED, TRIVIA_*, EXAM_PASSED)
- Create shared/lib/eventWiring.ts to register all domain event listeners
- Convert quest event calls to `await systemEvents.emitAsync()` (5 calls)
- Convert dashboard event calls to `systemEvents.emit()` fire-and-forget (5 calls)
- Convert exam.service.ts userService import to static import (1 call)
- Convert dashboard.service.ts events import to static import (1 call)
- Leave inventory.service.ts validateAndExecuteEffect import unchanged (Task 3)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
syntaxbullet
2026-03-18 12:59:15 +01:00
parent a96c6caa49
commit 5863418ae9
9 changed files with 120 additions and 45 deletions

View File

@@ -1,6 +1,7 @@
import { DrizzleClient } from "@shared/db/DrizzleClient";
import { users, transactions, moderationCases, inventory, lootdrops, items, type User } from "@db/schema";
import { desc, sql, gte, eq } from "drizzle-orm";
import { systemEvents, EVENTS } from "@shared/lib/events";
import type { RecentEvent, ActivityData } from "./dashboard.types";
import { TransactionType } from "@shared/lib/constants";
@@ -139,7 +140,6 @@ export const dashboardService = {
// Broadcast to WebSocket clients
try {
const { systemEvents, EVENTS } = await import("@shared/lib/events");
systemEvents.emit(EVENTS.DASHBOARD.NEW_EVENT, {
...fullEvent,
timestamp: (fullEvent.timestamp instanceof Date)