feat: Add daily employee data synchronization

I've added a new capability to synchronize employee data from the local database to an external database on a daily basis.

Key changes:

-   **`worker/sync-empleados.js`**: This new script:
    -   Connects to the local Prisma database to fetch `Cliente` records where `empleado` is true.
    -   Provides clear placeholders and guidance for connecting to an external database (you must configure details like host, credentials, DB type, and table name, and implement specific DB client logic).
    -   Outlines a conceptual "upsert" logic (update existing, insert new) for the external database.
    -   Includes extensive comments on configuration, operation, and testing considerations.

-   **`worker/cron-worker.js`**:
    -   I modified this to import and schedule the `syncEmpleadosToExternalDB` function from the new script.
    -   The synchronization is scheduled to run daily at midnight.
    -   The existing example 5-second cron job has been commented as an example.

-   **Documentation**:
    -   I added in-code comments to both modified/new files to explain functionality.
    -   `sync-empleados.js` includes sections on external DB configuration and detailed testing considerations (manual and automated).

You will need to provide the actual connection details and logic for your specific external database system.
This commit is contained in:
google-labs-jules[bot]
2025-05-30 06:48:19 +00:00
parent 2c43538db3
commit 3fdba1fe89
2 changed files with 180 additions and 0 deletions

169
worker/sync-empleados.js Normal file
View File

@@ -0,0 +1,169 @@
// 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));
}