Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
5c03bff
refactor(autoRebalancer): add WebSocketServer import from ws package
Jaydbrown Jun 20, 2026
39ef5de
refactor(autoRebalancer): declare private wss field initialized to null
Jaydbrown Jun 20, 2026
ccff407
refactor(autoRebalancer): add setWss() method stub for wss injection
Jaydbrown Jun 20, 2026
a8e25fa
refactor(autoRebalancer): implement setWss() body
Jaydbrown Jun 20, 2026
7e151eb
docs(autoRebalancer): add JSDoc explaining setWss() contract
Jaydbrown Jun 20, 2026
a9722ff
feat(autoRebalancer): add hasWss() helper for tests and health checks
Jaydbrown Jun 20, 2026
9e0abe1
refactor(autoRebalancer): add WebSocket broadcasting section divider
Jaydbrown Jun 20, 2026
9f1feac
feat(autoRebalancer): add notifyClients() signature and null guard
Jaydbrown Jun 20, 2026
94fa34f
feat(autoRebalancer): build portfolio_update JSON message in notifyCl…
Jaydbrown Jun 20, 2026
22aa1b0
feat(autoRebalancer): broadcast to wss.clients in notifyClients()
Jaydbrown Jun 20, 2026
00314cb
feat(autoRebalancer): add logger.info call in notifyClients()
Jaydbrown Jun 20, 2026
8c45299
feat(autoRebalancer): add broadcastToAllClients() signature and null …
Jaydbrown Jun 20, 2026
20f5f08
feat(autoRebalancer): add market_update JSON message in broadcastToAl…
Jaydbrown Jun 20, 2026
17d84fa
feat(autoRebalancer): implement broadcast loop and logger in broadcas…
Jaydbrown Jun 20, 2026
04b93a7
docs(autoRebalancer): add JSDoc for broadcastToAllClients()
Jaydbrown Jun 20, 2026
6d94594
docs(autoRebalancer): add JSDoc for notifyClients()
Jaydbrown Jun 20, 2026
cc1b99a
style(autoRebalancer): normalise trailing newline
Jaydbrown Jun 20, 2026
42e3965
refactor(index): remove unused RebalancingService import
Jaydbrown Jun 20, 2026
5040fcb
refactor(index): remove dead block comment for legacy rebalancing ser…
Jaydbrown Jun 20, 2026
72188fa
refactor(index): remove try-catch opening line for dead service startup
Jaydbrown Jun 20, 2026
480c476
refactor(index): remove const rebalancingService instantiation
Jaydbrown Jun 20, 2026
2eb53b9
refactor(index): remove rebalancingService.start() call
Jaydbrown Jun 20, 2026
49ac7a1
refactor(index): remove REBALANCING-SERVICE console.log
Jaydbrown Jun 20, 2026
2ced3c5
refactor(index): remove catch (error) clause of dead try-catch
Jaydbrown Jun 20, 2026
715ac40
refactor(index): remove console.error from dead catch clause
Jaydbrown Jun 20, 2026
def21b1
refactor(index): remove orphaned closing brace of dead try-catch
Jaydbrown Jun 20, 2026
761dde2
feat(index): wire wss into autoRebalancer.setWss() after WebSocket se…
Jaydbrown Jun 20, 2026
51f244d
style(index): improve wss-wiring comment for clarity
Jaydbrown Jun 20, 2026
f52dab4
style(index): normalise trailing newline
Jaydbrown Jun 20, 2026
61cfbcb
feat: delete legacy RebalancingService — broadcast methods migrated t…
Jaydbrown Jun 20, 2026
8a36bb7
fix: remove RebalancingService, wire wss into AutoRebalancerService
Jaydbrown Jun 24, 2026
fed68fc
feat: migrate WebSocket broadcast methods into AutoRebalancerService
Jaydbrown Jun 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 2 additions & 9 deletions backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { v1Router } from './api/v1Router.js'
import { errorHandler, notFound } from './middleware/errorHandler.js'
import { legacyApiDeprecation } from './middleware/legacyApiDeprecation.js'
import { globalRateLimiter } from './middleware/rateLimit.js'
import { RebalancingService } from './monitoring/rebalancer.js'
import { AutoRebalancerService } from './services/autoRebalancer.js'
import { logger } from './utils/logger.js'
import { databaseService } from './services/databaseService.js'
Expand Down Expand Up @@ -226,14 +225,8 @@ wss.on('connection', (ws) => {
})
})

// Start existing rebalancing service (now queue-backed, no cron)
try {
const rebalancingService = new RebalancingService(wss)
rebalancingService.start()
console.log('[REBALANCING-SERVICE] Monitoring service started (queue-backed)')
} catch (error) {
console.error('Failed to start rebalancing service:', error)
}
// Wire wss into autoRebalancer so it can push real-time portfolio events to clients
autoRebalancer.setWss(wss)

// Start server
server.listen(port, async () => {
Expand Down
162 changes: 0 additions & 162 deletions backend/src/monitoring/rebalancer.ts

This file was deleted.

54 changes: 54 additions & 0 deletions backend/src/services/autoRebalancer.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { WebSocketServer } from 'ws'
import { StellarService } from './stellar.js'
import { ReflectorService } from './reflector.js'
import { rebalanceHistoryService } from './serviceContainer.js'
Expand All @@ -12,6 +13,7 @@ export class AutoRebalancerService {
private stellarService: StellarService
private reflectorService: ReflectorService
private isRunning = false
private wss: WebSocketServer | null = null

// Configuration (kept for getStatus() compatibility)
private readonly CHECK_INTERVAL = 30 * 60 * 1000 // 30 minutes
Expand Down Expand Up @@ -136,4 +138,56 @@ export class AutoRebalancerService {
}
}
}

/**
* Inject the WebSocket server so portfolio events can be pushed to clients.
* Called from index.ts once wss is available.
*/
setWss(wss: WebSocketServer): void {
this.wss = wss
}

/**
* Returns true once setWss() has been called.
*/
hasWss(): boolean {
return this.wss !== null
}

// ─── WebSocket broadcasting ──────────────────────────────────────────────

/**
* Push a portfolio-specific event to all connected WebSocket clients.
*/
notifyClients(portfolioId: string, event: string, data: Record<string, unknown> = {}): void {
if (!this.wss) return
const message = JSON.stringify({
type: 'portfolio_update',
portfolioId,
event,
data,
timestamp: new Date().toISOString(),
})
this.wss.clients.forEach(client => {
if (client.readyState === 1) client.send(message)
})
logger.info(`[AUTO-REBALANCER] Pushed "${event}" event to WebSocket clients`, { portfolioId })
}

/**
* Broadcast a market-wide event to all connected WebSocket clients.
*/
broadcastToAllClients(event: string, data: Record<string, unknown> = {}): void {
if (!this.wss) return
const message = JSON.stringify({
type: 'market_update',
event,
data,
timestamp: new Date().toISOString(),
})
this.wss.clients.forEach(client => {
if (client.readyState === 1) client.send(message)
})
logger.info(`[AUTO-REBALANCER] Broadcast "${event}" to all WebSocket clients`)
}
}
Loading