// This script is responsible for synchronizing employee data from the local // Prisma database to an external database. It is designed to be run as a scheduled task. // --- External Database Configuration (PLACEHOLDERS - User MUST Configure via environment variables) --- // IMPORTANT: These variables define the connection to your external database. // You MUST configure these, ideally through environment variables, for the script to work. // The script provides a template for different database types, but you'll need to: // 1. Install the appropriate database client library (e.g., `npm install pg` or `npm install mysql2`). // 2. Implement the actual database connection and query logic in the designated section. const EXTERNAL_DB_TYPE = process.env.EXTERNAL_DB_TYPE || 'your_db_type_here'; // e.g., 'postgres', 'mysql'. User must set this. const EXTERNAL_DB_HOST = process.env.EXTERNAL_DB_HOST || 'YOUR_EXTERNAL_DB_HOST'; // User must set this. const EXTERNAL_DB_PORT = process.env.EXTERNAL_DB_PORT || 5432; // Adjust default port if needed. User must set this. const EXTERNAL_DB_USER = process.env.EXTERNAL_DB_USER || 'YOUR_EXTERNAL_DB_USER'; // User must set this. const EXTERNAL_DB_PASSWORD = process.env.EXTERNAL_DB_PASSWORD || 'YOUR_EXTERNAL_DB_PASSWORD'; // User must set this. const EXTERNAL_DB_NAME = process.env.EXTERNAL_DB_NAME || 'YOUR_EXTERNAL_DB_NAME'; // User must set this. const EXTERNAL_DB_EMPLEADOS_TABLE = process.env.EXTERNAL_DB_EMPLEADOS_TABLE || 'empleados_externos'; // User must set this. // --- End of External Database Configuration --- import { PrismaClient } from '../api/prisma/generated/client'; const prisma = new PrismaClient(); async function syncEmpleadosToExternalDB() { console.log('[SyncEmpleados] Starting synchronization process...'); // Core logic for synchronization, wrapped in try/catch/finally to ensure // resources like the Prisma client are properly managed (e.g., disconnected). try { // Fetch all 'Cliente' records from the local Prisma database that are marked as 'empleado'. const localEmpleados = await prisma.cliente.findMany({ where: { empleado: true }, // Filters for clients who are also employees select: { id: true, // Local ID, might be useful for logging/tracing name: true, cedula: true, ubicacion: true, telefono: true, // avatar_url: true, // Add other relevant fields // idciat: true, // Add other relevant fields }, }); if (!localEmpleados.length) { console.log('[SyncEmpleados] No employees found in local database. Nothing to sync.'); return; } console.log(`[SyncEmpleados] Found ${localEmpleados.length} employees to sync.`); // --- External DB Connection Logic (User to implement based on EXTERNAL_DB_TYPE) --- // User must implement the actual database connection logic here based on EXTERNAL_DB_TYPE // and install the required database client library (e.g., 'pg' for PostgreSQL, 'mysql2' for MySQL). // The following are conceptual examples. // Example for PostgreSQL using 'pg' library (user would need to install it: npm install pg) /* if (EXTERNAL_DB_TYPE === 'postgres') { // const { Client } = require('pg'); // User would uncomment and install // const externalDbClient = new Client({ // host: EXTERNAL_DB_HOST, // port: EXTERNAL_DB_PORT, // user: EXTERNAL_DB_USER, // password: EXTERNAL_DB_PASSWORD, // database: EXTERNAL_DB_NAME, // }); // await externalDbClient.connect(); // console.log('[SyncEmpleados] Connected to external PostgreSQL database.'); // ... (sync logic using externalDbClient) ... // await externalDbClient.end(); // console.log('[SyncEmpleados] Disconnected from external PostgreSQL database.'); } else if (EXTERNAL_DB_TYPE === 'mysql') { // const mysql = require('mysql2/promise'); // User would uncomment and install // const connection = await mysql.createConnection({ // host: EXTERNAL_DB_HOST, // user: EXTERNAL_DB_USER, // password: EXTERNAL_DB_PASSWORD, // database: EXTERNAL_DB_NAME, // port: EXTERNAL_DB_PORT, // }); // console.log('[SyncEmpleados] Connected to external MySQL database.'); // ... (sync logic using connection) ... // await connection.end(); // console.log('[SyncEmpleados] Disconnected from external MySQL database.'); } else { console.error(`[SyncEmpleados] Unsupported EXTERNAL_DB_TYPE: ${EXTERNAL_DB_TYPE}. User needs to implement connection logic.`); // For now, we will just log the data that would be synced } */ // --- End of External DB Connection Logic --- console.log('[SyncEmpleados] --- Data to be Synced (Conceptual) ---'); for (const emp of localEmpleados) { console.log(`[SyncEmpleados] Processing employee: ID=${emp.id}, Cedula=${emp.cedula}, Name=${emp.name}`); // Conceptual Upsert Logic: The following section outlines where you would implement the upsert (update or insert) operation. // You'll need to use your chosen external database client to first check if an employee // with a matching unique identifier (e.g., emp.cedula) exists in the ${EXTERNAL_DB_EMPLEADOS_TABLE}. // If it exists, execute an UPDATE statement. If not, execute an INSERT statement. // Ensure you map fields from 'emp' (local employee) to the corresponding columns in your external table. // Example of data to be inserted/updated: const externalData = { // Assuming external table has these columns. User must map accordingly. // Ensure data types are compatible between local and external databases. cedula: emp.cedula, // Primary key for matching in the external table (assumed) nombre: emp.name, telefono: emp.telefono, ubicacion: emp.ubicacion, // local_id: emp.id, // Optional: store local ID for reference // ... map other fields ... }; console.log(`[SyncEmpleados] Data for external table: ${JSON.stringify(externalData)}`); } console.log('[SyncEmpleados] --- End of Data to be Synced ---'); } catch (error) { // Catch any errors that occur during the synchronization process. console.error('[SyncEmpleados] Error during synchronization:', error); } finally { // Ensure the Prisma client is always disconnected, even if an error occurs. await prisma.$disconnect(); console.log('[SyncEmpleados] Prisma client disconnected.'); } console.log('[SyncEmpleados] Synchronization process finished.'); } export { syncEmpleadosToExternalDB }; // --- Testing Considerations --- // 1. **Configuration is Key:** This script requires the `EXTERNAL_DB_...` variables to be correctly // configured with your actual external database credentials and details before any meaningful // end-to-end testing can be performed. // // 2. **Manual Testing:** // * Once configured, you can test the script by running it directly: `node worker/sync-empleados.js` // * Observe the console logs for any errors or successful completion messages. // * Verify that data from your local 'Cliente' table (where empleado=true) appears correctly // in your designated external database table (`EXTERNAL_DB_EMPLEADOS_TABLE`). // * Check that subsequent runs correctly update existing records and insert new ones. // * The cron job in `worker/cron-worker.js` is scheduled to run this script daily at midnight. // You can monitor logs after this time to see its execution. // // 3. **Automated Testing (Recommendations for future development):** // * **Unit Tests:** // - Mock the Prisma client (`../api/prisma/generated/client`) to return predefined employee data // and spy on its methods. // - Mock the external database client (e.g., `pg`, `mysql2`) to simulate connection, // query execution (select, insert, update), and disconnections. This allows testing // the sync logic without actual database dependencies. // * **Integration Tests:** // - If possible, set up a dedicated test instance of your external database. // - Write tests that populate the local Prisma test database with sample employee data, // run the sync script, and then query the external test database to assert that // the data was synchronized correctly. This provides more comprehensive testing // but requires more setup. // // 4. **Logging:** Pay close attention to the console output. The script includes logging for various // stages, which will be crucial for diagnosing issues during testing and operation. // --- End of Testing Considerations --- // Optional: For direct execution of this script, e.g., `node worker/sync-empleados.js` if (require.main === module) { console.log('[SyncEmpleados] Running synchronization script directly.'); syncEmpleadosToExternalDB() .then(() => console.log('[SyncEmpleados] Direct execution completed.')) .catch(err => console.error('[SyncEmpleados] Direct execution failed:', err)); }