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 +20 -0
- package/package.json +1 -1
- package/src/commands/profile.js +29 -0
- package/src/scrapers/pappers.js +20 -3
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
package/src/commands/profile.js
CHANGED
|
@@ -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 => ({
|
package/src/scrapers/pappers.js
CHANGED
|
@@ -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:
|
|
138
|
-
details: p.acte?.descriptif ||
|
|
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
|
|