'use strict'; const mongoose = require('mongoose'), Schema = mongoose.Schema, PartnerLogTrackerStatus = require('../helpers/constants').PartnerLogTrackerStatus; // Track processed partner logs to avoid duplicate processing const partnerLogTrackerSchema = new Schema({ // Partner and aircraft identification partnerCode: { type: String, required: true, trim: true }, // e.g., 'SATLOC' aircraftId: { type: String, required: true, trim: true }, // Partner aircraft ID customerId: { type: Schema.Types.ObjectId, ref: 'User', required: true }, // Log identification logId: { type: String, required: true, trim: true }, // Partner log ID logFileName: { type: String, required: true, trim: true }, // Log file name uploadedDate: { type: String, required: false, trim: true }, // When log was uploaded to partner system (stored as-is, timezone unknown) // Processing status with states to prevent race conditions status: { type: String, enum: Object.values(PartnerLogTrackerStatus), default: PartnerLogTrackerStatus.PENDING }, processed: { type: Boolean, default: false }, processedAt: { type: Date, required: false }, enqueuedAt: { type: Date, required: false }, // When log was enqueued for processing savedLocalFile: { type: String, required: false, trim: true }, // Filename only (path agnostic) - full path constructed from env SATLOC_STORAGE_PATH processingStartedAt: { type: Date, required: false }, // When processing started (for timeout detection) // Job matching matchedJobs: [{ assignId: { type: Schema.Types.ObjectId, ref: 'Job_Assign' }, jobId: { type: Number, ref: 'Job' }, confidence: { type: Number, default: 1.0 } // Matching confidence 0-1 }], // File processing results appFileId: { type: Schema.Types.ObjectId, ref: 'AppFile' }, // Processing metadata processTime: { type: Number, required: false }, // Processing time in ms errorMessage: { type: String, required: false }, retryCount: { type: Number, default: 0 }, // Timestamps createdAt: { type: Date, default: Date.now }, updatedAt: { type: Date, default: Date.now } }); // Unique compound index for duplicate prevention partnerLogTrackerSchema.index({ logId: 1, partnerCode: 1 }, { unique: true }); // Compound index for worker queries: status-based filtering with time-based sorting // Covers: stuck task detection, DLQ queries, status monitoring // {status: 1, updatedAt: 1} can also use {status: 1, processingStartedAt: 1} for processingStartedAt queries partnerLogTrackerSchema.index({ status: 1, updatedAt: 1, processingStartedAt: 1, createdAt: 1, retryCount: 1 }); // Compound index for customer-specific queries (admin dashboard, reports) partnerLogTrackerSchema.index({ customerId: 1, createdAt: -1 }); // Compound index for file download lookup with jobId optimization // Covers both logFileName and savedLocalFile in one index using $or query partnerLogTrackerSchema.index({ 'matchedJobs.jobId': 1, logFileName: 1, savedLocalFile: 1 }); // Single-field index for filename-only lookup (fallback when jobId not provided) // Covers both logFileName and savedLocalFile with one index partnerLogTrackerSchema.index({ logFileName: 1, savedLocalFile: 1 }); // Update the updatedAt field on save partnerLogTrackerSchema.pre('save', function (next) { this.updatedAt = new Date(); next(); }); module.exports = mongoose.model('Partner_Log_Tracker', partnerLogTrackerSchema);