@fidusia/question-engine-dynamic 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # @aimi/question-engine
2
+
3
+ Moteur de questions partagé pour la plateforme Aimi.
4
+
5
+ ## Installation
6
+
7
+ Le package est automatiquement disponible dans tous les projets du monorepo via npm workspaces.
8
+
9
+ ## Utilisation
10
+
11
+ ```typescript
12
+ import { QuestionEngine, resetQuestionEngine, type I18nFunctions } from "@aimi/question-engine"
13
+ import { t, getQuestionOptions } from "@/lib/i18n"
14
+
15
+ // Créer une instance avec injection de dépendances i18n
16
+ const i18n: I18nFunctions = { t, getQuestionOptions }
17
+ const engine = resetQuestionEngine(i18n)
18
+ ```
19
+
20
+ ## Structure
21
+
22
+ - `engine.ts` : Classe principale QuestionEngine
23
+ - `types.ts` : Types TypeScript
24
+ - `config-loader.ts` : Chargement de configuration
25
+ - `ai-questions-loader.ts` : Chargement des questions IA
26
+
27
+ ## Dépendances Externes
28
+
29
+ Le package nécessite que les projets consommateurs fournissent les fonctions i18n via injection :
30
+ - `t(key, params?, lang?)` : Fonction de traduction
31
+ - `getQuestionOptions(questionId, lang?)` : Récupération des options de question
32
+
33
+ ## Modification
34
+
35
+ Pour modifier QuestionEngine :
36
+ 1. Modifier les fichiers dans `packages/question-engine/src/`
37
+ 2. Tous les projets utilisent automatiquement la nouvelle version
38
+ 3. Tester dans chaque projet
39
+
40
+
41
+
42
+
43
+
@@ -0,0 +1,43 @@
1
+ import type { ModuleQuestion } from './types';
2
+ export interface AIQuestion {
3
+ id: string;
4
+ sectorId: string;
5
+ questionId: string;
6
+ questionText: string;
7
+ questionType: string;
8
+ options?: string[] | null;
9
+ placeholder?: string | null;
10
+ minValue?: number | null;
11
+ maxValue?: number | null;
12
+ conditions: Record<string, any>;
13
+ isActive: boolean;
14
+ parentQuestionId?: string | null;
15
+ nextQuestionId?: string | null;
16
+ }
17
+ /**
18
+ * Charge les questions IA actives pour un secteur et filtre selon les conditions
19
+ * Utilise l'API backend externe
20
+ */
21
+ export declare function loadAIQuestionsForSector(sectorId: string, formData: Record<string, any>): Promise<AIQuestion[]>;
22
+ /**
23
+ * Convertit une question IA en ModuleQuestion
24
+ */
25
+ export declare function convertAIQuestionToModuleQuestion(aiQuestion: AIQuestion): ModuleQuestion;
26
+ /**
27
+ * Trouve l'index d'une question dans un module
28
+ */
29
+ export declare function findQuestionIndexInModule(module: {
30
+ questions: Array<{
31
+ id: string;
32
+ }>;
33
+ }, questionId: string): number;
34
+ /**
35
+ * Charge toutes les questions IA actives pour un secteur (sans filtrage par formData)
36
+ * Utilise l'API backend externe
37
+ */
38
+ export declare function loadAllAIQuestionsForSector(sectorId: string, chatbotId?: string): Promise<AIQuestion[]>;
39
+ /**
40
+ * Vérifie si les conditions d'une question IA sont remplies par le formData
41
+ */
42
+ export declare function checkConditions(conditions: Record<string, any> | null, formData: Record<string, any>): boolean;
43
+ //# sourceMappingURL=ai-questions-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-questions-loader.d.ts","sourceRoot":"","sources":["../src/ai-questions-loader.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAgB,MAAM,SAAS,CAAC;AAE5D,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC5B,OAAO,CAAC,UAAU,EAAE,CAAC,CA2BvB;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAAC,UAAU,EAAE,UAAU,GAAG,cAAc,CAoBxF;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE;IAAE,SAAS,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,EAC5C,UAAU,EAAE,MAAM,GACjB,MAAM,CAER;AAED;;;GAGG;AACH,wBAAsB,2BAA2B,CAC/C,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,UAAU,EAAE,CAAC,CA8BvB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,EACtC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC5B,OAAO,CAgCT"}
@@ -0,0 +1,131 @@
1
+ // =====================================================
2
+ // LOADER DE QUESTIONS IA
3
+ // Charge et filtre les questions générées par IA
4
+ // Utilise une API route car le Question Engine s'exécute côté client
5
+ // =====================================================
6
+ /**
7
+ * Charge les questions IA actives pour un secteur et filtre selon les conditions
8
+ * Utilise l'API backend externe
9
+ */
10
+ export async function loadAIQuestionsForSector(sectorId, formData) {
11
+ try {
12
+ // Utiliser une route API proxy locale (même domaine)
13
+ // La route proxy dans le projet chatbot fera le pont vers le backend
14
+ const url = `/api/sectors/${sectorId}/questions/ai/active`;
15
+ const response = await fetch(url, {
16
+ method: 'POST',
17
+ headers: { 'Content-Type': 'application/json' },
18
+ body: JSON.stringify({ formData })
19
+ });
20
+ if (!response.ok) {
21
+ console.error('[AI Questions Loader] API error:', response.statusText);
22
+ return [];
23
+ }
24
+ const data = await response.json();
25
+ if (data.success) {
26
+ return data.questions || [];
27
+ }
28
+ return [];
29
+ }
30
+ catch (error) {
31
+ console.error('[AI Questions Loader] Error loading AI questions:', error);
32
+ return [];
33
+ }
34
+ }
35
+ /**
36
+ * Convertit une question IA en ModuleQuestion
37
+ */
38
+ export function convertAIQuestionToModuleQuestion(aiQuestion) {
39
+ return {
40
+ id: aiQuestion.questionId,
41
+ text: aiQuestion.questionText,
42
+ type: aiQuestion.questionType,
43
+ options: aiQuestion.options || undefined,
44
+ placeholder: aiQuestion.placeholder || undefined,
45
+ min: aiQuestion.minValue || undefined,
46
+ max: aiQuestion.maxValue || undefined,
47
+ nextInModule: aiQuestion.nextQuestionId || null,
48
+ isRequired: true,
49
+ // Préserver les métadonnées pour l'export JSON
50
+ aiQuestionMetadata: {
51
+ conditions: aiQuestion.conditions || null,
52
+ parentQuestionId: aiQuestion.parentQuestionId || null,
53
+ nextQuestionId: aiQuestion.nextQuestionId || null,
54
+ sectorId: aiQuestion.sectorId,
55
+ isActive: aiQuestion.isActive
56
+ }
57
+ };
58
+ }
59
+ /**
60
+ * Trouve l'index d'une question dans un module
61
+ */
62
+ export function findQuestionIndexInModule(module, questionId) {
63
+ return module.questions.findIndex(q => q.id === questionId);
64
+ }
65
+ /**
66
+ * Charge toutes les questions IA actives pour un secteur (sans filtrage par formData)
67
+ * Utilise l'API backend externe
68
+ */
69
+ export async function loadAllAIQuestionsForSector(sectorId, chatbotId) {
70
+ try {
71
+ // Utiliser une route API proxy locale (même domaine)
72
+ // La route proxy dans le projet chatbot fera le pont vers le backend
73
+ let url = `/api/sectors/${sectorId}/questions/ai`;
74
+ if (chatbotId) {
75
+ url += `?chatbotId=${encodeURIComponent(chatbotId)}`;
76
+ }
77
+ const response = await fetch(url, {
78
+ method: 'GET',
79
+ headers: { 'Content-Type': 'application/json' }
80
+ });
81
+ if (!response.ok) {
82
+ console.error('[AI Questions Loader] API error:', response.statusText);
83
+ return [];
84
+ }
85
+ const data = await response.json();
86
+ if (data.success) {
87
+ // Filtrer seulement les questions actives
88
+ return (data.questions || []).filter((q) => q.isActive);
89
+ }
90
+ return [];
91
+ }
92
+ catch (error) {
93
+ console.error('[AI Questions Loader] Error loading all AI questions:', error);
94
+ return [];
95
+ }
96
+ }
97
+ /**
98
+ * Vérifie si les conditions d'une question IA sont remplies par le formData
99
+ */
100
+ export function checkConditions(conditions, formData) {
101
+ // Si pas de conditions (null ou {}), la question s'affiche toujours
102
+ if (!conditions || Object.keys(conditions).length === 0) {
103
+ return true;
104
+ }
105
+ // Vérifier chaque condition
106
+ for (const [key, value] of Object.entries(conditions)) {
107
+ const formValue = formData[key];
108
+ // Si la valeur attendue est un tableau, vérifier si formValue est dans le tableau
109
+ if (Array.isArray(value)) {
110
+ if (!Array.isArray(formValue)) {
111
+ // Si formValue n'est pas un tableau mais value en est un, vérifier si formValue est dans value
112
+ if (!value.includes(formValue)) {
113
+ return false;
114
+ }
115
+ }
116
+ else {
117
+ // Si les deux sont des tableaux, vérifier si au moins un élément de formValue est dans value
118
+ if (!formValue.some((v) => value.includes(v))) {
119
+ return false;
120
+ }
121
+ }
122
+ }
123
+ else {
124
+ // Comparaison simple
125
+ if (formValue !== value) {
126
+ return false;
127
+ }
128
+ }
129
+ }
130
+ return true;
131
+ }
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Interface pour la configuration complète d'un chatbot
3
+ */
4
+ export interface ChatbotConfig {
5
+ systemIds?: {
6
+ budgetPriorityQuestionId?: string;
7
+ contactCorrectionQuestionId?: string;
8
+ continueOtherSectorsQuestionId?: string;
9
+ finalModuleId?: string;
10
+ introModuleId?: string;
11
+ continueOtherSectorsModuleId?: string;
12
+ };
13
+ priorityMappings?: Record<string, string[]>;
14
+ priorityBoosts?: Record<string, Array<{
15
+ moduleId: string;
16
+ boost: number;
17
+ }>>;
18
+ basePriorities?: Record<string, number>;
19
+ bookedProviderMappings?: Record<string, {
20
+ moduleId: string;
21
+ skipQuestion: string;
22
+ }>;
23
+ priorityToBookedProviders?: Record<string, string[]>;
24
+ priorityCalculation?: {
25
+ base?: number;
26
+ step?: number;
27
+ };
28
+ specialBehaviors?: {
29
+ budgetPriority?: {
30
+ enabled?: boolean;
31
+ filterOptionsByBookedProviders?: boolean;
32
+ };
33
+ contactCorrection?: {
34
+ enabled?: boolean;
35
+ detectEmailFrom?: string[];
36
+ };
37
+ continueOtherSectors?: {
38
+ enabled?: boolean;
39
+ skipToFinalOnNo?: boolean;
40
+ skipModulesWithPriority?: number;
41
+ insertBetweenPriorityAndNonPriority?: boolean;
42
+ };
43
+ transitions?: {
44
+ excludeModules?: string[];
45
+ };
46
+ };
47
+ dynamicParams?: Record<string, {
48
+ source: 'formData';
49
+ field?: string;
50
+ type?: 'string' | 'number';
51
+ logic?: {
52
+ type: 'conditional';
53
+ condition?: {
54
+ field: string;
55
+ operator: 'equals' | 'exists';
56
+ value?: any;
57
+ };
58
+ ifTrue?: any;
59
+ ifFalse?: any;
60
+ fallback?: {
61
+ check: string;
62
+ ifExists: any;
63
+ else: any;
64
+ };
65
+ };
66
+ }>;
67
+ }
68
+ /**
69
+ * Obtient les IDs système avec fallback vers les valeurs par défaut
70
+ */
71
+ export declare function getSystemIds(config: ChatbotConfig): {
72
+ budgetPriorityQuestionId: string;
73
+ contactCorrectionQuestionId: string;
74
+ continueOtherSectorsQuestionId: string;
75
+ finalModuleId: string;
76
+ introModuleId: string;
77
+ continueOtherSectorsModuleId: string;
78
+ };
79
+ /**
80
+ * Obtient les mappings de priorité avec fallback vers les valeurs par défaut
81
+ */
82
+ export declare function getPriorityMappings(config: ChatbotConfig): Record<string, string[]>;
83
+ /**
84
+ * Obtient les mappings de prestataires avec fallback vers les valeurs par défaut
85
+ */
86
+ export declare function getBookedProviderMappings(config: ChatbotConfig): Record<string, {
87
+ moduleId: string;
88
+ skipQuestion: string;
89
+ }>;
90
+ /**
91
+ * Obtient les priorités de base avec fallback vers les valeurs par défaut
92
+ */
93
+ export declare function getBasePriorities(config: ChatbotConfig): Record<string, number>;
94
+ /**
95
+ * Obtient les boosts de priorité avec fallback vers les valeurs par défaut
96
+ */
97
+ export declare function getPriorityBoosts(config: ChatbotConfig): Record<string, Array<{
98
+ moduleId: string;
99
+ boost: number;
100
+ }>>;
101
+ /**
102
+ * Obtient le mapping priorité -> prestataires avec fallback
103
+ */
104
+ export declare function getPriorityToBookedProviders(config: ChatbotConfig): Record<string, string[]>;
105
+ /**
106
+ * Obtient la configuration du calcul de priorité
107
+ */
108
+ export declare function getPriorityCalculation(config: ChatbotConfig): {
109
+ base: number;
110
+ step: number;
111
+ };
112
+ /**
113
+ * Obtient les comportements spéciaux avec fallbacks
114
+ */
115
+ export declare function getSpecialBehaviors(config: ChatbotConfig): {
116
+ budgetPriority: {
117
+ enabled: boolean;
118
+ filterOptionsByBookedProviders: boolean;
119
+ };
120
+ contactCorrection: {
121
+ enabled: boolean;
122
+ detectEmailFrom: string[];
123
+ };
124
+ continueOtherSectors: {
125
+ enabled: boolean;
126
+ skipToFinalOnNo: boolean;
127
+ skipModulesWithPriority: number;
128
+ insertBetweenPriorityAndNonPriority: boolean;
129
+ };
130
+ transitions: {
131
+ excludeModules: string[];
132
+ };
133
+ };
134
+ //# sourceMappingURL=config-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ import { PRIORITY_TO_MODULES, BOOKED_PROVIDER_TO_MODULE, BASE_PRIORITIES, PRIORITY_BOOSTS, PRIORITY_TO_BOOKED_PROVIDERS } from './types';
2
+ /**
3
+ * Obtient les IDs système avec fallback vers les valeurs par défaut
4
+ */
5
+ export function getSystemIds(config) {
6
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
7
+ return {
8
+ budgetPriorityQuestionId: (_b = (_a = config.systemIds) === null || _a === void 0 ? void 0 : _a.budgetPriorityQuestionId) !== null && _b !== void 0 ? _b : "budget_priority",
9
+ contactCorrectionQuestionId: (_d = (_c = config.systemIds) === null || _c === void 0 ? void 0 : _c.contactCorrectionQuestionId) !== null && _d !== void 0 ? _d : "contact_correction",
10
+ continueOtherSectorsQuestionId: (_f = (_e = config.systemIds) === null || _e === void 0 ? void 0 : _e.continueOtherSectorsQuestionId) !== null && _f !== void 0 ? _f : "continue_other_sectors_question",
11
+ finalModuleId: (_h = (_g = config.systemIds) === null || _g === void 0 ? void 0 : _g.finalModuleId) !== null && _h !== void 0 ? _h : "final",
12
+ introModuleId: (_k = (_j = config.systemIds) === null || _j === void 0 ? void 0 : _j.introModuleId) !== null && _k !== void 0 ? _k : "intro",
13
+ continueOtherSectorsModuleId: (_m = (_l = config.systemIds) === null || _l === void 0 ? void 0 : _l.continueOtherSectorsModuleId) !== null && _m !== void 0 ? _m : "continue_other_sectors",
14
+ };
15
+ }
16
+ /**
17
+ * Obtient les mappings de priorité avec fallback vers les valeurs par défaut
18
+ */
19
+ export function getPriorityMappings(config) {
20
+ return config.priorityMappings || PRIORITY_TO_MODULES;
21
+ }
22
+ /**
23
+ * Obtient les mappings de prestataires avec fallback vers les valeurs par défaut
24
+ */
25
+ export function getBookedProviderMappings(config) {
26
+ return config.bookedProviderMappings || BOOKED_PROVIDER_TO_MODULE;
27
+ }
28
+ /**
29
+ * Obtient les priorités de base avec fallback vers les valeurs par défaut
30
+ */
31
+ export function getBasePriorities(config) {
32
+ return config.basePriorities || BASE_PRIORITIES;
33
+ }
34
+ /**
35
+ * Obtient les boosts de priorité avec fallback vers les valeurs par défaut
36
+ */
37
+ export function getPriorityBoosts(config) {
38
+ return config.priorityBoosts || PRIORITY_BOOSTS;
39
+ }
40
+ /**
41
+ * Obtient le mapping priorité -> prestataires avec fallback
42
+ */
43
+ export function getPriorityToBookedProviders(config) {
44
+ return config.priorityToBookedProviders || PRIORITY_TO_BOOKED_PROVIDERS;
45
+ }
46
+ /**
47
+ * Obtient la configuration du calcul de priorité
48
+ */
49
+ export function getPriorityCalculation(config) {
50
+ var _a, _b, _c, _d;
51
+ return {
52
+ base: (_b = (_a = config.priorityCalculation) === null || _a === void 0 ? void 0 : _a.base) !== null && _b !== void 0 ? _b : -500,
53
+ step: (_d = (_c = config.priorityCalculation) === null || _c === void 0 ? void 0 : _c.step) !== null && _d !== void 0 ? _d : 100,
54
+ };
55
+ }
56
+ /**
57
+ * Obtient les comportements spéciaux avec fallbacks
58
+ */
59
+ export function getSpecialBehaviors(config) {
60
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2;
61
+ return {
62
+ budgetPriority: {
63
+ enabled: (_c = (_b = (_a = config.specialBehaviors) === null || _a === void 0 ? void 0 : _a.budgetPriority) === null || _b === void 0 ? void 0 : _b.enabled) !== null && _c !== void 0 ? _c : true,
64
+ filterOptionsByBookedProviders: (_f = (_e = (_d = config.specialBehaviors) === null || _d === void 0 ? void 0 : _d.budgetPriority) === null || _e === void 0 ? void 0 : _e.filterOptionsByBookedProviders) !== null && _f !== void 0 ? _f : true,
65
+ },
66
+ contactCorrection: {
67
+ enabled: (_j = (_h = (_g = config.specialBehaviors) === null || _g === void 0 ? void 0 : _g.contactCorrection) === null || _h === void 0 ? void 0 : _h.enabled) !== null && _j !== void 0 ? _j : true,
68
+ detectEmailFrom: (_m = (_l = (_k = config.specialBehaviors) === null || _k === void 0 ? void 0 : _k.contactCorrection) === null || _l === void 0 ? void 0 : _l.detectEmailFrom) !== null && _m !== void 0 ? _m : ["Par email", "contact_email"],
69
+ },
70
+ continueOtherSectors: {
71
+ enabled: (_q = (_p = (_o = config.specialBehaviors) === null || _o === void 0 ? void 0 : _o.continueOtherSectors) === null || _p === void 0 ? void 0 : _p.enabled) !== null && _q !== void 0 ? _q : true,
72
+ skipToFinalOnNo: (_t = (_s = (_r = config.specialBehaviors) === null || _r === void 0 ? void 0 : _r.continueOtherSectors) === null || _s === void 0 ? void 0 : _s.skipToFinalOnNo) !== null && _t !== void 0 ? _t : true,
73
+ skipModulesWithPriority: (_w = (_v = (_u = config.specialBehaviors) === null || _u === void 0 ? void 0 : _u.continueOtherSectors) === null || _v === void 0 ? void 0 : _v.skipModulesWithPriority) !== null && _w !== void 0 ? _w : 0,
74
+ insertBetweenPriorityAndNonPriority: (_z = (_y = (_x = config.specialBehaviors) === null || _x === void 0 ? void 0 : _x.continueOtherSectors) === null || _y === void 0 ? void 0 : _y.insertBetweenPriorityAndNonPriority) !== null && _z !== void 0 ? _z : true,
75
+ },
76
+ transitions: {
77
+ excludeModules: (_2 = (_1 = (_0 = config.specialBehaviors) === null || _0 === void 0 ? void 0 : _0.transitions) === null || _1 === void 0 ? void 0 : _1.excludeModules) !== null && _2 !== void 0 ? _2 : ["intro", "final", "continue_other_sectors"],
78
+ },
79
+ };
80
+ }
@@ -0,0 +1,81 @@
1
+ import type { QuestionModule, ModuleQuestion, QueueState, AnsweredQuestion, UserPriority, I18nFunctions } from "./types";
2
+ import type { ChatbotConfig } from './config-loader';
3
+ export declare class QuestionEngine {
4
+ private modules;
5
+ private state;
6
+ private listeners;
7
+ private advancedByTrigger;
8
+ private aiQuestionsCache;
9
+ private config;
10
+ private i18n;
11
+ private chatbotId;
12
+ constructor(i18n: I18nFunctions);
13
+ /**
14
+ * Définit l'ID du chatbot pour filtrer les questions IA
15
+ */
16
+ setChatbotId(chatbotId: string | undefined): void;
17
+ private createInitialState;
18
+ registerModule(module: QuestionModule): void;
19
+ registerModules(modules: QuestionModule[]): void;
20
+ /**
21
+ * Définit la configuration du chatbot
22
+ * Doit être appelée avant initialize() pour que la configuration soit utilisée
23
+ */
24
+ setConfig(config: ChatbotConfig): void;
25
+ initialize(): Promise<void>;
26
+ reset(): void;
27
+ restoreState(savedState: QueueState): Promise<void>;
28
+ private buildQueue;
29
+ private buildModuleQuestions;
30
+ /**
31
+ * Charge toutes les questions IA pour tous les secteurs une seule fois
32
+ * Utilise la version serveur si disponible (API routes), sinon la version fetch (client)
33
+ * OU extrait depuis les métadonnées des modules si disponibles (pour JSON)
34
+ */
35
+ private loadAllAIQuestions;
36
+ /**
37
+ * Extrait les questions IA depuis les métadonnées des modules (pour import JSON)
38
+ * Retourne une Map<sectorId, AIQuestion[]>
39
+ */
40
+ private extractAIQuestionsFromModules;
41
+ /**
42
+ * Injecte les questions IA depuis le cache selon les conditions actuelles
43
+ * Évite les doublons en vérifiant si la question est déjà dans la queue
44
+ * Gère l'injection récursive des questions IA qui dépendent d'autres questions IA
45
+ */
46
+ private injectAIQuestionsFromCache;
47
+ private shouldHideModule;
48
+ private evaluateModuleTrigger;
49
+ private activateFirstQuestion;
50
+ getCurrentQuestion(): ModuleQuestion | null;
51
+ getCurrentModule(): QuestionModule | null;
52
+ getModuleById(moduleId: string): QuestionModule | null;
53
+ private checkHasQuestionSkip;
54
+ private getSkipDestination;
55
+ submitAnswer(answer: string | string[] | number | boolean): Promise<ModuleQuestion | null>;
56
+ private generateDynamicSubQuestions;
57
+ private generateSubQuestionsFromFormData;
58
+ private getNextQuestionId;
59
+ private advanceToNextModule;
60
+ private executeQuestionTriggers;
61
+ private evaluateQuestionTrigger;
62
+ private executeAction;
63
+ applyUserPriority(priority: UserPriority): void;
64
+ private recalculateQueue;
65
+ getState(): QueueState;
66
+ getFormData(): Record<string, any>;
67
+ getAnsweredQuestions(): AnsweredQuestion[];
68
+ getProgress(): {
69
+ current: number;
70
+ total: number;
71
+ percent: number;
72
+ };
73
+ getCurrentModuleName(): string;
74
+ isComplete(): boolean;
75
+ private applyPriorityOrder;
76
+ subscribe(listener: (state: QueueState) => void): () => void;
77
+ private notifyListeners;
78
+ }
79
+ export declare function getQuestionEngine(i18n: I18nFunctions): QuestionEngine;
80
+ export declare function resetQuestionEngine(i18n: I18nFunctions): QuestionEngine;
81
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EACd,UAAU,EAGV,gBAAgB,EAChB,YAAY,EAIZ,aAAa,EACd,MAAM,SAAS,CAAA;AAGhB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AA8CpD,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAyC;IACxD,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,SAAS,CAA8C;IAC/D,OAAO,CAAC,iBAAiB,CAAiB;IAC1C,OAAO,CAAC,gBAAgB,CAAuC;IAC/D,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,IAAI,CAAe;IAC3B,OAAO,CAAC,SAAS,CAAgC;gBAErC,IAAI,EAAE,aAAa;IAK/B;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAQjD,OAAO,CAAC,kBAAkB;IAe1B,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAI5C,eAAe,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,IAAI;IAIhD;;;OAGG;IACH,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAIhC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAejC,KAAK,IAAI,IAAI;IAKP,YAAY,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAgDzD,OAAO,CAAC,UAAU;IA2BlB,OAAO,CAAC,oBAAoB;IAc5B;;;;OAIG;YACW,kBAAkB;IA2BhC;;;OAGG;IACH,OAAO,CAAC,6BAA6B;IAsCrC;;;;OAIG;IACH,OAAO,CAAC,0BAA0B;IAkMlC,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,qBAAqB;IAyB7B,OAAO,CAAC,qBAAqB;IAsB7B,kBAAkB,IAAI,cAAc,GAAG,IAAI;IAmF3C,gBAAgB,IAAI,cAAc,GAAG,IAAI;IAKzC,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAMtD,OAAO,CAAC,oBAAoB;IAyB5B,OAAO,CAAC,kBAAkB;IAYpB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAqMhG,OAAO,CAAC,2BAA2B;IAiHnC,OAAO,CAAC,gCAAgC;IAgGxC,OAAO,CAAC,iBAAiB;IAuCzB,OAAO,CAAC,mBAAmB;IAsI3B,OAAO,CAAC,uBAAuB;IAW/B,OAAO,CAAC,uBAAuB;IAoC/B,OAAO,CAAC,aAAa;IA2DrB,iBAAiB,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI;IAmB/C,OAAO,CAAC,gBAAgB;IA6BxB,QAAQ,IAAI,UAAU;IAItB,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAIlC,oBAAoB,IAAI,gBAAgB,EAAE;IAI1C,WAAW,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;IAclE,oBAAoB,IAAI,MAAM;IAK9B,UAAU,IAAI,OAAO;IAQrB,OAAO,CAAC,kBAAkB;IA0C1B,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,MAAM,IAAI;IAK5D,OAAO,CAAC,eAAe;CAIxB;AAKD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,aAAa,GAAG,cAAc,CAKrE;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,aAAa,GAAG,cAAc,CAGvE"}