JudgePole/Public/ecma/Managers/DatabaseManager.ecma.js
2026-09-20 17:12:09 +02:00

221 lines
8.9 KiB
JavaScript

"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;
})();