- Commission = 5% of total wallet balances (not sales) - Track commission payments in commission_payments table (migration 007) - Show 'Due Now' = current commission - last payment amount - Record payment form with amount and optional note - Payment history table with date, balances, commission, paid, delta - Delta shows difference between consecutive payments (new users = more owed) - Seed phrase unlock reminder shows the commission due amount - Stat warning highlight when commission is due
62 lines
2.2 KiB
JavaScript
62 lines
2.2 KiB
JavaScript
import db from '../config/database.js';
|
|
import logger from '../utils/logger.js';
|
|
|
|
const ALLOWED_TABLES = new Set([
|
|
'users', 'crypto_wallets', 'transactions', 'products',
|
|
'purchases', 'locations', 'categories', 'subcategories'
|
|
]);
|
|
|
|
export const checkColumnExists = async (tableName, columnName) => {
|
|
if (!ALLOWED_TABLES.has(tableName)) {
|
|
throw new Error(`Invalid table name: ${tableName}`);
|
|
}
|
|
try {
|
|
const result = await db.allAsync(`PRAGMA table_info(${tableName})`);
|
|
return result.some(column => column.name === columnName);
|
|
} catch (error) {
|
|
logger.error({ err: error, tableName, columnName }, 'Error checking column');
|
|
return false;
|
|
}
|
|
};
|
|
|
|
export const cleanUpInvalidForeignKeys = async () => {
|
|
try {
|
|
await db.runAsync(`DELETE FROM crypto_wallets WHERE user_id NOT IN (SELECT id FROM users)`);
|
|
logger.info('Cleaned up invalid foreign key references in crypto_wallets table');
|
|
} catch (error) {
|
|
logger.error({ err: error }, 'Error cleaning up invalid foreign key references');
|
|
}
|
|
};
|
|
|
|
export async function runMigrations() {
|
|
await db.runAsync(`CREATE TABLE IF NOT EXISTS _meta (key TEXT PRIMARY KEY, value TEXT)`);
|
|
|
|
const row = await db.getAsync(`SELECT value FROM _meta WHERE key = 'schema_version'`);
|
|
const currentVersion = row ? parseInt(row.value, 10) : 0;
|
|
|
|
const migrations = [
|
|
(await import('./001_initial_schema.js')).default,
|
|
(await import('./002_add_columns.js')).default,
|
|
(await import('./003_add_indexes.js')).default,
|
|
(await import('./004_user_states.js')).default,
|
|
(await import('./005_audit_log.js')).default,
|
|
(await import('./006_subcategories.js')).default,
|
|
(await import('./007_commission_payments.js')).default,
|
|
];
|
|
|
|
for (let i = currentVersion; i < migrations.length; i++) {
|
|
logger.info({ migration: i + 1, total: migrations.length }, 'Running migration');
|
|
if (i === 1) {
|
|
await migrations[i](db, checkColumnExists);
|
|
} else {
|
|
await migrations[i](db);
|
|
}
|
|
await db.runAsync(
|
|
`INSERT OR REPLACE INTO _meta (key, value) VALUES ('schema_version', ?)`,
|
|
[String(i + 1)]
|
|
);
|
|
}
|
|
|
|
logger.info({ schemaVersion: migrations.length }, 'Migrations complete');
|
|
}
|