managarten/apps-archived/wisekeep/apps/backend/src/websocket/progress.gateway.ts
Till-JS 61d181fbc2 chore: archive inactive projects to apps-archived/
Move inactive projects out of active workspace:
- bauntown (community website)
- maerchenzauber (AI story generation)
- memoro (voice memo app)
- news (news aggregation)
- nutriphi (nutrition tracking)
- reader (reading app)
- uload (URL shortener)
- wisekeep (AI wisdom extraction)

Update CLAUDE.md documentation:
- Add presi to active projects
- Document archived projects section
- Update workspace configuration

Archived apps can be re-activated by moving back to apps/

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 07:03:59 +01:00

79 lines
1.7 KiB
TypeScript

import {
WebSocketGateway,
WebSocketServer,
OnGatewayConnection,
OnGatewayDisconnect,
} from '@nestjs/websockets';
import { Logger } from '@nestjs/common';
import { Server, Socket } from 'socket.io';
export interface JobUpdatePayload {
status: string;
progress?: number;
error?: string;
videoInfo?: {
id: string;
title: string;
channel: string;
thumbnail: string;
};
transcriptPath?: string;
}
@WebSocketGateway({
cors: {
origin: ['http://localhost:5173', 'http://localhost:4321', 'http://localhost:3000'],
credentials: true,
},
namespace: '/progress',
})
export class ProgressGateway implements OnGatewayConnection, OnGatewayDisconnect {
private readonly logger = new Logger(ProgressGateway.name);
@WebSocketServer()
server: Server;
handleConnection(client: Socket) {
this.logger.log(`Client connected: ${client.id}`);
// Send heartbeat every 10 seconds
const interval = setInterval(() => {
client.emit('heartbeat', { timestamp: Date.now() });
}, 10000);
client.on('disconnect', () => {
clearInterval(interval);
});
}
handleDisconnect(client: Socket) {
this.logger.log(`Client disconnected: ${client.id}`);
}
broadcastJobUpdate(jobId: string, payload: JobUpdatePayload) {
this.server.emit('job_update', {
type: 'job_update',
jobId,
...payload,
timestamp: Date.now(),
});
}
broadcastJobComplete(jobId: string, payload: JobUpdatePayload) {
this.server.emit('job_complete', {
type: 'job_complete',
jobId,
...payload,
timestamp: Date.now(),
});
}
broadcastJobError(jobId: string, error: string) {
this.server.emit('job_error', {
type: 'job_error',
jobId,
error,
timestamp: Date.now(),
});
}
}