feat(#115,#116): implement cron scheduler worker and WebSocket notifications

## Issues Addressed
- #115: Cron scheduler worker
- #116: Cron WebSocket notifications

## Changes

### CronSchedulerService (cron.scheduler.ts)
- Polls CronSchedule table every minute for due schedules
- Executes commands when schedules fire (placeholder for MoltBot integration)
- Updates lastRun/nextRun fields after execution
- Handles errors gracefully with logging
- Supports manual trigger for testing
- Start/stop lifecycle management

### WebSocket Integration
- Added emitCronExecuted() method to WebSocketGateway
- Emits workspace-scoped cron:executed events
- Payload includes: scheduleId, command, executedAt

### Tests
- cron.scheduler.spec.ts: 9 passing tests
- Tests cover: status, due schedule processing, manual trigger, scheduler lifecycle

## Technical Notes
- Placeholder triggerMoltBotCommand() needs actual implementation
- Uses setInterval for polling (could upgrade to cron-parser library)
- WebSocket rooms use workspace:{id} format (existing pattern)

## Files Changed
- apps/api/src/cron/cron.scheduler.ts (new)
- apps/api/src/cron/cron.scheduler.spec.ts (new)
- apps/api/src/cron/cron.module.ts (updated)
- apps/api/src/websocket/websocket.gateway.ts (updated)
This commit is contained in:
2026-01-29 23:05:39 -06:00
parent 2e6b7d4070
commit 5048d9eb01
4 changed files with 342 additions and 4 deletions

View File

@@ -162,6 +162,15 @@ export class WebSocketGateway implements OnGatewayConnection, OnGatewayDisconnec
this.logger.debug(`Emitted project:deleted to ${room}`);
}
/**
* Emit cron:executed event when a scheduled command fires
*/
emitCronExecuted(workspaceId: string, data: { scheduleId: string; command: string; executedAt: Date }): void {
const room = this.getWorkspaceRoom(workspaceId);
this.server.to(room).emit('cron:executed', data);
this.logger.debug(`Emitted cron:executed to ${room}`);
}
/**
* Get workspace room name
*/