All files / services/crawler-service-api/src/models CrawlerConfig.js

100% Statements 71/71
100% Branches 1/1
100% Functions 0/0
100% Lines 71/71

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 711x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x
const mongoose = require('mongoose');
 
const crawlerConfigSchema = new mongoose.Schema({
  userId: {
    type: String,
    required: true,
    index: true,
  },
  organizationId: {
    type: String,
    required: true,
    index: true,
  },
  name: {
    type: String,
    required: true,
  },
  description: {
    type: String,
    default: '',
  },
  // Prompt utilisé pour l'évaluation de pertinence des pages (evaluatePage).
  // Le raffinage (instruction de synthèse) est porté par les destinations de la config.
  prompt: {
    type: String,
    default: '',
  },
  startUrl: {
    type: String,
    default: '',
  },
  config: {
    maxPages: { type: Number, default: 10 },
    maxDepth: { type: Number, default: 3 },
    
    pageThreshold: { type: Number, default: 60 },
    linkThreshold: { type: Number, default: 40 },
    
    crawlDelay: { type: Number, default: 100 },
    
    llmModel: { type: String, default: 'deepseek/deepseek-v4-flash' },
    // Raisonnement du modèle pour l'évaluation de pertinence (qualité vs coût).
    reasoning: { type: Boolean, default: true },
    // Plafond optionnel de tokens de sortie ; null = pas de plafond (modèle libre).
    maxTokens: { type: Number, default: null },
    sameDomain: { type: Boolean, default: false },
    enableSynthesis: { type: Boolean, default: true },
    
    // Destinations pour l'envoi des résultats raffinés (remplace le router)
    // Format: [{ type: "assertion-kb"|"data-kb"|"api"|"display", id?: "...", prompt?: "...", refinement?: { mode?, spec?, llmModel? } }, ...]
    // 'display' : aucune cible (id absent) → résultat raffiné conservé en output du job.
    // Les destinations sont transmises telles quelles au workflow-service-api qui valide
    // et construit les plans de raffinage (voir buildRefinementPlans).
    destinations: { type: mongoose.Schema.Types.Mixed, default: [] },
  },
  isActive: {
    type: Boolean,
    default: true,
  },
  runCount: {
    type: Number,
    default: 0,
  },
}, {
  timestamps: true,
});
 
crawlerConfigSchema.index({ userId: 1, createdAt: -1 });
crawlerConfigSchema.index({ organizationId: 1, createdAt: -1 });
 
module.exports = mongoose.model('CrawlerConfig', crawlerConfigSchema, 'crawlerconfigs');