diff --git a/scripts/data-transformers/content-generators.ts b/scripts/data-transformers/content-generators.ts index cc5357c1..b2e8b4ac 100644 --- a/scripts/data-transformers/content-generators.ts +++ b/scripts/data-transformers/content-generators.ts @@ -1358,3 +1358,210 @@ export function generateGenericContent(data: ArticleContentData, lang: Language return content; } + +/** + * Generate Month-Ahead article content with strategic legislative forecasting. + * Extends week-ahead calendar coverage with committee pipeline tracking, + * propositions in pipeline, and motion trend analysis. + */ +export function generateMonthAheadContent(data: ArticleContentData, lang: Language | string): string { + // Base calendar/event content (handles events + upcoming documents) + let content = generateWeekAheadContent(data as WeekAheadData, lang); + + const propositions = data.propositions ?? []; + const reports = data.reports ?? []; + const motions = data.motions ?? []; + + // ── Strategic Legislative Outlook ──────────────────────────────────────── + if (propositions.length > 0) { + const outlookLabel = lang === 'sv' ? 'Strategisk lagstiftningsutsikt' + : lang === 'de' ? 'Strategischer Gesetzgebungsausblick' + : lang === 'fr' ? 'Perspectives législatives stratégiques' + : lang === 'es' ? 'Perspectiva legislativa estratégica' + : lang === 'da' ? 'Strategisk lovgivningsmæssigt udsyn' + : lang === 'no' ? 'Strategisk lovgivningsmessig utsikt' + : lang === 'fi' ? 'Strateginen lainsäädäntönäkymä' + : lang === 'nl' ? 'Strategisch wetgevingsoverzicht' + : lang === 'ar' ? 'التوقعات التشريعية الاستراتيجية' + : lang === 'he' ? 'תחזית חקיקתית אסטרטגית' + : lang === 'ja' ? '戦略的立法見通し' + : lang === 'ko' ? '전략적 입법 전망' + : lang === 'zh' ? '战略立法展望' + : 'Strategic Legislative Outlook'; + content += `\n
${escapeHtml(propLede)}
\n`; + + propositions.slice(0, 8).forEach(prop => { // 8 propositions: readable summary without overwhelming + const rec = prop as Record${escapeHtml(significance)}
\n`; + } + content += `${domainIntro}
\n`; + } + + // Top parties by motion volume + const topParties = Object.entries(byPartyTrend) + .filter(([k]) => k !== 'unknown' && k !== 'other') + .sort((a, b) => b[1] - a[1]) + .slice(0, 4); // 4 parties: covers the typical Swedish governing+major-opposition parties + + if (topParties.length > 0) { + content += `Committee pipeline report proposition motion scheduled for next month.
', + sources: ['source1', 'source2', 'source3'] + }; + + const validation = monthAheadModule.validateMonthAhead(article); + expect(validation).toHaveProperty('hasLegislativePipeline'); + expect(validation.hasLegislativePipeline).toBe(true); + }); }); describe('Multi-Language', () => {