4NK_IA_front/backend/collectors/rbeCollector.js
4NK IA aad52027c1 ci: docker_tag=dev-test
- Alignement backend: seules 4 entités retournées (persons, companies, addresses, contractual)
- Version API mise à jour à 1.0.1 dans /api/health
- Interface onglets d entités: Personnes, Adresses, Entreprises, Contractuel
- Correction erreurs TypeScript pour build stricte
- Tests et documentation mis à jour
- CHANGELOG.md mis à jour avec version 1.1.1
2025-09-18 20:07:08 +00:00

288 lines
7.8 KiB
JavaScript

/**
* Collecteur RBE (Registre des Bénéficiaires Effectifs)
* Accès aux données des bénéficiaires effectifs via l'API RBE
*/
const fetch = require('node-fetch');
const RBE_BASE_URL = 'https://registre-beneficiaires-effectifs.inpi.fr';
const USER_AGENT = '4NK-IA-Front/1.0 (Document Analysis Tool)';
const REQUEST_TIMEOUT_MS = 15000; // 15 secondes timeout
/**
* Recherche les bénéficiaires effectifs pour une entreprise
* @param {string} siren - SIREN de l'entreprise
* @param {string} siret - SIRET de l'entreprise (optionnel)
* @returns {Promise<Object>} Résultat de la recherche RBE
*/
async function searchRBEBeneficiaires(siren, siret = '') {
const startTime = Date.now();
try {
console.log(`[RBE] Recherche bénéficiaires effectifs pour SIREN: ${siren}`);
// Vérification de la validité du SIREN
if (!siren || siren.length !== 9 || !/^\d{9}$/.test(siren)) {
throw new Error('SIREN invalide - doit contenir 9 chiffres');
}
// Construction de l'URL de recherche
const searchUrl = `${RBE_BASE_URL}/api/beneficiaires?q=${encodeURIComponent(siren)}`;
// Requête avec headers appropriés
const response = await fetch(searchUrl, {
method: 'GET',
headers: {
'User-Agent': USER_AGENT,
'Accept': 'application/json',
'Accept-Language': 'fr-FR,fr;q=0.9,en;q=0.8',
'Cache-Control': 'no-cache'
},
timeout: REQUEST_TIMEOUT_MS
});
if (!response.ok) {
if (response.status === 404) {
return {
success: true,
duration: Date.now() - startTime,
siren,
beneficiaires: [],
message: 'Aucun bénéficiaire effectif trouvé',
timestamp: new Date().toISOString()
};
}
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
// Traitement des données RBE
const beneficiaires = processRBEData(data, siren);
const duration = Date.now() - startTime;
console.log(`[RBE] Recherche terminée en ${duration}ms - ${beneficiaires.length} bénéficiaire(s) trouvé(s)`);
return {
success: true,
duration,
siren,
siret,
beneficiaires,
total: beneficiaires.length,
timestamp: new Date().toISOString(),
source: 'rbe.inpi.fr'
};
} catch (error) {
const duration = Date.now() - startTime;
console.error(`[RBE] Erreur recherche:`, error.message);
return {
success: false,
duration,
siren,
error: error.message,
beneficiaires: [],
timestamp: new Date().toISOString()
};
}
}
/**
* Traite les données RBE brutes
* @param {Object} data - Données brutes de l'API RBE
* @param {string} siren - SIREN de l'entreprise
* @returns {Array} Liste des bénéficiaires effectifs
*/
function processRBEData(data, siren) {
try {
const beneficiaires = [];
// Structure des données RBE (à adapter selon l'API réelle)
if (data.beneficiaires && Array.isArray(data.beneficiaires)) {
for (const benef of data.beneficiaires) {
const beneficiaire = {
nom: benef.nom || '',
prenom: benef.prenom || '',
dateNaissance: benef.dateNaissance || '',
nationalite: benef.nationalite || '',
adresse: benef.adresse || '',
qualite: benef.qualite || '',
pourcentage: benef.pourcentage || 0,
type: benef.type || 'personne_physique', // personne_physique ou personne_morale
siren: benef.siren || '',
dateDeclaration: benef.dateDeclaration || '',
statut: benef.statut || 'actif'
};
// Validation des données
if (beneficiaire.nom || beneficiaire.prenom) {
beneficiaires.push(beneficiaire);
}
}
}
return beneficiaires;
} catch (error) {
console.error(`[RBE] Erreur traitement données:`, error.message);
return [];
}
}
/**
* Recherche les informations détaillées d'un bénéficiaire
* @param {string} beneficiaireId - ID du bénéficiaire
* @returns {Promise<Object>} Informations détaillées
*/
async function getBeneficiaireDetails(beneficiaireId) {
const startTime = Date.now();
try {
console.log(`[RBE] Recherche détails bénéficiaire: ${beneficiaireId}`);
const detailsUrl = `${RBE_BASE_URL}/api/beneficiaires/${encodeURIComponent(beneficiaireId)}`;
const response = await fetch(detailsUrl, {
method: 'GET',
headers: {
'User-Agent': USER_AGENT,
'Accept': 'application/json'
},
timeout: REQUEST_TIMEOUT_MS
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
const duration = Date.now() - startTime;
console.log(`[RBE] Détails récupérés en ${duration}ms`);
return {
success: true,
duration,
beneficiaireId,
details: data,
timestamp: new Date().toISOString()
};
} catch (error) {
const duration = Date.now() - startTime;
console.error(`[RBE] Erreur détails:`, error.message);
return {
success: false,
duration,
beneficiaireId,
error: error.message,
timestamp: new Date().toISOString()
};
}
}
/**
* Recherche les entreprises liées à une personne
* @param {string} nom - Nom de famille
* @param {string} prenom - Prénom (optionnel)
* @returns {Promise<Object>} Liste des entreprises
*/
async function searchPersonneEntreprises(nom, prenom = '') {
const startTime = Date.now();
try {
console.log(`[RBE] Recherche entreprises pour: ${nom} ${prenom}`);
const searchQuery = `${nom} ${prenom}`.trim();
const searchUrl = `${RBE_BASE_URL}/api/personnes?q=${encodeURIComponent(searchQuery)}`;
const response = await fetch(searchUrl, {
method: 'GET',
headers: {
'User-Agent': USER_AGENT,
'Accept': 'application/json'
},
timeout: REQUEST_TIMEOUT_MS
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
const entreprises = processPersonneEntreprises(data);
const duration = Date.now() - startTime;
console.log(`[RBE] Recherche terminée en ${duration}ms - ${entreprises.length} entreprise(s) trouvée(s)`);
return {
success: true,
duration,
nom,
prenom,
entreprises,
total: entreprises.length,
timestamp: new Date().toISOString()
};
} catch (error) {
const duration = Date.now() - startTime;
console.error(`[RBE] Erreur recherche personne:`, error.message);
return {
success: false,
duration,
nom,
prenom,
error: error.message,
entreprises: [],
timestamp: new Date().toISOString()
};
}
}
/**
* Traite les données d'entreprises liées à une personne
* @param {Object} data - Données brutes
* @returns {Array} Liste des entreprises
*/
function processPersonneEntreprises(data) {
try {
const entreprises = [];
if (data.entreprises && Array.isArray(data.entreprises)) {
for (const ent of data.entreprises) {
const entreprise = {
siren: ent.siren || '',
denomination: ent.denomination || '',
forme: ent.forme || '',
adresse: ent.adresse || '',
qualite: ent.qualite || '',
pourcentage: ent.pourcentage || 0,
dateDeclaration: ent.dateDeclaration || '',
statut: ent.statut || 'actif'
};
if (entreprise.siren && entreprise.denomination) {
entreprises.push(entreprise);
}
}
}
return entreprises;
} catch (error) {
console.error(`[RBE] Erreur traitement entreprises:`, error.message);
return [];
}
}
module.exports = {
searchRBEBeneficiaires,
getBeneficiaireDetails,
searchPersonneEntreprises
};