Files
location-mqtt-tracker-app/scripts/add-mqtt-tables.js
2025-11-24 16:30:37 +00:00

104 lines
3.1 KiB
JavaScript

#!/usr/bin/env node
/**
* Migration script to add MQTT credentials and ACL tables
* This extends the existing database with MQTT provisioning capabilities
*/
const Database = require('better-sqlite3');
const path = require('path');
const fs = require('fs');
const dataDir = path.join(__dirname, '..', 'data');
const dbPath = path.join(dataDir, 'database.sqlite');
// Check if database exists
if (!fs.existsSync(dbPath)) {
console.error('❌ Database not found. Run npm run db:init:app first');
process.exit(1);
}
// Open database
const db = new Database(dbPath);
db.pragma('journal_mode = WAL');
console.log('Starting MQTT tables migration...\n');
// Create mqtt_credentials table
db.exec(`
CREATE TABLE IF NOT EXISTS mqtt_credentials (
id INTEGER PRIMARY KEY AUTOINCREMENT,
device_id TEXT NOT NULL UNIQUE,
mqtt_username TEXT NOT NULL UNIQUE,
mqtt_password_hash TEXT NOT NULL,
enabled INTEGER DEFAULT 1,
created_at TEXT DEFAULT (datetime('now')),
updated_at TEXT DEFAULT (datetime('now')),
FOREIGN KEY (device_id) REFERENCES Device(id) ON DELETE CASCADE,
CHECK (enabled IN (0, 1))
);
`);
console.log('✓ Created mqtt_credentials table');
// Create mqtt_acl_rules table
db.exec(`
CREATE TABLE IF NOT EXISTS mqtt_acl_rules (
id INTEGER PRIMARY KEY AUTOINCREMENT,
device_id TEXT NOT NULL,
topic_pattern TEXT NOT NULL,
permission TEXT NOT NULL CHECK(permission IN ('read', 'write', 'readwrite')),
created_at TEXT DEFAULT (datetime('now')),
FOREIGN KEY (device_id) REFERENCES Device(id) ON DELETE CASCADE
);
`);
console.log('✓ Created mqtt_acl_rules table');
// Create indexes for performance
db.exec(`
CREATE INDEX IF NOT EXISTS idx_mqtt_credentials_device
ON mqtt_credentials(device_id);
CREATE INDEX IF NOT EXISTS idx_mqtt_credentials_username
ON mqtt_credentials(mqtt_username);
CREATE INDEX IF NOT EXISTS idx_mqtt_acl_device
ON mqtt_acl_rules(device_id);
`);
console.log('✓ Created indexes');
// Create mqtt_sync_status table to track pending changes
db.exec(`
CREATE TABLE IF NOT EXISTS mqtt_sync_status (
id INTEGER PRIMARY KEY CHECK (id = 1),
pending_changes INTEGER DEFAULT 0,
last_sync_at TEXT,
last_sync_status TEXT,
created_at TEXT DEFAULT (datetime('now')),
updated_at TEXT DEFAULT (datetime('now'))
);
`);
console.log('✓ Created mqtt_sync_status table');
// Initialize sync status
const syncStatus = db.prepare('SELECT * FROM mqtt_sync_status WHERE id = 1').get();
if (!syncStatus) {
db.prepare(`
INSERT INTO mqtt_sync_status (id, pending_changes, last_sync_status)
VALUES (1, 0, 'never_synced')
`).run();
console.log('✓ Initialized sync status');
} else {
console.log('✓ Sync status already exists');
}
// Get stats
const mqttCredsCount = db.prepare('SELECT COUNT(*) as count FROM mqtt_credentials').get();
const aclRulesCount = db.prepare('SELECT COUNT(*) as count FROM mqtt_acl_rules').get();
console.log(`\n✓ MQTT tables migration completed successfully!`);
console.log(` MQTT Credentials: ${mqttCredsCount.count}`);
console.log(` ACL Rules: ${aclRulesCount.count}`);
db.close();