intelwatch 1.1.2 → 1.1.3

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/CHANGELOG.md CHANGED
@@ -1,6 +1,26 @@
1
1
  # Changelog
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
+ ## [1.1.3] - 2026-03-03
5
+
6
+ ### Added
7
+ - PDF redesign: intelligence cabinet style with SVG inline icons (18 monoline icons)
8
+ - BODACC enriched descriptions (capital changes, governance details, filing types)
9
+ - BODACC clickable links to bodacc.fr for each publication
10
+ - FLI code-built revenue target override (picks highest announced figure from articles)
11
+ - Revenue Growth YoY all years from consolidated finances (code-built)
12
+ - Last Deposited vs Announced comparison in Forward-Looking Indicators
13
+ - Stale financials auto-refresh via Pappers API direct
14
+
15
+ ### Fixed
16
+ - Cover page header/footer overlap (disabled Puppeteer displayHeaderFooter)
17
+ - Page margins increased for better readability
18
+ - Page breaks: Subsidiaries and Directors tables start on new pages
19
+ - BODACC URL format corrected (was 404, now uses correct bodacc.fr format)
20
+ - FLI acquisitions with empty targets no longer shown
21
+ - Revenue chart top labels no longer cropped
22
+ - Group Structure organigramme includes off-brand subsidiaries
23
+
4
24
  ## [1.1.2] - 2026-03-03
5
25
 
6
26
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "intelwatch",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "description": "Competitive intelligence CLI — track competitors, keywords, and brand mentions from the terminal",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1060,6 +1060,34 @@ OBLIGATOIRE :
1060
1060
  fl.projectedGrowth = `+${growth}% → ~${projected}M€ projected ${(last.annee || 2024) + 1}`;
1061
1061
  }
1062
1062
  }
1063
+ // Inject lastDeposited from consolidated finances
1064
+ if (consolidatedFinances?.length > 0) {
1065
+ const last = consolidatedFinances[0];
1066
+ if (last.ca) {
1067
+ fl.lastDeposited = {
1068
+ amount: (last.ca / 1e6).toFixed(1) + 'M€',
1069
+ year: last.annee || '?',
1070
+ raw: last.ca,
1071
+ };
1072
+ }
1073
+ }
1074
+ // Compute real delta between deposited and announced
1075
+ if (fl.lastDeposited?.raw && fl.announcedRevenue?.amount) {
1076
+ const announcedVal = parseInt((fl.announcedRevenue.amount || '0').replace(/[^\d]/g, '')) || 0;
1077
+ const depositedVal = fl.lastDeposited.raw / 1e6;
1078
+ if (announcedVal > 0 && depositedVal > 0) {
1079
+ const pct = ((announcedVal - depositedVal) / depositedVal * 100).toFixed(0);
1080
+ const yearDiff = (fl.announcedRevenue.year || 2030) - (fl.lastDeposited.year || 2024);
1081
+ fl.delta = `+${pct}% (x${(announcedVal / depositedVal).toFixed(1)}) over ${yearDiff > 0 ? yearDiff + 'y' : '?'}`;
1082
+ }
1083
+ }
1084
+ // Fix AI commentary if it mentions wrong revenue target
1085
+ if (fl.aiComment && fl.announcedRevenue?.amount && fl.lastDeposited?.amount) {
1086
+ const announced = fl.announcedRevenue.amount;
1087
+ const deposited = fl.lastDeposited.amount;
1088
+ const year = fl.announcedRevenue.year || '2030';
1089
+ fl.aiComment = `Target revenue: ${announced} by ${year} (announced via press). Last deposited: ${deposited} (${fl.lastDeposited.year}). ${fl.delta ? 'Gap: ' + fl.delta + '.' : ''} ${fl.aiComment.replace(/\d{2,4}\s*M€?/gi, '').replace(/\s{2,}/g, ' ').trim().split('.').slice(-2).join('.').trim()}`;
1090
+ }
1063
1091
  return fl;
1064
1092
  })(),
1065
1093
  competitors: [{
@@ -1157,6 +1185,7 @@ OBLIGATOIRE :
1157
1185
  date: b.date || '—',
1158
1186
  type: b.type || '—',
1159
1187
  description: b.description || '',
1188
+ url: b.url || null,
1160
1189
  })),
1161
1190
  // Procédures collectives
1162
1191
  procedures: (proceduresCollectives || []).map(p => ({
@@ -128,14 +128,31 @@ export async function pappersGetFullDossier(siren) {
128
128
 
129
129
  // BODACC publications — last 50 (captures M&A activity)
130
130
  const bodacc = (d.publications_bodacc || []).slice(0, 50).map(p => {
131
+ // Build rich description from all available fields
132
+ const parts = [];
133
+ if (p.description && p.description !== p.type) parts.push(p.description);
134
+ if (p.administration) parts.push(p.administration);
135
+ if (p.capital) parts.push(`Capital: ${(p.capital / 1e3).toFixed(0)}K€`);
136
+ if (p.date_cloture) parts.push(`Clôture: ${p.date_cloture}`);
137
+ if (p.type_depot) parts.push(p.type_depot);
138
+ if (p.activite) parts.push(p.activite);
131
139
  const actes = (p.acte?.actes_publies || []).map(a => a.type_acte).filter(Boolean);
140
+ if (actes.length) parts.push(actes.join(', '));
141
+ // Build BODACC URL: format id:{letter}{parution}{annonce}
142
+ const bodaccLetter = p.bodacc || (p.type?.toLowerCase().includes('comptes') ? 'C' : 'B');
143
+ const bodaccUrl = p.numero_parution && p.numero_annonce
144
+ ? `https://www.bodacc.fr/pages/annonces-commerciales-detail/?q.id=id:${bodaccLetter}${p.numero_parution}${p.numero_annonce}`
145
+ : null;
132
146
  return {
133
147
  date: p.date,
134
148
  type: p.type,
135
- tribunal: p.tribunal || null,
149
+ tribunal: p.greffe || p.tribunal || null,
136
150
  numero: p.numero_annonce || null,
137
- description: actes.length ? actes.join(', ') : p.type || null,
138
- details: p.acte?.descriptif || p.acte?.capital || null,
151
+ description: parts.length ? parts.join('. ') : p.type || null,
152
+ details: p.acte?.descriptif || null,
153
+ url: bodaccUrl,
154
+ capital: p.capital || null,
155
+ rcs: p.rcs || null,
139
156
  };
140
157
  });
141
158