253 lines
9.5 KiB
Python
253 lines
9.5 KiB
Python
"""
|
|
Database initialization script
|
|
Creates required tables for the application
|
|
Run this script to initialize the database
|
|
"""
|
|
import pymysql
|
|
import os
|
|
import logging
|
|
import hashlib
|
|
from app.config import Config
|
|
|
|
logging.basicConfig(level=logging.INFO)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def hash_password(password):
|
|
"""Hash password using SHA256"""
|
|
return hashlib.sha256(password.encode()).hexdigest()
|
|
|
|
|
|
def create_database():
|
|
"""Create the database if it doesn't exist"""
|
|
try:
|
|
conn = pymysql.connect(
|
|
user=Config.DB_USER,
|
|
password=Config.DB_PASSWORD,
|
|
host=Config.DB_HOST,
|
|
port=Config.DB_PORT
|
|
)
|
|
cursor = conn.cursor()
|
|
|
|
# Create database
|
|
cursor.execute(f"CREATE DATABASE IF NOT EXISTS `{Config.DB_NAME}`")
|
|
logger.info(f"Database {Config.DB_NAME} created or already exists")
|
|
|
|
cursor.close()
|
|
conn.close()
|
|
except Exception as e:
|
|
logger.error(f"Error creating database: {e}")
|
|
raise
|
|
|
|
|
|
def create_tables():
|
|
"""Create application tables"""
|
|
try:
|
|
conn = pymysql.connect(
|
|
user=Config.DB_USER,
|
|
password=Config.DB_PASSWORD,
|
|
host=Config.DB_HOST,
|
|
port=Config.DB_PORT,
|
|
database=Config.DB_NAME
|
|
)
|
|
cursor = conn.cursor()
|
|
|
|
# Users table
|
|
cursor.execute("""
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
username VARCHAR(255) UNIQUE NOT NULL,
|
|
email VARCHAR(255),
|
|
full_name VARCHAR(255),
|
|
role VARCHAR(50) DEFAULT 'user',
|
|
is_active TINYINT(1) DEFAULT 1,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
""")
|
|
logger.info("Table 'users' created or already exists")
|
|
|
|
# User credentials table
|
|
cursor.execute("""
|
|
CREATE TABLE IF NOT EXISTS user_credentials (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
user_id INT NOT NULL,
|
|
password_hash VARCHAR(255) NOT NULL,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
""")
|
|
logger.info("Table 'user_credentials' created or already exists")
|
|
|
|
# Quality inspections table
|
|
cursor.execute("""
|
|
CREATE TABLE IF NOT EXISTS quality_inspections (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
inspection_type VARCHAR(100),
|
|
status VARCHAR(50),
|
|
inspector_id INT,
|
|
inspection_date DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
notes TEXT,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (inspector_id) REFERENCES users(id) ON DELETE SET NULL
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
""")
|
|
logger.info("Table 'quality_inspections' created or already exists")
|
|
|
|
# Settings table
|
|
cursor.execute("""
|
|
CREATE TABLE IF NOT EXISTS application_settings (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
setting_key VARCHAR(255) UNIQUE NOT NULL,
|
|
setting_value LONGTEXT,
|
|
setting_type VARCHAR(50),
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
""")
|
|
logger.info("Table 'application_settings' created or already exists")
|
|
|
|
# Roles table
|
|
cursor.execute("""
|
|
CREATE TABLE IF NOT EXISTS roles (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
name VARCHAR(100) UNIQUE NOT NULL,
|
|
description TEXT,
|
|
level INT DEFAULT 0,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
""")
|
|
logger.info("Table 'roles' created or already exists")
|
|
|
|
# User modules (which modules a user has access to)
|
|
cursor.execute("""
|
|
CREATE TABLE IF NOT EXISTS user_modules (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
user_id INT NOT NULL,
|
|
module_name VARCHAR(100) NOT NULL,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
UNIQUE KEY unique_user_module (user_id, module_name),
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
""")
|
|
logger.info("Table 'user_modules' created or already exists")
|
|
|
|
# User permissions (granular permissions)
|
|
cursor.execute("""
|
|
CREATE TABLE IF NOT EXISTS user_permissions (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
user_id INT NOT NULL,
|
|
module_name VARCHAR(100) NOT NULL,
|
|
section_name VARCHAR(100) NOT NULL,
|
|
action_name VARCHAR(100) NOT NULL,
|
|
granted TINYINT(1) DEFAULT 1,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
UNIQUE KEY unique_permission (user_id, module_name, section_name, action_name),
|
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
""")
|
|
logger.info("Table 'user_permissions' created or already exists")
|
|
|
|
conn.commit()
|
|
cursor.close()
|
|
conn.close()
|
|
logger.info("All tables created successfully")
|
|
except Exception as e:
|
|
logger.error(f"Error creating tables: {e}")
|
|
raise
|
|
|
|
|
|
def insert_default_user():
|
|
"""Insert default admin user and roles"""
|
|
try:
|
|
conn = pymysql.connect(
|
|
user=Config.DB_USER,
|
|
password=Config.DB_PASSWORD,
|
|
host=Config.DB_HOST,
|
|
port=Config.DB_PORT,
|
|
database=Config.DB_NAME
|
|
)
|
|
cursor = conn.cursor()
|
|
|
|
# Insert default roles if they don't exist
|
|
roles = [
|
|
('superadmin', 'Super Administrator - Full system access', 100),
|
|
('admin', 'Administrator - Administrative access', 90),
|
|
('manager', 'Manager - Full access to assigned modules', 70),
|
|
('worker', 'Worker - Limited access', 50),
|
|
]
|
|
|
|
for role_name, role_desc, role_level in roles:
|
|
cursor.execute(
|
|
"SELECT id FROM roles WHERE name = %s",
|
|
(role_name,)
|
|
)
|
|
if not cursor.fetchone():
|
|
cursor.execute(
|
|
"INSERT INTO roles (name, description, level) VALUES (%s, %s, %s)",
|
|
(role_name, role_desc, role_level)
|
|
)
|
|
logger.info(f"Role '{role_name}' created")
|
|
|
|
# Check if admin user exists
|
|
cursor.execute("SELECT id FROM users WHERE username = 'admin'")
|
|
admin_result = cursor.fetchone()
|
|
|
|
if admin_result:
|
|
logger.info("Admin user already exists")
|
|
cursor.close()
|
|
conn.close()
|
|
return
|
|
|
|
# Insert admin user
|
|
cursor.execute("""
|
|
INSERT INTO users (username, email, full_name, role, is_active)
|
|
VALUES (%s, %s, %s, %s, 1)
|
|
""", ('admin', 'admin@quality-app.local', 'Administrator', 'admin'))
|
|
|
|
# Get admin user ID
|
|
cursor.execute("SELECT id FROM users WHERE username = 'admin'")
|
|
admin_id = cursor.fetchone()[0]
|
|
|
|
# Insert admin password (default: admin123)
|
|
password_hash = hash_password('admin123')
|
|
cursor.execute("""
|
|
INSERT INTO user_credentials (user_id, password_hash)
|
|
VALUES (%s, %s)
|
|
""", (admin_id, password_hash))
|
|
|
|
# Grant admin user access to all modules
|
|
modules = ['quality', 'settings']
|
|
for module in modules:
|
|
cursor.execute("""
|
|
INSERT IGNORE INTO user_modules (user_id, module_name)
|
|
VALUES (%s, %s)
|
|
""", (admin_id, module))
|
|
|
|
conn.commit()
|
|
cursor.close()
|
|
conn.close()
|
|
|
|
logger.info("Default admin user created (username: admin, password: admin123)")
|
|
logger.warning("IMPORTANT: Change the default admin password after first login!")
|
|
except Exception as e:
|
|
logger.error(f"Error inserting default user: {e}")
|
|
raise
|
|
|
|
|
|
if __name__ == '__main__':
|
|
logger.info("Starting database initialization...")
|
|
|
|
try:
|
|
create_database()
|
|
create_tables()
|
|
insert_default_user()
|
|
logger.info("Database initialization completed successfully!")
|
|
except Exception as e:
|
|
logger.error(f"Database initialization failed: {e}")
|
|
exit(1)
|