Update db.js

This commit is contained in:
2026-01-09 23:12:12 +01:00
committed by GitHub
parent a6dc1d789e
commit 6aaca6adc4

View File

@@ -47,8 +47,6 @@ const dbInterface = {
return {
query: executeQuery,
release: () => {},
// Mock transaction methods for Postgres simple wrapper
// In a real prod app, you would get a specific client from the pool here
beginTransaction: async () => {},
commit: async () => {},
rollback: async () => {}
@@ -66,44 +64,47 @@ const initDb = async () => {
const TIMESTAMP_TYPE = 'TIMESTAMP';
const LONG_TEXT_TYPE = DB_CLIENT === 'postgres' ? 'TEXT' : 'LONGTEXT'; // For base64 files
const JSON_TYPE = 'JSON';
// 0. Settings Table (Global App Settings)
// --- 0. SETTINGS TABLE ---
// Definizione completa per nuova installazione
await connection.query(`
CREATE TABLE IF NOT EXISTS settings (
id INT PRIMARY KEY,
current_year INT,
smtp_config JSON ${DB_CLIENT === 'postgres' ? 'NULL' : 'NULL'},
features JSON ${DB_CLIENT === 'postgres' ? 'NULL' : 'NULL'},
storage_config JSON ${DB_CLIENT === 'postgres' ? 'NULL' : 'NULL'}
smtp_config ${JSON_TYPE},
features ${JSON_TYPE},
storage_config ${JSON_TYPE},
branding ${JSON_TYPE}
)
`);
// Migration: Add features column if not exists
// MIGRATION: Controllo e aggiunta colonne mancanti per installazioni esistenti
try {
let hasFeatures = false;
let hasStorage = false;
let cols = [];
if (DB_CLIENT === 'postgres') {
const [cols] = await connection.query("SELECT column_name FROM information_schema.columns WHERE table_name='settings'");
hasFeatures = cols.some(c => c.column_name === 'features');
hasStorage = cols.some(c => c.column_name === 'storage_config');
const [res] = await connection.query("SELECT column_name FROM information_schema.columns WHERE table_name='settings'");
cols = res.map(c => c.column_name);
} else {
const [cols] = await connection.query("SHOW COLUMNS FROM settings");
hasFeatures = cols.some(c => c.Field === 'features');
hasStorage = cols.some(c => c.Field === 'storage_config');
const [res] = await connection.query("SHOW COLUMNS FROM settings");
cols = res.map(c => c.Field);
}
if (!hasFeatures) {
if (!cols.includes('features')) {
console.log('Migrating: Adding features to settings...');
await connection.query("ALTER TABLE settings ADD COLUMN features JSON");
}
if (!hasStorage) {
if (!cols.includes('storage_config')) {
console.log('Migrating: Adding storage_config to settings...');
await connection.query("ALTER TABLE settings ADD COLUMN storage_config JSON");
}
if (!cols.includes('branding')) {
console.log('Migrating: Adding branding to settings...');
await connection.query("ALTER TABLE settings ADD COLUMN branding JSON");
}
} catch(e) { console.warn("Settings migration warning:", e.message); }
// 1. Condos Table
// --- 1. CONDOS TABLE ---
await connection.query(`
CREATE TABLE IF NOT EXISTS condos (
id VARCHAR(36) PRIMARY KEY,
@@ -123,24 +124,24 @@ const initDb = async () => {
)
`);
// Migration for condos due_day
// Migration condos
try {
let hasDueDay = false;
let cols = [];
if (DB_CLIENT === 'postgres') {
const [cols] = await connection.query("SELECT column_name FROM information_schema.columns WHERE table_name='condos'");
hasDueDay = cols.some(c => c.column_name === 'due_day');
const [res] = await connection.query("SELECT column_name FROM information_schema.columns WHERE table_name='condos'");
cols = res.map(c => c.column_name);
} else {
const [cols] = await connection.query("SHOW COLUMNS FROM condos");
hasDueDay = cols.some(c => c.Field === 'due_day');
const [res] = await connection.query("SHOW COLUMNS FROM condos");
cols = res.map(c => c.Field);
}
if (!hasDueDay) {
if (!cols.includes('due_day')) {
console.log('Migrating: Adding due_day to condos...');
await connection.query("ALTER TABLE condos ADD COLUMN due_day INT DEFAULT 10");
}
} catch(e) { console.warn("Condo migration warning:", e.message); }
// 2. Families Table
// --- 2. FAMILIES TABLE ---
await connection.query(`
CREATE TABLE IF NOT EXISTS families (
id VARCHAR(36) PRIMARY KEY,
@@ -157,7 +158,24 @@ const initDb = async () => {
)
`);
// 3. Payments Table
// Migration families
try {
let cols = [];
if (DB_CLIENT === 'postgres') {
const [res] = await connection.query("SELECT column_name FROM information_schema.columns WHERE table_name='families'");
cols = res.map(c => c.column_name);
} else {
const [res] = await connection.query("SHOW COLUMNS FROM families");
cols = res.map(c => c.Field);
}
if (!cols.includes('custom_monthly_quota')) {
console.log('Migrating: Adding custom_monthly_quota to families...');
await connection.query("ALTER TABLE families ADD COLUMN custom_monthly_quota DECIMAL(10, 2) NULL");
}
} catch(e) { console.warn("Family migration warning:", e.message); }
// --- 3. PAYMENTS TABLE ---
await connection.query(`
CREATE TABLE IF NOT EXISTS payments (
id VARCHAR(36) PRIMARY KEY,
@@ -173,7 +191,7 @@ const initDb = async () => {
)
`);
// 4. Users Table
// --- 4. USERS TABLE ---
await connection.query(`
CREATE TABLE IF NOT EXISTS users (
id VARCHAR(36) PRIMARY KEY,
@@ -189,7 +207,7 @@ const initDb = async () => {
)
`);
// 5. Alerts Table
// --- 5. ALERTS TABLE ---
await connection.query(`
CREATE TABLE IF NOT EXISTS alerts (
id VARCHAR(36) PRIMARY KEY,
@@ -206,7 +224,7 @@ const initDb = async () => {
)
`);
// 6. Notices Table
// --- 6. NOTICES TABLE ---
await connection.query(`
CREATE TABLE IF NOT EXISTS notices (
id VARCHAR(36) PRIMARY KEY,
@@ -217,13 +235,30 @@ const initDb = async () => {
link VARCHAR(255),
date ${TIMESTAMP_TYPE} DEFAULT CURRENT_TIMESTAMP,
active BOOLEAN DEFAULT TRUE,
target_families JSON ${DB_CLIENT === 'postgres' ? 'NULL' : 'NULL'},
target_families ${JSON_TYPE},
created_at ${TIMESTAMP_TYPE} DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (condo_id) REFERENCES condos(id) ON DELETE CASCADE
)
`);
// 7. Notice Reads
// Migration notices
try {
let cols = [];
if (DB_CLIENT === 'postgres') {
const [res] = await connection.query("SELECT column_name FROM information_schema.columns WHERE table_name='notices'");
cols = res.map(c => c.column_name);
} else {
const [res] = await connection.query("SHOW COLUMNS FROM notices");
cols = res.map(c => c.Field);
}
if (!cols.includes('target_families')) {
console.log('Migrating: Adding target_families to notices...');
await connection.query("ALTER TABLE notices ADD COLUMN target_families JSON");
}
} catch(e) { console.warn("Notices migration warning:", e.message); }
// --- 7. NOTICE READS ---
await connection.query(`
CREATE TABLE IF NOT EXISTS notice_reads (
user_id VARCHAR(36),
@@ -234,7 +269,7 @@ const initDb = async () => {
)
`);
// 8. Tickets Table
// --- 8. TICKETS TABLE ---
await connection.query(`
CREATE TABLE IF NOT EXISTS tickets (
id VARCHAR(36) PRIMARY KEY,
@@ -252,7 +287,7 @@ const initDb = async () => {
)
`);
// 9. Ticket Attachments
// --- 9. TICKET ATTACHMENTS ---
await connection.query(`
CREATE TABLE IF NOT EXISTS ticket_attachments (
id VARCHAR(36) PRIMARY KEY,
@@ -265,7 +300,7 @@ const initDb = async () => {
)
`);
// 10. Ticket Comments
// --- 10. TICKET COMMENTS ---
await connection.query(`
CREATE TABLE IF NOT EXISTS ticket_comments (
id VARCHAR(36) PRIMARY KEY,
@@ -278,7 +313,7 @@ const initDb = async () => {
)
`);
// 11. Extraordinary Expenses
// --- 11. EXTRAORDINARY EXPENSES ---
await connection.query(`
CREATE TABLE IF NOT EXISTS extraordinary_expenses (
id VARCHAR(36) PRIMARY KEY,
@@ -330,7 +365,7 @@ const initDb = async () => {
)
`);
// 12. CONDO ORDINARY EXPENSES (USCITE)
// --- 12. CONDO ORDINARY EXPENSES (USCITE) ---
await connection.query(`
CREATE TABLE IF NOT EXISTS condo_expenses (
id VARCHAR(36) PRIMARY KEY,
@@ -360,7 +395,7 @@ const initDb = async () => {
)
`);
// 13. DOCUMENTS (Cloud/Local)
// --- 13. DOCUMENTS (Cloud/Local) ---
await connection.query(`
CREATE TABLE IF NOT EXISTS documents (
id VARCHAR(36) PRIMARY KEY,
@@ -370,7 +405,7 @@ const initDb = async () => {
file_name VARCHAR(255) NOT NULL,
file_type VARCHAR(100),
file_size INT,
tags JSON ${DB_CLIENT === 'postgres' ? 'NULL' : 'NULL'},
tags ${JSON_TYPE},
storage_provider VARCHAR(50) DEFAULT 'local_db',
file_data ${LONG_TEXT_TYPE},
upload_date ${TIMESTAMP_TYPE} DEFAULT CURRENT_TIMESTAMP,
@@ -388,48 +423,45 @@ const initDb = async () => {
reports: true,
extraordinaryExpenses: true,
condoFinancialsView: false,
documents: true // Enabled by default for demo
documents: true
};
const defaultStorage = {
provider: 'local_db'
provider: 'local_db',
apiKey: '',
apiSecret: '',
bucket: '',
region: ''
};
const defaultBranding = {
appName: 'CondoPay',
primaryColor: 'blue',
logoUrl: '',
loginBackgroundUrl: ''
};
if (rows.length === 0) {
const currentYear = new Date().getFullYear();
await connection.query(
'INSERT INTO settings (id, current_year, features, storage_config) VALUES (1, ?, ?, ?)',
[currentYear, JSON.stringify(defaultFeatures), JSON.stringify(defaultStorage)]
'INSERT INTO settings (id, current_year, features, storage_config, branding) VALUES (1, ?, ?, ?, ?)',
[currentYear, JSON.stringify(defaultFeatures), JSON.stringify(defaultStorage), JSON.stringify(defaultBranding)]
);
} else {
// Ensure features column has defaults if null
if (!rows[0].features) {
await connection.query('UPDATE settings SET features = ? WHERE id = 1', [JSON.stringify(defaultFeatures)]);
}
if (!rows[0].storage_config) {
await connection.query('UPDATE settings SET storage_config = ? WHERE id = 1', [JSON.stringify(defaultStorage)]);
}
}
// ENSURE ADMIN EXISTS
const [admins] = await connection.query('SELECT * FROM users WHERE email = ?', ['fcarra79@gmail.com']);
if (admins.length === 0) {
const hashedPassword = await bcrypt.hash('Mr10921.', 10);
const { v4: uuidv4 } = require('uuid');
const hash = await bcrypt.hash('admin', 10);
await connection.query(
'INSERT INTO users (id, email, password_hash, name, role) VALUES (?, ?, ?, ?, ?)',
[uuidv4(), 'fcarra79@gmail.com', hashedPassword, 'Amministratore', 'admin']
'INSERT INTO users (id, email, password_hash, name, role, receive_alerts) VALUES (?, ?, ?, ?, ?, ?)',
['admin-id', 'admin@condo.it', hash, 'Amministratore', 'admin', true]
);
} else {
await connection.query('UPDATE users SET role = ? WHERE email = ?', ['admin', 'fcarra79@gmail.com']);
console.log("Database initialized with seed data.");
}
console.log('Database tables initialized.');
if (connection.release) connection.release();
} catch (error) {
console.error('Database initialization failed:', error);
process.exit(1);
if (DB_CLIENT !== 'postgres') {
connection.release();
}
} catch (e) {
console.error("Database init error:", e);
}
};
module.exports = { pool: dbInterface, initDb };
module.exports = { pool: DB_CLIENT === 'postgres' ? pgPool : mysqlPool, initDb };