Refactor: Centralize Prisma schema and restrict DB access
This commit refactors the project to use a shared Prisma schema and restricts direct database access to the API service. Key changes: - Created a new shared package `core/prisma` containing the Prisma schema, generated client, and types. - Configured the monorepo to use NPM workspaces, including `core/prisma` and all services. - Updated all services (`api`, `ui`, `mcp`, `agent`, and the background processing service) to depend on `@empresa/prisma-schema`. - The API service now imports `PrismaClient` from `@empresa/prisma-schema/client`. - Other services import only types from `@empresa/prisma-schema`. - Removed redundant Prisma configurations from `api` and the background processing service. - Updated the background processing service's `sync-empleados.js` to fetch data via an API call instead of direct database access. - Updated TypeScript configurations (`tsconfig.base.json` and service-specific ones) to support the new structure and path aliases. - Updated `README.md` to reflect the new architecture and added convenience scripts for Prisma operations. This change promotes a single source of truth for data models, reduces code duplication, and improves the overall architecture by centralizing database operations within the API service.
This commit is contained in:
14
worker/jsconfig.json
Normal file
14
worker/jsconfig.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"extends": "../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"checkJs": false,
|
||||
"resolveJsonModule": true,
|
||||
"moduleResolution": "node",
|
||||
"target": "esnext", // Or appropriate target for your Node.js version
|
||||
"module": "esnext", // Since package.json has "type": "module"
|
||||
// Paths are inherited from tsconfig.base.json
|
||||
"baseUrl": "." // baseUrl is still needed if there are other local paths
|
||||
},
|
||||
"include": ["**/*.js"],
|
||||
"exclude": ["node_modules", "prisma"] // Excluding worker/prisma as it's not used anymore
|
||||
}
|
||||
@@ -7,10 +7,9 @@
|
||||
"start": "node server.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@prisma/client": "^6.7.0",
|
||||
"@empresa/prisma-schema": "1.0.0",
|
||||
"express": "^4.18.2",
|
||||
"node-cron": "^4.0.5",
|
||||
"pg": "^8.8.0",
|
||||
"prisma": "^6.7.0"
|
||||
"pg": "^8.8.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
// This is your Prisma schema file,
|
||||
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
||||
|
||||
// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
|
||||
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init
|
||||
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
output = "../generated/prisma"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
@@ -17,33 +17,31 @@ const EXTERNAL_DB_NAME = process.env.EXTERNAL_DB_NAME || 'YOUR_EXTERNAL_DB_NAME'
|
||||
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();
|
||||
// Import types from the shared Prisma package.
|
||||
// We are not importing PrismaClient here as the worker will fetch data from the API.
|
||||
import type { Cliente } from '@empresa/prisma-schema'; // Assuming Cliente is the relevant type for employees
|
||||
|
||||
// Define a type for the employee data we expect from the API.
|
||||
// This might be identical to Cliente or a subset, depending on the API endpoint.
|
||||
type EmployeeDataFromAPI = Pick<Cliente, 'id' | 'name' | 'cedula' | 'ubicacion' | 'telefono'>;
|
||||
|
||||
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
|
||||
},
|
||||
});
|
||||
// TODO: Fetch employee data from the API (e.g., GET /api/empleados)
|
||||
// This is a placeholder for the API call logic.
|
||||
console.log('[SyncEmpleados] Fetching employee data from API...');
|
||||
const response = await fetch('http://localhost:4000/api/empleados'); // Replace with your actual API endpoint
|
||||
if (!response.ok) {
|
||||
throw new Error(`API request failed with status ${response.status}`);
|
||||
}
|
||||
const localEmpleados: EmployeeDataFromAPI[] = await response.json();
|
||||
|
||||
if (!localEmpleados.length) {
|
||||
console.log('[SyncEmpleados] No employees found in local database. Nothing to sync.');
|
||||
if (!localEmpleados || !localEmpleados.length) {
|
||||
console.log('[SyncEmpleados] No employees found from API. Nothing to sync.');
|
||||
return;
|
||||
}
|
||||
console.log(`[SyncEmpleados] Found ${localEmpleados.length} employees to sync.`);
|
||||
console.log(`[SyncEmpleados] Found ${localEmpleados.length} employees from API 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
|
||||
@@ -119,9 +117,7 @@ async function syncEmpleadosToExternalDB() {
|
||||
// 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.');
|
||||
// No Prisma client to disconnect as we are using API.
|
||||
}
|
||||
console.log('[SyncEmpleados] Synchronization process finished.');
|
||||
}
|
||||
@@ -136,19 +132,17 @@ export { syncEmpleadosToExternalDB };
|
||||
// 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.
|
||||
// * Verify that data fetched from the API appears correctly (or is logged as intended for now)
|
||||
// if you have implemented the external DB sync part.
|
||||
// * The cron job in `worker/cron-worker.js` is scheduled to run this script.
|
||||
// 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 API call (`fetch`) to return predefined employee data.
|
||||
// - 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.
|
||||
// the sync logic without actual API or 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,
|
||||
|
||||
Reference in New Issue
Block a user