543 lines
No EOL
16 KiB
JavaScript
543 lines
No EOL
16 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Script de vérification des données Supabase pour PDFMonkey
|
|
*
|
|
* Ce script vérifie si toutes les données nécessaires pour générer
|
|
* un contrat avec PDFMonkey sont disponibles dans les tables Supabase.
|
|
*/
|
|
|
|
import { createClient } from '@supabase/supabase-js';
|
|
import { config } from 'dotenv';
|
|
|
|
// Charger les variables d'environnement
|
|
config({ path: '.env.local' });
|
|
|
|
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
|
|
const supabaseServiceKey = process.env.SUPABASE_SERVICE_ROLE_KEY;
|
|
|
|
if (!supabaseUrl || !supabaseServiceKey) {
|
|
console.error('❌ Variables d\'environnement manquantes:');
|
|
console.error(' NEXT_PUBLIC_SUPABASE_URL:', !!supabaseUrl ? '✅' : '❌');
|
|
console.error(' SUPABASE_SERVICE_ROLE_KEY:', !!supabaseServiceKey ? '✅' : '❌');
|
|
process.exit(1);
|
|
}
|
|
|
|
const supabase = createClient(supabaseUrl, supabaseServiceKey);
|
|
|
|
// Mapping des champs PDFMonkey vers les tables Supabase
|
|
const PDFMONKEY_MAPPING = {
|
|
// === STRUCTURE/CLIENT DATA ===
|
|
structure_name: {
|
|
table: 'organizations',
|
|
column: 'structure_api', // ou 'name'
|
|
description: 'Nom de la structure'
|
|
},
|
|
structure_adresse: {
|
|
table: 'organizations',
|
|
column: 'address', // À vérifier
|
|
description: 'Adresse de la structure'
|
|
},
|
|
structure_cpville: {
|
|
table: 'organizations',
|
|
column: 'postal_code', // À vérifier
|
|
description: 'Code postal de la structure'
|
|
},
|
|
structure_ville: {
|
|
table: 'organizations',
|
|
column: 'city', // À vérifier
|
|
description: 'Ville de la structure'
|
|
},
|
|
structure_siret: {
|
|
table: 'organizations',
|
|
column: 'siret', // À vérifier
|
|
description: 'SIRET de la structure'
|
|
},
|
|
structure_licence: {
|
|
table: 'organizations',
|
|
column: 'licence_spectacles', // À vérifier
|
|
description: 'Licence spectacles'
|
|
},
|
|
structure_spectacle: {
|
|
table: 'productions',
|
|
column: 'name',
|
|
description: 'Nom du spectacle/production'
|
|
},
|
|
forme_juridique: {
|
|
table: 'organizations',
|
|
column: 'legal_form', // À vérifier
|
|
description: 'Forme juridique'
|
|
},
|
|
structure_signataire: {
|
|
table: 'organizations',
|
|
column: 'signatory_name', // À vérifier (concat prénom + nom)
|
|
description: 'Nom complet du signataire'
|
|
},
|
|
structure_signatairequalite: {
|
|
table: 'organizations',
|
|
column: 'signatory_title', // À vérifier
|
|
description: 'Qualité du signataire'
|
|
},
|
|
delegation: {
|
|
table: 'organizations',
|
|
column: 'delegation_authority', // À vérifier
|
|
description: 'Signataire agissant par délégation'
|
|
},
|
|
|
|
// === EMPLOYEE DATA ===
|
|
employee_civ: {
|
|
table: 'salaries',
|
|
column: 'civilite',
|
|
description: 'Civilité du salarié'
|
|
},
|
|
employee_firstname: {
|
|
table: 'salaries',
|
|
column: 'prenom',
|
|
description: 'Prénom du salarié'
|
|
},
|
|
employee_lastname: {
|
|
table: 'salaries',
|
|
column: 'nom',
|
|
description: 'Nom du salarié'
|
|
},
|
|
employee_birthname: {
|
|
table: 'salaries',
|
|
column: 'nom_naissance', // À vérifier
|
|
description: 'Nom de naissance'
|
|
},
|
|
employee_pseudo: {
|
|
table: 'salaries',
|
|
column: 'pseudonyme', // À vérifier
|
|
description: 'Pseudonyme'
|
|
},
|
|
employee_dob: {
|
|
table: 'salaries',
|
|
column: 'date_naissance', // À vérifier
|
|
description: 'Date de naissance'
|
|
},
|
|
employee_cob: {
|
|
table: 'salaries',
|
|
column: 'lieu_naissance', // À vérifier
|
|
description: 'Lieu de naissance'
|
|
},
|
|
employee_address: {
|
|
table: 'salaries',
|
|
column: 'adresse', // À vérifier
|
|
description: 'Adresse du salarié'
|
|
},
|
|
employee_ss: {
|
|
table: 'salaries',
|
|
column: 'nir', // À vérifier
|
|
description: 'Numéro de sécurité sociale'
|
|
},
|
|
employee_cs: {
|
|
table: 'salaries',
|
|
column: 'conges_spectacles', // À vérifier
|
|
description: 'Congés Spectacles'
|
|
},
|
|
employee_profession: {
|
|
table: 'cddu_contracts', // ou salaries
|
|
column: 'profession',
|
|
description: 'Profession'
|
|
},
|
|
employee_codeprofession: {
|
|
table: 'cddu_contracts',
|
|
column: 'code_profession', // À vérifier
|
|
description: 'Code profession'
|
|
},
|
|
employee_catpro: {
|
|
table: 'cddu_contracts',
|
|
column: 'categorie_pro',
|
|
description: 'Catégorie professionnelle'
|
|
},
|
|
|
|
// === CONTRACT DATA ===
|
|
mineur1618: {
|
|
table: 'cddu_contracts',
|
|
column: 'mineur_entre_16_et_18',
|
|
description: 'Mineur entre 16 et 18 ans'
|
|
},
|
|
representant_civ: {
|
|
table: 'cddu_contracts',
|
|
column: 'civilite_representant_legal',
|
|
description: 'Civilité représentant légal'
|
|
},
|
|
representant_nom: {
|
|
table: 'cddu_contracts',
|
|
column: 'nom_representant_legal',
|
|
description: 'Nom représentant légal'
|
|
},
|
|
representant_dob: {
|
|
table: 'cddu_contracts',
|
|
column: 'dob_representant_legal',
|
|
description: 'Date naissance représentant légal'
|
|
},
|
|
representant_cob: {
|
|
table: 'cddu_contracts',
|
|
column: 'cob_representant_legal', // À vérifier
|
|
description: 'Lieu naissance représentant légal'
|
|
},
|
|
representant_adresse: {
|
|
table: 'cddu_contracts',
|
|
column: 'adresse_representant_legal',
|
|
description: 'Adresse représentant légal'
|
|
},
|
|
spectacle: {
|
|
table: 'cddu_contracts',
|
|
column: 'production_name',
|
|
description: 'Nom du spectacle'
|
|
},
|
|
numobjet: {
|
|
table: 'cddu_contracts',
|
|
column: 'objet_spectacle', // ou numero_objet
|
|
description: 'Numéro/objet spectacle'
|
|
},
|
|
type_numobjet: {
|
|
table: 'cddu_contracts',
|
|
column: 'type_numero_objet', // À vérifier
|
|
description: 'Type numéro objet'
|
|
},
|
|
date_debut: {
|
|
table: 'cddu_contracts',
|
|
column: 'start_date',
|
|
description: 'Date de début'
|
|
},
|
|
date_fin: {
|
|
table: 'cddu_contracts',
|
|
column: 'end_date',
|
|
description: 'Date de fin'
|
|
},
|
|
dates_travaillees: {
|
|
table: 'cddu_contracts',
|
|
column: 'jours_travail', // À vérifier
|
|
description: 'Jours travaillés'
|
|
},
|
|
autreprecision: {
|
|
table: 'cddu_contracts',
|
|
column: 'autre_precision_salaire', // À vérifier
|
|
description: 'Autre précision salaire'
|
|
},
|
|
salaire_brut: {
|
|
table: 'cddu_contracts',
|
|
column: 'brut',
|
|
description: 'Salaire brut'
|
|
},
|
|
date_signature: {
|
|
table: 'cddu_contracts',
|
|
column: 'date_signature_contrat', // À vérifier
|
|
description: 'Date de signature'
|
|
},
|
|
CCN: {
|
|
table: 'cddu_contracts',
|
|
column: 'ccn', // À vérifier
|
|
description: 'Convention collective'
|
|
},
|
|
precisions_salaire: {
|
|
table: 'cddu_contracts',
|
|
column: 'precisions_salaire',
|
|
description: 'Précisions salaire'
|
|
},
|
|
panierrepas: {
|
|
table: 'cddu_contracts',
|
|
column: 'panier_repas',
|
|
description: 'Panier repas'
|
|
},
|
|
panierrepasccn: {
|
|
table: 'cddu_contracts',
|
|
column: 'panier_repas_ccn',
|
|
description: 'Panier repas CCN'
|
|
},
|
|
montantpanierrepas: {
|
|
table: 'cddu_contracts',
|
|
column: 'si_non_montant_par_panier',
|
|
description: 'Montant panier repas'
|
|
},
|
|
|
|
// === CACHETS DATA ===
|
|
'cachets.representations': {
|
|
table: 'cddu_contracts',
|
|
column: 'cachets_representations',
|
|
description: 'Cachets représentations'
|
|
},
|
|
'cachets.repetitions': {
|
|
table: 'cddu_contracts',
|
|
column: 'services_repetitions',
|
|
description: 'Services répétitions'
|
|
},
|
|
'cachets.heures': {
|
|
table: 'cddu_contracts',
|
|
column: 'nombre_d_heures',
|
|
description: 'Nombre d\'heures'
|
|
},
|
|
'cachets.heuresparjour': {
|
|
table: 'cddu_contracts',
|
|
column: 'nombre_d_heures_par_jour',
|
|
description: 'Heures par jour'
|
|
},
|
|
|
|
// === RESPONSABLE TRAITEMENT DATA ===
|
|
nom_responsable_traitement: {
|
|
table: 'organizations',
|
|
column: 'data_controller_name', // À vérifier
|
|
description: 'Nom responsable traitement'
|
|
},
|
|
qualite_responsable_traitement: {
|
|
table: 'organizations',
|
|
column: 'data_controller_title', // À vérifier
|
|
description: 'Qualité responsable traitement'
|
|
},
|
|
email_responsable_traitement: {
|
|
table: 'organizations',
|
|
column: 'data_controller_email', // À vérifier
|
|
description: 'Email responsable traitement'
|
|
},
|
|
imageUrl: {
|
|
table: 'organizations',
|
|
column: 'logo_base64', // À vérifier
|
|
description: 'Logo en base64'
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Vérification de l'existence des colonnes dans les tables
|
|
*/
|
|
async function checkTableColumns() {
|
|
console.log('📊 Vérification des colonnes existantes dans Supabase...\n');
|
|
|
|
const tables = ['organizations', 'salaries', 'cddu_contracts', 'productions'];
|
|
const tableColumns = {};
|
|
|
|
for (const table of tables) {
|
|
try {
|
|
console.log(`🔍 Table: ${table}`);
|
|
|
|
// Récupérer un échantillon pour voir les colonnes disponibles
|
|
const { data, error } = await supabase
|
|
.from(table)
|
|
.select('*')
|
|
.limit(1);
|
|
|
|
if (error) {
|
|
console.log(` ❌ Erreur: ${error.message}`);
|
|
tableColumns[table] = [];
|
|
} else if (data && data.length > 0) {
|
|
const columns = Object.keys(data[0]);
|
|
tableColumns[table] = columns;
|
|
console.log(` ✅ ${columns.length} colonnes trouvées`);
|
|
console.log(` 📋 Colonnes: ${columns.join(', ')}`);
|
|
} else {
|
|
console.log(` ⚠️ Table vide, récupération du schéma...`);
|
|
// Essayer une requête pour voir les colonnes même si vide
|
|
const { error: schemaError } = await supabase
|
|
.from(table)
|
|
.select('*')
|
|
.limit(0);
|
|
|
|
if (!schemaError) {
|
|
tableColumns[table] = [];
|
|
console.log(` 📋 Table existe mais est vide`);
|
|
}
|
|
}
|
|
|
|
console.log('');
|
|
} catch (err) {
|
|
console.log(` ❌ Erreur inattendue: ${err.message}\n`);
|
|
tableColumns[table] = [];
|
|
}
|
|
}
|
|
|
|
return tableColumns;
|
|
}
|
|
|
|
/**
|
|
* Analyse des champs requis vs disponibles
|
|
*/
|
|
async function analyzePDFMonkeyMapping(tableColumns) {
|
|
console.log('🎯 Analyse des champs requis pour PDFMonkey...\n');
|
|
|
|
const results = {
|
|
available: [],
|
|
missing: [],
|
|
uncertain: []
|
|
};
|
|
|
|
for (const [pdfField, mapping] of Object.entries(PDFMONKEY_MAPPING)) {
|
|
const { table, column, description } = mapping;
|
|
const availableColumns = tableColumns[table] || [];
|
|
|
|
if (availableColumns.includes(column)) {
|
|
results.available.push({ pdfField, table, column, description, status: '✅ Disponible' });
|
|
} else if (availableColumns.length === 0) {
|
|
results.uncertain.push({ pdfField, table, column, description, status: '❓ Table non accessible' });
|
|
} else {
|
|
results.missing.push({ pdfField, table, column, description, status: '❌ Manquant' });
|
|
}
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
/**
|
|
* Suggestions de colonnes similaires
|
|
*/
|
|
function findSimilarColumns(targetColumn, availableColumns) {
|
|
const similar = availableColumns.filter(col =>
|
|
col.toLowerCase().includes(targetColumn.toLowerCase()) ||
|
|
targetColumn.toLowerCase().includes(col.toLowerCase())
|
|
);
|
|
return similar;
|
|
}
|
|
|
|
/**
|
|
* Rapport détaillé
|
|
*/
|
|
function printDetailedReport(results, tableColumns) {
|
|
console.log('📈 RAPPORT DÉTAILLÉ\n');
|
|
console.log('='.repeat(80));
|
|
|
|
// Statistiques
|
|
const total = results.available.length + results.missing.length + results.uncertain.length;
|
|
console.log(`📊 STATISTIQUES:`);
|
|
console.log(` Total des champs requis: ${total}`);
|
|
console.log(` ✅ Disponibles: ${results.available.length} (${Math.round(results.available.length/total*100)}%)`);
|
|
console.log(` ❌ Manquants: ${results.missing.length} (${Math.round(results.missing.length/total*100)}%)`);
|
|
console.log(` ❓ Incertains: ${results.uncertain.length} (${Math.round(results.uncertain.length/total*100)}%)`);
|
|
console.log('');
|
|
|
|
// Champs disponibles
|
|
if (results.available.length > 0) {
|
|
console.log('✅ CHAMPS DISPONIBLES:');
|
|
console.log('-'.repeat(50));
|
|
results.available.forEach(item => {
|
|
console.log(` ${item.pdfField}: ${item.table}.${item.column}`);
|
|
console.log(` → ${item.description}`);
|
|
});
|
|
console.log('');
|
|
}
|
|
|
|
// Champs manquants avec suggestions
|
|
if (results.missing.length > 0) {
|
|
console.log('❌ CHAMPS MANQUANTS:');
|
|
console.log('-'.repeat(50));
|
|
results.missing.forEach(item => {
|
|
console.log(` ${item.pdfField}: ${item.table}.${item.column} (MANQUANT)`);
|
|
console.log(` → ${item.description}`);
|
|
|
|
// Chercher des colonnes similaires
|
|
const availableColumns = tableColumns[item.table] || [];
|
|
const similar = findSimilarColumns(item.column, availableColumns);
|
|
if (similar.length > 0) {
|
|
console.log(` 💡 Suggestions: ${similar.join(', ')}`);
|
|
}
|
|
console.log('');
|
|
});
|
|
}
|
|
|
|
// Champs incertains
|
|
if (results.uncertain.length > 0) {
|
|
console.log('❓ CHAMPS INCERTAINS (table inaccessible):');
|
|
console.log('-'.repeat(50));
|
|
results.uncertain.forEach(item => {
|
|
console.log(` ${item.pdfField}: ${item.table}.${item.column}`);
|
|
console.log(` → ${item.description}`);
|
|
});
|
|
console.log('');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Générer un exemple de requête
|
|
*/
|
|
function generateExampleQuery(results) {
|
|
console.log('💡 EXEMPLE DE REQUÊTE POUR RÉCUPÉRER LES DONNÉES:');
|
|
console.log('-'.repeat(60));
|
|
|
|
const availableByTable = {};
|
|
results.available.forEach(item => {
|
|
if (!availableByTable[item.table]) {
|
|
availableByTable[item.table] = [];
|
|
}
|
|
availableByTable[item.table].push(item.column);
|
|
});
|
|
|
|
console.log('```javascript');
|
|
console.log('async function getPDFMonkeyData(contractId) {');
|
|
console.log(' const supabase = createClient(...);');
|
|
console.log(' ');
|
|
|
|
Object.entries(availableByTable).forEach(([table, columns]) => {
|
|
const uniqueColumns = [...new Set(columns)];
|
|
console.log(` // Données de la table ${table}`);
|
|
console.log(` const { data: ${table}Data } = await supabase`);
|
|
console.log(` .from('${table}')`);
|
|
console.log(` .select('${uniqueColumns.join(', ')}')`);
|
|
if (table === 'cddu_contracts') {
|
|
console.log(` .eq('id', contractId)`);
|
|
}
|
|
console.log(` .single();`);
|
|
console.log(' ');
|
|
});
|
|
|
|
console.log(' const dataPayload = {');
|
|
results.available.forEach(item => {
|
|
const varName = item.table === 'cddu_contracts' ? 'cddu_contractsData' : `${item.table}Data`;
|
|
console.log(` ${item.pdfField}: ${varName}?.${item.column} || "",`);
|
|
});
|
|
console.log(' // TODO: Ajouter les champs manquants');
|
|
console.log(' };');
|
|
console.log(' ');
|
|
console.log(' return dataPayload;');
|
|
console.log('}');
|
|
console.log('```');
|
|
}
|
|
|
|
/**
|
|
* Fonction principale
|
|
*/
|
|
async function main() {
|
|
console.log('🚀 Vérification des données Supabase pour PDFMonkey');
|
|
console.log('='.repeat(80));
|
|
console.log('');
|
|
|
|
try {
|
|
// 1. Vérifier les colonnes des tables
|
|
const tableColumns = await checkTableColumns();
|
|
|
|
// 2. Analyser le mapping PDFMonkey
|
|
const results = await analyzePDFMonkeyMapping(tableColumns);
|
|
|
|
// 3. Afficher le rapport détaillé
|
|
printDetailedReport(results, tableColumns);
|
|
|
|
// 4. Générer un exemple de requête
|
|
generateExampleQuery(results);
|
|
|
|
// 5. Résumé final
|
|
console.log('\n📋 ACTIONS RECOMMANDÉES:');
|
|
console.log('-'.repeat(30));
|
|
|
|
if (results.missing.length > 0) {
|
|
console.log('1. 🔧 Ajouter les colonnes manquantes dans les tables Supabase');
|
|
console.log('2. 📝 Créer des migrations pour ajouter ces colonnes');
|
|
console.log('3. 🔄 Migrer les données existantes d\'Airtable vers Supabase');
|
|
}
|
|
|
|
if (results.available.length > 30) {
|
|
console.log('4. ✅ Créer une API endpoint pour récupérer toutes les données');
|
|
console.log('5. 🧪 Tester la génération PDFMonkey avec les données Supabase');
|
|
}
|
|
|
|
console.log('\n🎯 Prêt à remplacer Airtable:', results.available.length >= 40 ? '✅ OUI' : '❌ NON');
|
|
|
|
} catch (error) {
|
|
console.error('❌ Erreur lors de l\'analyse:', error.message);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
// Exécuter le script
|
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
main();
|
|
}
|
|
|
|
export { PDFMONKEY_MAPPING, checkTableColumns, analyzePDFMonkeyMapping }; |