fix: batch priorités — thème, scroll, wizard, agents, slides, charts, packs
Anti-flash dark (color-scheme + applyDocumentTheme), scroll pages publiques, prompts wizard/slides moins génériques, cron agents rattrapage nextRun null, slides carnet via notebookId, graphiques à 2 crédits + hint, audit dashboard, packs Stripe marqués non configurés sans price ID.
This commit is contained in:
@@ -42,7 +42,8 @@ const LANG_NAMES: Record<string, string> = {
|
||||
function wordTargetsForLevel(level?: string): { min: number; max: number; label: string } {
|
||||
const l = (level || '').toLowerCase()
|
||||
if (/expert|avancé|advanced|fort/.test(l)) {
|
||||
return { min: 400, max: 800, label: 'expert (400–800 words per note)' }
|
||||
// Borné pour éviter timeouts JSON / mode expert qui plantait
|
||||
return { min: 350, max: 700, label: 'expert (350–700 words per note, dense)' }
|
||||
}
|
||||
if (/intermédiaire|intermediate|moyen/.test(l)) {
|
||||
return { min: 300, max: 550, label: 'intermediate (300–550 words per note)' }
|
||||
@@ -240,7 +241,13 @@ Return ONLY:
|
||||
Rules:
|
||||
- Exactly ${count} titles, progressive learning order.
|
||||
- Titles in ${this.langName(lang)} only.
|
||||
- notebookName ≠ full user sentence.`
|
||||
- notebookName ≠ full user sentence (3–8 words, concrete, topic-specific).
|
||||
- FORBIDDEN generic notebook names / chapter patterns (any language):
|
||||
"Fondements", "Foundations", "Maîtrise", "Mastery", "Introduction",
|
||||
"Basics", "Overview", "Getting started", "Chapitre 1", "Chapter 1",
|
||||
"Partie 1", "Bases", "Notions de base", "Synthèse finale" alone.
|
||||
- Prefer specific titles that name the real subject (e.g. topic keywords + angle).
|
||||
- Each title must be unique and non-interchangeable with another topic.`
|
||||
|
||||
const raw = await provider.generateText(prompt)
|
||||
const parsed = this.parseJsonObject(raw)
|
||||
@@ -250,10 +257,41 @@ Rules:
|
||||
while (titles.length < count) {
|
||||
titles.push(lang === 'fr' ? `Chapitre ${titles.length + 1}` : `Chapter ${titles.length + 1}`)
|
||||
}
|
||||
return {
|
||||
notebookName: String(parsed?.notebookName || '').trim().slice(0, 80),
|
||||
titles,
|
||||
let notebookName = String(parsed?.notebookName || '').trim().slice(0, 80)
|
||||
if (this.isGenericNotebookName(notebookName, topic)) {
|
||||
notebookName = this.deriveNotebookName(topic, titles.map((t) => ({ title: t, content: '' })), lang)
|
||||
}
|
||||
const cleanedTitles = titles.map((t, i) =>
|
||||
this.isGenericChapterTitle(t) ? this.fallbackChapterTitle(topic, i, lang) : t,
|
||||
)
|
||||
return {
|
||||
notebookName,
|
||||
titles: cleanedTitles,
|
||||
}
|
||||
}
|
||||
|
||||
private isGenericNotebookName(name: string, topic: string): boolean {
|
||||
const n = (name || '').trim().toLowerCase()
|
||||
if (!n || n.length < 3) return true
|
||||
if (n === topic.trim().toLowerCase() && topic.trim().split(/\s+/).length > 10) return true
|
||||
const banned =
|
||||
/^(fondements?|foundations?|ma[iî]trise|mastery|introduction|bases?|basics?|overview|getting started|notions de base|synth[eè]se|summary)$/i
|
||||
return banned.test(n)
|
||||
}
|
||||
|
||||
private isGenericChapterTitle(title: string): boolean {
|
||||
const t = (title || '').trim()
|
||||
if (!t) return true
|
||||
return /^(chapitre|chapter|partie|part|section)\s*\d+$/i.test(t)
|
||||
|| /^(fondements?|foundations?|ma[iî]trise|introduction|bases?|basics?|overview)$/i.test(t)
|
||||
}
|
||||
|
||||
private fallbackChapterTitle(topic: string, index: number, lang: string): string {
|
||||
const short = topic.trim().slice(0, 48) || (lang === 'fr' ? 'Sujet' : 'Topic')
|
||||
const anglesFr = ['Concepts clés', 'Méthodes', 'Exemples guidés', 'Pièges fréquents', 'Mise en pratique', 'Bilan']
|
||||
const anglesEn = ['Key concepts', 'Methods', 'Guided examples', 'Common pitfalls', 'Practice', 'Recap']
|
||||
const angles = lang === 'fr' ? anglesFr : anglesEn
|
||||
return `${angles[index % angles.length]} — ${short}`
|
||||
}
|
||||
|
||||
private async generateOneNote(
|
||||
|
||||
Reference in New Issue
Block a user