Working Database setupgit add .
This commit is contained in:
110
src/services/sync.service.ts
Normal file
110
src/services/sync.service.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
import { fetchGradesFromScraper } from './scraper.service';
|
||||
import { syncGradesToDatabase, getAllUsers } from './grades.service';
|
||||
|
||||
interface SyncResult {
|
||||
username: string;
|
||||
success: boolean;
|
||||
error?: string;
|
||||
classesProcessed?: number;
|
||||
assignmentsAdded?: number;
|
||||
assignmentsUpdated?: number;
|
||||
}
|
||||
|
||||
export async function syncUserGrades(
|
||||
username: string,
|
||||
password: string
|
||||
): Promise<SyncResult> {
|
||||
try {
|
||||
console.log(`[Sync] Starting sync for user: ${username}`);
|
||||
|
||||
// Step 1: Fetch from scraper
|
||||
const gradesData = await fetchGradesFromScraper(username, password);
|
||||
|
||||
// Step 2: Save to database
|
||||
const result = await syncGradesToDatabase(username, password, gradesData);
|
||||
|
||||
console.log(`[Sync] ✓ Completed for ${username}: ${result.classesProcessed} classes, ${result.assignmentsAdded} new, ${result.assignmentsUpdated} updated`);
|
||||
|
||||
return {
|
||||
username,
|
||||
success: true,
|
||||
classesProcessed: result.classesProcessed,
|
||||
assignmentsAdded: result.assignmentsAdded,
|
||||
assignmentsUpdated: result.assignmentsUpdated,
|
||||
};
|
||||
} catch (error) {
|
||||
const errorMsg = error instanceof Error ? error.message : String(error);
|
||||
console.error(`[Sync] ✗ Failed for ${username}: ${errorMsg}`);
|
||||
|
||||
return {
|
||||
username,
|
||||
success: false,
|
||||
error: errorMsg,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export async function syncMultipleUsers(): Promise<{
|
||||
total: number;
|
||||
successful: number;
|
||||
failed: number;
|
||||
results: SyncResult[];
|
||||
duration: number;
|
||||
}> {
|
||||
const startTime = Date.now();
|
||||
const maxConcurrent = parseInt(process.env.MAX_CONCURRENT_SYNCS || '3');
|
||||
|
||||
console.log(`\n[Sync Job] Starting batch sync (max ${maxConcurrent} concurrent)`);
|
||||
|
||||
// Get all users with their credentials
|
||||
const users = await getAllUsers();
|
||||
|
||||
if (users.length === 0) {
|
||||
console.log('[Sync Job] No users to sync');
|
||||
return {
|
||||
total: 0,
|
||||
successful: 0,
|
||||
failed: 0,
|
||||
results: [],
|
||||
duration: 0,
|
||||
};
|
||||
}
|
||||
|
||||
// We need to get passwords, so fetch full user records
|
||||
const { prisma } = await import('../db');
|
||||
const usersWithPasswords = await prisma.user.findMany({
|
||||
select: {
|
||||
username: true,
|
||||
password: true,
|
||||
},
|
||||
});
|
||||
|
||||
const results: SyncResult[] = [];
|
||||
|
||||
// Process in batches
|
||||
for (let i = 0; i < usersWithPasswords.length; i += maxConcurrent) {
|
||||
const batch = usersWithPasswords.slice(i, i + maxConcurrent);
|
||||
console.log(`[Sync Job] Processing batch ${Math.floor(i / maxConcurrent) + 1}: ${batch.map(u => u.username).join(', ')}`);
|
||||
|
||||
const batchPromises = batch.map(user =>
|
||||
syncUserGrades(user.username, user.password)
|
||||
);
|
||||
|
||||
const batchResults = await Promise.all(batchPromises);
|
||||
results.push(...batchResults);
|
||||
}
|
||||
|
||||
const successful = results.filter(r => r.success).length;
|
||||
const failed = results.filter(r => !r.success).length;
|
||||
const duration = Date.now() - startTime;
|
||||
|
||||
console.log(`[Sync Job] Completed: ${successful} successful, ${failed} failed (${(duration / 1000).toFixed(1)}s)\n`);
|
||||
|
||||
return {
|
||||
total: users.length,
|
||||
successful,
|
||||
failed,
|
||||
results,
|
||||
duration,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user