"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var PostInterviewProcessor_1; Object.defineProperty(exports, "__esModule", { value: true }); exports.PostInterviewProcessor = void 0; const bullmq_1 = require("@nestjs/bullmq"); const common_1 = require("@nestjs/common"); const bullmq_2 = require("bullmq"); const prisma_service_1 = require("../prisma/prisma.service"); let PostInterviewProcessor = PostInterviewProcessor_1 = class PostInterviewProcessor extends bullmq_1.WorkerHost { prisma; logger = new common_1.Logger(PostInterviewProcessor_1.name); constructor(prisma) { super(); this.prisma = prisma; } async process(job) { const { workflowId, episodeId, taskType } = job.data; this.logger.log(`Processing post-interview task ${taskType} for workflow ${workflowId}`); const task = await this.prisma.postInterviewTask.findUnique({ where: { workflowId_taskType: { workflowId, taskType, }, }, }); if (!task) { throw new Error(`Task ${taskType} not found for workflow ${workflowId}`); } if (task.status === "completed") { this.logger.log(`Task ${taskType} is already completed; skipping`); return { success: true }; } await this.prisma.postInterviewTask.update({ where: { workflowId_taskType: { workflowId, taskType, }, }, data: { status: "in_progress", errorMessage: null, }, }); try { const metadata = await this.executeTask(taskType, episodeId, workflowId); await this.prisma.postInterviewTask.update({ where: { workflowId_taskType: { workflowId, taskType, }, }, data: { status: "completed", completedAt: new Date(), errorMessage: null, metadata: metadata, }, }); await this.recomputeWorkflowStatus(workflowId); return { success: true }; } catch (error) { const message = error instanceof Error ? error.message : "Unknown post-interview processing error"; await this.prisma.postInterviewTask.update({ where: { workflowId_taskType: { workflowId, taskType, }, }, data: { status: "failed", errorMessage: message, }, }); await this.recomputeWorkflowStatus(workflowId); throw error; } } async executeTask(taskType, episodeId, workflowId) { switch (taskType) { case "send_recording_link": { const recordingUrl = `https://MicProtocol.local/recordings/${episodeId}`; this.logger.log(`Prepared recording link for episode ${episodeId}`); return { recordingUrl, deliveryChannel: "email", generatedAt: new Date().toISOString(), }; } case "request_testimonial": { const testimonialFormUrl = `https://MicProtocol.local/testimonials/${episodeId}`; this.logger.log(`Prepared testimonial request for episode ${episodeId}`); return { testimonialFormUrl, requestedAt: new Date().toISOString(), }; } case "provide_clips": { const approvedClips = await this.prisma.clip.count({ where: { episodeId, isApproved: true, }, }); this.logger.log(`Found ${approvedClips} approved clips for episode ${episodeId}`); return { approvedClips, handoffAt: new Date().toISOString(), }; } case "schedule_check_in": { const workflow = await this.prisma.postInterviewWorkflow.findUnique({ where: { id: workflowId }, select: { checkInDueAt: true }, }); return { checkInDueAt: workflow?.checkInDueAt?.toISOString() || null, scheduledAt: new Date().toISOString(), }; } case "track_promotion": { const completedPromoTasks = await this.prisma.promoTask.count({ where: { episodeId, completedAt: { not: null, }, }, }); this.logger.log(`Promotion tracking captured ${completedPromoTasks} completed promo tasks for episode ${episodeId}`); return { completedPromoTasks, capturedAt: new Date().toISOString(), }; } default: throw new Error(`Unsupported post-interview task type: ${taskType}`); } } async recomputeWorkflowStatus(workflowId) { const tasks = await this.prisma.postInterviewTask.findMany({ where: { workflowId }, select: { status: true, errorMessage: true }, }); if (tasks.length === 0) { return; } const hasFailedTask = tasks.some((task) => task.status === "failed"); const allCompleted = tasks.every((task) => task.status === "completed"); if (hasFailedTask) { const firstError = tasks.find((task) => task.errorMessage)?.errorMessage || null; await this.prisma.postInterviewWorkflow.update({ where: { id: workflowId }, data: { status: "failed", lastError: firstError, completedAt: null, }, }); return; } if (allCompleted) { await this.prisma.postInterviewWorkflow.update({ where: { id: workflowId }, data: { status: "completed", completedAt: new Date(), lastError: null, }, }); return; } await this.prisma.postInterviewWorkflow.update({ where: { id: workflowId }, data: { status: "running", completedAt: null, lastError: null, }, }); } onCompleted(job) { this.logger.log(`Post-interview job ${job.id} completed`); } onFailed(job, error) { this.logger.error(`Post-interview job ${job.id} failed: ${error.message}`, error.stack); } }; exports.PostInterviewProcessor = PostInterviewProcessor; __decorate([ (0, bullmq_1.OnWorkerEvent)("completed"), __metadata("design:type", Function), __metadata("design:paramtypes", [bullmq_2.Job]), __metadata("design:returntype", void 0) ], PostInterviewProcessor.prototype, "onCompleted", null); __decorate([ (0, bullmq_1.OnWorkerEvent)("failed"), __metadata("design:type", Function), __metadata("design:paramtypes", [bullmq_2.Job, Error]), __metadata("design:returntype", void 0) ], PostInterviewProcessor.prototype, "onFailed", null); exports.PostInterviewProcessor = PostInterviewProcessor = PostInterviewProcessor_1 = __decorate([ (0, bullmq_1.Processor)("post-interview", { concurrency: 4, }), __metadata("design:paramtypes", [prisma_service_1.PrismaService]) ], PostInterviewProcessor); //# sourceMappingURL=post-interview.processor.js.map