"use strict"; const DatabaseManager = (function(){ const DatabaseManager = function(judge_pole){ const self = this; let data = { users : [], projects : [], criteria : [], votes : {} // { project_id: { user_id: { criterion_name: score } } } }; const constructor = () => { // Inicializar criterios por defecto si no existen const default_crit = judge_pole.settings.get("default_criteria", null, []); default_crit.forEach(crit => self.add_criterion(crit)); // Carga de base de datos externa inyectada if(typeof database != "undefined" && typeof database == "string"){ self.import_base64(database); } }; this.get_data = () => data; this.add_criterion = (criterion_name) => { criterion_name = ("" + criterion_name).trim(); if(criterion_name && !data.criteria.includes(criterion_name)){ data.criteria.push(criterion_name); return true; } return false; }; this.update_criterion = (old_name, new_name) => { old_name = ("" + old_name).trim(); new_name = ("" + new_name).trim(); if(!new_name || old_name === new_name) return false; const index = data.criteria.indexOf(old_name); if(index === -1) return false; // Reemplazar en la lista maestra data.criteria[index] = new_name; // Propagar en cascada en todos los votos existentes Object.keys(data.votes).forEach(project_id => { const project_votes = data.votes[project_id]; if(project_votes){ Object.keys(project_votes).forEach(user_id => { if(project_votes[user_id] && project_votes[user_id][old_name] !== undefined){ project_votes[user_id][new_name] = project_votes[user_id][old_name]; delete project_votes[user_id][old_name]; } }); } }); return true; }; this.delete_criterion = (criterion_name) => { criterion_name = ("" + criterion_name).trim(); const initial_len = data.criteria.length; data.criteria = data.criteria.filter(c => c !== criterion_name); if(data.criteria.length !== initial_len){ // Purgar el criterio de todos los votos guardados Object.keys(data.votes).forEach(project_id => { const project_votes = data.votes[project_id]; if(project_votes){ Object.keys(project_votes).forEach(user_id => { if(project_votes[user_id] && project_votes[user_id][criterion_name] !== undefined){ delete project_votes[user_id][criterion_name]; } }); } }); return true; } return false; }; this.save_votes = (project_id, vote_package) => { // vote_package: { scores, judge_weights, criteria_weights } data.votes[project_id] = vote_package; }; this.export_base64 = () => { const json_string = JSON.stringify(data, null, 4); return btoa(unescape(encodeURIComponent(json_string))); }; this.import_base64 = (base64_string) => { try { const json_string = decodeURIComponent(escape(atob(base64_string.trim()))); data = JSON.parse(json_string); return true; } catch(error) { console.error("Error al importar Base64:", error); return false; } }; this.delete_user = (user_id) => { const initial_length = data.users.length; data.users = data.users.filter(u => u.id !== user_id); if(data.users.length !== initial_length){ // Limpieza de proyectos huérfanos asociados a este usuario const removed_project_ids = data.projects .filter(p => p.user_id === user_id) .map(p => p.id); data.projects = data.projects.filter(p => p.user_id !== user_id); // Limpieza de votos del usuario o de proyectos eliminados removed_project_ids.forEach(p_id => { delete data.votes[p_id]; }); Object.keys(data.votes).forEach(p_id => { if(data.votes[p_id] && data.votes[p_id][user_id]){ delete data.votes[p_id][user_id]; } }); return true; } return false; }; this.add_user = (user_data) => { const now = new Date().toISOString(); const user = { id : "usr_" + Date.now() + "_" + Math.floor(Math.random() * 1000), type : user_data.type || "human", // "human" | "ai" nick : user_data.nick || "Anon", password : user_data.password ? user_data.password.trim() : "", description : user_data.description || "", avatar : user_data.avatar || "", links : user_data.links || [], created_at : now, updated_at : now }; data.users.push(user); return user; }; this.update_user = (user_id, updated_fields) => { const user = data.users.find(u => u.id === user_id); if(!user) return null; user.type = updated_fields.type !== undefined ? updated_fields.type : (user.type || "human"); user.nick = updated_fields.nick !== undefined ? updated_fields.nick : user.nick; user.password = updated_fields.password !== undefined ? updated_fields.password.trim() : (user.password || ""); user.description = updated_fields.description !== undefined ? updated_fields.description : user.description; user.avatar = updated_fields.avatar !== undefined ? updated_fields.avatar : user.avatar; user.links = updated_fields.links !== undefined ? updated_fields.links : user.links; user.updated_at = new Date().toISOString(); return user; }; this.add_project = (project_data) => { const now = new Date().toISOString(); const project = { id : "prj_" + Date.now() + "_" + Math.floor(Math.random() * 1000), user_ids : project_data.user_ids || (project_data.user_id ? [project_data.user_id] : []), name : project_data.name, description : project_data.description || "", avatar : project_data.avatar || "", tags : project_data.tags || [], technologies : project_data.technologies || [], links : project_data.links || [], created_at : now, updated_at : now }; data.projects.push(project); return project; }; this.update_project = (project_id, updated_fields) => { const project = data.projects.find(p => p.id === project_id); if(!project) return null; project.user_ids = updated_fields.user_ids !== undefined ? updated_fields.user_ids : (project.user_ids || (project.user_id ? [project.user_id] : [])); project.name = updated_fields.name !== undefined ? updated_fields.name : project.name; project.description = updated_fields.description !== undefined ? updated_fields.description : project.description; project.avatar = updated_fields.avatar !== undefined ? updated_fields.avatar : project.avatar; project.tags = updated_fields.tags !== undefined ? updated_fields.tags : project.tags; project.technologies = updated_fields.technologies !== undefined ? updated_fields.technologies : project.technologies; project.links = updated_fields.links !== undefined ? updated_fields.links : project.links; project.updated_at = new Date().toISOString(); return project; }; this.delete_project = (project_id) => { const initial_length = data.projects.length; data.projects = data.projects.filter(p => p.id !== project_id); if(data.projects.length !== initial_length){ // Limpieza de las puntuaciones asociadas al proyecto eliminado if(data.votes[project_id]){ delete data.votes[project_id]; } return true; } return false; }; constructor(); }; return DatabaseManager; })();