Add MQTT tables and parent_user_id column to database schema
Added MQTT credentials, ACL rules, and sync status tables for broker integration. Added parent_user_id column to User table for hierarchical user management. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -33,6 +33,7 @@ db.exec(`
|
|||||||
email TEXT,
|
email TEXT,
|
||||||
passwordHash TEXT NOT NULL,
|
passwordHash TEXT NOT NULL,
|
||||||
role TEXT NOT NULL DEFAULT 'VIEWER',
|
role TEXT NOT NULL DEFAULT 'VIEWER',
|
||||||
|
parent_user_id TEXT,
|
||||||
createdAt TEXT DEFAULT (datetime('now')),
|
createdAt TEXT DEFAULT (datetime('now')),
|
||||||
updatedAt TEXT DEFAULT (datetime('now')),
|
updatedAt TEXT DEFAULT (datetime('now')),
|
||||||
lastLoginAt TEXT,
|
lastLoginAt TEXT,
|
||||||
@@ -64,6 +65,7 @@ console.log('✓ Created Device table');
|
|||||||
// Create indexes
|
// Create indexes
|
||||||
db.exec(`
|
db.exec(`
|
||||||
CREATE INDEX IF NOT EXISTS idx_user_username ON User(username);
|
CREATE INDEX IF NOT EXISTS idx_user_username ON User(username);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_user_parent ON User(parent_user_id);
|
||||||
CREATE INDEX IF NOT EXISTS idx_device_owner ON Device(ownerId);
|
CREATE INDEX IF NOT EXISTS idx_device_owner ON Device(ownerId);
|
||||||
CREATE INDEX IF NOT EXISTS idx_device_active ON Device(isActive);
|
CREATE INDEX IF NOT EXISTS idx_device_active ON Device(isActive);
|
||||||
`);
|
`);
|
||||||
@@ -99,6 +101,75 @@ db.exec(`
|
|||||||
`);
|
`);
|
||||||
console.log('✓ Created password reset tokens index');
|
console.log('✓ Created password reset tokens index');
|
||||||
|
|
||||||
|
// 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 MQTT sync status table
|
||||||
|
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');
|
||||||
|
|
||||||
|
// Create MQTT indexes
|
||||||
|
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 MQTT indexes');
|
||||||
|
|
||||||
|
// Initialize MQTT 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 MQTT sync status');
|
||||||
|
} else {
|
||||||
|
console.log('✓ MQTT sync status already exists');
|
||||||
|
}
|
||||||
|
|
||||||
// Check if admin user exists
|
// Check if admin user exists
|
||||||
const existingAdmin = db.prepare('SELECT * FROM User WHERE username = ?').get('admin');
|
const existingAdmin = db.prepare('SELECT * FROM User WHERE username = ?').get('admin');
|
||||||
|
|
||||||
@@ -106,9 +177,9 @@ if (!existingAdmin) {
|
|||||||
// Create default admin user
|
// Create default admin user
|
||||||
const passwordHash = bcrypt.hashSync('admin123', 10);
|
const passwordHash = bcrypt.hashSync('admin123', 10);
|
||||||
db.prepare(`
|
db.prepare(`
|
||||||
INSERT INTO User (id, username, email, passwordHash, role)
|
INSERT INTO User (id, username, email, passwordHash, role, parent_user_id)
|
||||||
VALUES (?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?, ?)
|
||||||
`).run('admin-001', 'admin', 'admin@example.com', passwordHash, 'ADMIN');
|
`).run('admin-001', 'admin', 'admin@example.com', passwordHash, 'ADMIN', null);
|
||||||
console.log('✓ Created default admin user (username: admin, password: admin123)');
|
console.log('✓ Created default admin user (username: admin, password: admin123)');
|
||||||
} else {
|
} else {
|
||||||
console.log('✓ Admin user already exists');
|
console.log('✓ Admin user already exists');
|
||||||
|
|||||||
Reference in New Issue
Block a user