feat: Implement comprehensive database setup system

- Add complete database setup script (setup_complete_database.py)
- Add quick deployment script (quick_deploy.sh)
- Add comprehensive documentation (DATABASE_SETUP_README.md)
- Move individual db scripts to backup_db_scripts folder
- Update external_server.conf with correct database settings
- Clean up obsolete documentation files
- Streamline deployment process to single command

Features:
- One-script database creation for all tables and triggers
- Automated permissions and roles setup
- Complete verification and error handling
- Production-ready deployment workflow
- Maintains backward compatibility with individual scripts
This commit is contained in:
Quality System Admin
2025-10-11 21:45:37 +03:00
parent 05394697a0
commit af62fa478f
30 changed files with 924 additions and 679 deletions

View File

@@ -5,7 +5,7 @@ db_config = {
"user": "trasabilitate",
"password": "Initial01!",
"host": "localhost",
"database": "trasabilitate_database"
"database": "trasabilitate"
}
# Connect to the database

View File

@@ -6,7 +6,7 @@ db_config = {
"user": "trasabilitate",
"password": "Initial01!",
"host": "localhost",
"database": "trasabilitate_database"
"database": "trasabilitate"
}
try:

View File

@@ -5,7 +5,7 @@ db_config = {
"user": "trasabilitate",
"password": "Initial01!",
"host": "localhost",
"database": "trasabilitate_database"
"database": "trasabilitate"
}
# Connect to the database

View File

@@ -5,7 +5,7 @@ db_config = {
"user": "trasabilitate",
"password": "Initial01!",
"host": "localhost",
"database": "trasabilitate_database"
"database": "trasabilitate"
}
# Connect to the database

View File

@@ -1,151 +0,0 @@
#!/usr/bin/env python3
"""
Database script to add the printed_labels column to the order_for_labels table
This column will track whether labels have been printed for each order (boolean: 0=false, 1=true)
Default value: 0 (false)
"""
import sys
import os
import mariadb
from flask import Flask
# Add the app directory to the path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
def get_db_connection():
"""Get database connection using settings from external_server.conf"""
# Go up two levels from this script to reach py_app directory, then to instance
app_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
settings_file = os.path.join(app_root, 'instance', 'external_server.conf')
settings = {}
with open(settings_file, 'r') as f:
for line in f:
key, value = line.strip().split('=', 1)
settings[key] = value
return mariadb.connect(
user=settings['username'],
password=settings['password'],
host=settings['server_domain'],
port=int(settings['port']),
database=settings['database_name']
)
def add_printed_labels_column():
"""
Adds the printed_labels column to the order_for_labels table after the line_number column
Column type: TINYINT(1) (boolean: 0=false, 1=true)
Default value: 0 (false)
"""
try:
conn = get_db_connection()
cursor = conn.cursor()
# Check if table exists
cursor.execute("SHOW TABLES LIKE 'order_for_labels'")
result = cursor.fetchone()
if not result:
print("❌ Table 'order_for_labels' does not exist. Please create it first.")
return False
# Check if column already exists
cursor.execute("SHOW COLUMNS FROM order_for_labels LIKE 'printed_labels'")
column_exists = cursor.fetchone()
if column_exists:
print(" Column 'printed_labels' already exists.")
# Show current structure
cursor.execute("DESCRIBE order_for_labels")
columns = cursor.fetchall()
print("\n📋 Current table structure:")
for col in columns:
null_info = 'NULL' if col[2] == 'YES' else 'NOT NULL'
default_info = f" DEFAULT {col[4]}" if col[4] else ""
print(f" 📌 {col[0]:<25} {col[1]:<20} {null_info}{default_info}")
else:
# Add the column after line_number
alter_table_sql = """
ALTER TABLE order_for_labels
ADD COLUMN printed_labels TINYINT(1) NOT NULL DEFAULT 0
COMMENT 'Boolean flag: 0=labels not printed, 1=labels printed'
AFTER line_number
"""
cursor.execute(alter_table_sql)
conn.commit()
print("✅ Column 'printed_labels' added successfully!")
# Show the updated structure
cursor.execute("DESCRIBE order_for_labels")
columns = cursor.fetchall()
print("\n📋 Updated table structure:")
for col in columns:
null_info = 'NULL' if col[2] == 'YES' else 'NOT NULL'
default_info = f" DEFAULT {col[4]}" if col[4] else ""
highlight = "🆕 " if col[0] == 'printed_labels' else " "
print(f"{highlight}{col[0]:<25} {col[1]:<20} {null_info}{default_info}")
# Show count of existing records that will have printed_labels = 0
cursor.execute("SELECT COUNT(*) FROM order_for_labels")
count = cursor.fetchone()[0]
if count > 0:
print(f"\n📊 {count} existing records now have printed_labels = 0 (false)")
conn.close()
except mariadb.Error as e:
print(f"❌ Database error: {e}")
return False
except Exception as e:
print(f"❌ Error: {e}")
return False
return True
def verify_column():
"""Verify the column was added correctly"""
try:
conn = get_db_connection()
cursor = conn.cursor()
# Test the column functionality
cursor.execute("SELECT COUNT(*) as total, SUM(printed_labels) as printed FROM order_for_labels")
result = cursor.fetchone()
if result:
total, printed = result
print(f"\n🔍 Verification:")
print(f" 📦 Total orders: {total}")
print(f" 🖨️ Printed orders: {printed or 0}")
print(f" 📄 Unprinted orders: {total - (printed or 0)}")
conn.close()
return True
except Exception as e:
print(f"❌ Verification failed: {e}")
return False
if __name__ == "__main__":
print("🔧 Adding printed_labels column to order_for_labels table...")
print("="*60)
success = add_printed_labels_column()
if success:
print("\n🔍 Verifying column addition...")
verify_column()
print("\n✅ Database modification completed successfully!")
print("\n📝 Column Details:")
print(" • Name: printed_labels")
print(" • Type: TINYINT(1) (boolean)")
print(" • Default: 0 (false - labels not printed)")
print(" • Values: 0 = not printed, 1 = printed")
print(" • Position: After line_number column")
else:
print("\n❌ Database modification failed!")
print("="*60)

View File

@@ -0,0 +1,637 @@
#!/usr/bin/env python3
"""
Complete Database Setup Script for Trasabilitate Application
This script creates all necessary database tables, triggers, and initial data
for quick deployment of the application.
Usage: python3 setup_complete_database.py
"""
import mariadb
import sqlite3
import os
import sys
from datetime import datetime
# Database configuration
DB_CONFIG = {
"user": "trasabilitate",
"password": "Initial01!",
"host": "localhost",
"database": "trasabilitate"
}
def print_step(step_num, description):
"""Print formatted step information"""
print(f"\n{'='*60}")
print(f"Step {step_num}: {description}")
print('='*60)
def print_success(message):
"""Print success message"""
print(f"{message}")
def print_error(message):
"""Print error message"""
print(f"{message}")
def test_database_connection():
"""Test if we can connect to the database"""
print_step(1, "Testing Database Connection")
try:
conn = mariadb.connect(**DB_CONFIG)
print_success("Successfully connected to MariaDB database 'trasabilitate'")
conn.close()
return True
except Exception as e:
print_error(f"Failed to connect to database: {e}")
print("\nPlease ensure:")
print("1. MariaDB is running")
print("2. Database 'trasabilitate' exists")
print("3. User 'trasabilitate' has been created with password 'Initial01!'")
print("4. User has all privileges on the database")
return False
def create_scan_tables():
"""Create scan1_orders and scanfg_orders tables"""
print_step(2, "Creating Scan Tables (scan1_orders & scanfg_orders)")
try:
conn = mariadb.connect(**DB_CONFIG)
cursor = conn.cursor()
# Create scan1_orders table
scan1_table_query = """
CREATE TABLE IF NOT EXISTS scan1_orders (
Id INT AUTO_INCREMENT PRIMARY KEY,
operator_code VARCHAR(4) NOT NULL,
CP_full_code VARCHAR(15) NOT NULL UNIQUE,
OC1_code VARCHAR(4) NOT NULL,
OC2_code VARCHAR(4) NOT NULL,
CP_base_code VARCHAR(10) GENERATED ALWAYS AS (LEFT(CP_full_code, 10)) STORED,
quality_code INT(3) NOT NULL,
date DATE NOT NULL,
time TIME NOT NULL,
approved_quantity INT DEFAULT 0,
rejected_quantity INT DEFAULT 0
);
"""
cursor.execute(scan1_table_query)
print_success("Table 'scan1_orders' created successfully")
# Create scanfg_orders table
scanfg_table_query = """
CREATE TABLE IF NOT EXISTS scanfg_orders (
Id INT AUTO_INCREMENT PRIMARY KEY,
operator_code VARCHAR(4) NOT NULL,
CP_full_code VARCHAR(15) NOT NULL UNIQUE,
OC1_code VARCHAR(4) NOT NULL,
OC2_code VARCHAR(4) NOT NULL,
CP_base_code VARCHAR(10) GENERATED ALWAYS AS (LEFT(CP_full_code, 10)) STORED,
quality_code INT(3) NOT NULL,
date DATE NOT NULL,
time TIME NOT NULL,
approved_quantity INT DEFAULT 0,
rejected_quantity INT DEFAULT 0
);
"""
cursor.execute(scanfg_table_query)
print_success("Table 'scanfg_orders' created successfully")
conn.commit()
cursor.close()
conn.close()
return True
except Exception as e:
print_error(f"Failed to create scan tables: {e}")
return False
def create_order_for_labels_table():
"""Create order_for_labels table"""
print_step(3, "Creating Order for Labels Table")
try:
conn = mariadb.connect(**DB_CONFIG)
cursor = conn.cursor()
order_labels_query = """
CREATE TABLE IF NOT EXISTS order_for_labels (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
comanda_productie VARCHAR(15) NOT NULL,
cod_articol VARCHAR(15) NULL,
descr_com_prod VARCHAR(50) NOT NULL,
cantitate INT(3) NOT NULL,
com_achiz_client VARCHAR(25) NULL,
nr_linie_com_client INT(3) NULL,
customer_name VARCHAR(50) NULL,
customer_article_number VARCHAR(25) NULL,
open_for_order VARCHAR(25) NULL,
line_number INT(3) NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
"""
cursor.execute(order_labels_query)
print_success("Table 'order_for_labels' created successfully")
conn.commit()
cursor.close()
conn.close()
return True
except Exception as e:
print_error(f"Failed to create order_for_labels table: {e}")
return False
def create_warehouse_locations_table():
"""Create warehouse_locations table"""
print_step(4, "Creating Warehouse Locations Table")
try:
conn = mariadb.connect(**DB_CONFIG)
cursor = conn.cursor()
warehouse_query = """
CREATE TABLE IF NOT EXISTS warehouse_locations (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
location_code VARCHAR(12) NOT NULL UNIQUE,
size INT,
description VARCHAR(250)
);
"""
cursor.execute(warehouse_query)
print_success("Table 'warehouse_locations' created successfully")
conn.commit()
cursor.close()
conn.close()
return True
except Exception as e:
print_error(f"Failed to create warehouse_locations table: {e}")
return False
def create_permissions_tables():
"""Create permission management tables"""
print_step(5, "Creating Permission Management Tables")
try:
conn = mariadb.connect(**DB_CONFIG)
cursor = conn.cursor()
# Create permissions table
permissions_query = """
CREATE TABLE IF NOT EXISTS permissions (
id INT AUTO_INCREMENT PRIMARY KEY,
permission_key VARCHAR(255) UNIQUE NOT NULL,
page VARCHAR(100) NOT NULL,
page_name VARCHAR(255) NOT NULL,
section VARCHAR(100) NOT NULL,
section_name VARCHAR(255) NOT NULL,
action VARCHAR(50) NOT NULL,
action_name VARCHAR(255) NOT NULL,
description TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
"""
cursor.execute(permissions_query)
print_success("Table 'permissions' created successfully")
# Create role_permissions table
role_permissions_query = """
CREATE TABLE IF NOT EXISTS role_permissions (
id INT AUTO_INCREMENT PRIMARY KEY,
role_name VARCHAR(100) NOT NULL,
permission_id INT NOT NULL,
granted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
granted_by VARCHAR(100),
FOREIGN KEY (permission_id) REFERENCES permissions(id) ON DELETE CASCADE,
UNIQUE KEY unique_role_permission (role_name, permission_id)
);
"""
cursor.execute(role_permissions_query)
print_success("Table 'role_permissions' created successfully")
# Create role_hierarchy table
role_hierarchy_query = """
CREATE TABLE IF NOT EXISTS role_hierarchy (
id INT AUTO_INCREMENT PRIMARY KEY,
role_name VARCHAR(100) UNIQUE NOT NULL,
role_display_name VARCHAR(255) NOT NULL,
level INT NOT NULL,
parent_role VARCHAR(100),
description TEXT,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
"""
cursor.execute(role_hierarchy_query)
print_success("Table 'role_hierarchy' created successfully")
# Create permission_audit_log table
audit_log_query = """
CREATE TABLE IF NOT EXISTS permission_audit_log (
id INT AUTO_INCREMENT PRIMARY KEY,
action VARCHAR(50) NOT NULL,
role_name VARCHAR(100),
permission_key VARCHAR(255),
user_id VARCHAR(100),
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
details TEXT,
ip_address VARCHAR(45)
);
"""
cursor.execute(audit_log_query)
print_success("Table 'permission_audit_log' created successfully")
conn.commit()
cursor.close()
conn.close()
return True
except Exception as e:
print_error(f"Failed to create permissions tables: {e}")
return False
def create_sqlite_tables():
"""Create SQLite tables for users and roles"""
print_step(6, "Creating SQLite User and Role Tables")
try:
# Create instance folder if it doesn't exist
instance_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../instance'))
if not os.path.exists(instance_folder):
os.makedirs(instance_folder)
db_path = os.path.join(instance_folder, 'users.db')
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
# Create users table
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
password TEXT NOT NULL,
role TEXT NOT NULL
)
''')
# Insert superadmin user if not exists
cursor.execute('''
INSERT OR IGNORE INTO users (username, password, role)
VALUES (?, ?, ?)
''', ('superadmin', 'superadmin123', 'superadmin'))
# Create roles table
cursor.execute('''
CREATE TABLE IF NOT EXISTS roles (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT UNIQUE NOT NULL,
access_level TEXT NOT NULL,
description TEXT
)
''')
# Insert superadmin role if not exists
cursor.execute('''
INSERT OR IGNORE INTO roles (name, access_level, description)
VALUES (?, ?, ?)
''', ('superadmin', 'full', 'Full access to all app areas and functions'))
conn.commit()
conn.close()
print_success("SQLite tables created and superadmin user initialized")
return True
except Exception as e:
print_error(f"Failed to create SQLite tables: {e}")
return False
def create_database_triggers():
"""Create database triggers for automatic quantity calculations"""
print_step(7, "Creating Database Triggers")
try:
conn = mariadb.connect(**DB_CONFIG)
cursor = conn.cursor()
# Drop existing triggers if they exist
trigger_drops = [
"DROP TRIGGER IF EXISTS increment_approved_quantity;",
"DROP TRIGGER IF EXISTS increment_rejected_quantity;",
"DROP TRIGGER IF EXISTS increment_approved_quantity_fg;",
"DROP TRIGGER IF EXISTS increment_rejected_quantity_fg;"
]
for drop_query in trigger_drops:
cursor.execute(drop_query)
# Create trigger for scan1_orders approved quantity
scan1_approved_trigger = """
CREATE TRIGGER increment_approved_quantity
AFTER INSERT ON scan1_orders
FOR EACH ROW
BEGIN
IF NEW.quality_code = 000 THEN
UPDATE scan1_orders
SET approved_quantity = approved_quantity + 1
WHERE CP_base_code = NEW.CP_base_code;
ELSE
UPDATE scan1_orders
SET rejected_quantity = rejected_quantity + 1
WHERE CP_base_code = NEW.CP_base_code;
END IF;
END;
"""
cursor.execute(scan1_approved_trigger)
print_success("Trigger 'increment_approved_quantity' created for scan1_orders")
# Create trigger for scanfg_orders approved quantity
scanfg_approved_trigger = """
CREATE TRIGGER increment_approved_quantity_fg
AFTER INSERT ON scanfg_orders
FOR EACH ROW
BEGIN
IF NEW.quality_code = 000 THEN
UPDATE scanfg_orders
SET approved_quantity = approved_quantity + 1
WHERE CP_base_code = NEW.CP_base_code;
ELSE
UPDATE scanfg_orders
SET rejected_quantity = rejected_quantity + 1
WHERE CP_base_code = NEW.CP_base_code;
END IF;
END;
"""
cursor.execute(scanfg_approved_trigger)
print_success("Trigger 'increment_approved_quantity_fg' created for scanfg_orders")
conn.commit()
cursor.close()
conn.close()
return True
except Exception as e:
print_error(f"Failed to create database triggers: {e}")
return False
def populate_permissions_data():
"""Populate permissions and roles with default data"""
print_step(8, "Populating Permissions and Roles Data")
try:
conn = mariadb.connect(**DB_CONFIG)
cursor = conn.cursor()
# Define all permissions
permissions_data = [
# Home page permissions
('home.view', 'home', 'Home Page', 'navigation', 'Navigation', 'view', 'View Home Page', 'Access to home page'),
# Scan1 permissions
('scan1.view', 'scan1', 'Scan1 Page', 'scanning', 'Scanning Operations', 'view', 'View Scan1', 'Access to scan1 page'),
('scan1.scan', 'scan1', 'Scan1 Page', 'scanning', 'Scanning Operations', 'scan', 'Perform Scan1', 'Ability to perform scan1 operations'),
('scan1.history', 'scan1', 'Scan1 Page', 'scanning', 'Scanning Operations', 'history', 'View Scan1 History', 'View scan1 operation history'),
# ScanFG permissions
('scanfg.view', 'scanfg', 'ScanFG Page', 'scanning', 'Scanning Operations', 'view', 'View ScanFG', 'Access to scanfg page'),
('scanfg.scan', 'scanfg', 'ScanFG Page', 'scanning', 'Scanning Operations', 'scan', 'Perform ScanFG', 'Ability to perform scanfg operations'),
('scanfg.history', 'scanfg', 'ScanFG Page', 'scanning', 'Scanning Operations', 'history', 'View ScanFG History', 'View scanfg operation history'),
# Warehouse permissions
('warehouse.view', 'warehouse', 'Warehouse Management', 'warehouse', 'Warehouse Operations', 'view', 'View Warehouse', 'Access to warehouse page'),
('warehouse.manage_locations', 'warehouse', 'Warehouse Management', 'warehouse', 'Warehouse Operations', 'manage', 'Manage Locations', 'Add, edit, delete warehouse locations'),
('warehouse.view_locations', 'warehouse', 'Warehouse Management', 'warehouse', 'Warehouse Operations', 'view_locations', 'View Locations', 'View warehouse locations'),
# Labels permissions
('labels.view', 'labels', 'Label Management', 'labels', 'Label Operations', 'view', 'View Labels', 'Access to labels page'),
('labels.print', 'labels', 'Label Management', 'labels', 'Label Operations', 'print', 'Print Labels', 'Print labels'),
('labels.manage_orders', 'labels', 'Label Management', 'labels', 'Label Operations', 'manage', 'Manage Label Orders', 'Manage label orders'),
# Print Module permissions
('print.view', 'print', 'Print Module', 'printing', 'Printing Operations', 'view', 'View Print Module', 'Access to print module'),
('print.execute', 'print', 'Print Module', 'printing', 'Printing Operations', 'execute', 'Execute Print', 'Execute print operations'),
('print.manage_queue', 'print', 'Print Module', 'printing', 'Printing Operations', 'manage_queue', 'Manage Print Queue', 'Manage print queue'),
# Settings permissions
('settings.view', 'settings', 'Settings', 'system', 'System Management', 'view', 'View Settings', 'Access to settings page'),
('settings.edit', 'settings', 'Settings', 'system', 'System Management', 'edit', 'Edit Settings', 'Modify application settings'),
('settings.database', 'settings', 'Settings', 'system', 'System Management', 'database', 'Database Settings', 'Manage database settings'),
# User Management permissions
('users.view', 'users', 'User Management', 'admin', 'Administration', 'view', 'View Users', 'View user list'),
('users.create', 'users', 'User Management', 'admin', 'Administration', 'create', 'Create Users', 'Create new users'),
('users.edit', 'users', 'User Management', 'admin', 'Administration', 'edit', 'Edit Users', 'Edit existing users'),
('users.delete', 'users', 'User Management', 'admin', 'Administration', 'delete', 'Delete Users', 'Delete users'),
# Permission Management permissions
('permissions.view', 'permissions', 'Permission Management', 'admin', 'Administration', 'view', 'View Permissions', 'View permissions'),
('permissions.assign', 'permissions', 'Permission Management', 'admin', 'Administration', 'assign', 'Assign Permissions', 'Assign permissions to roles'),
('permissions.audit', 'permissions', 'Permission Management', 'admin', 'Administration', 'audit', 'View Audit Log', 'View permission audit log'),
]
# Insert permissions
permission_insert_query = """
INSERT IGNORE INTO permissions
(permission_key, page, page_name, section, section_name, action, action_name, description)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
"""
cursor.executemany(permission_insert_query, permissions_data)
print_success(f"Inserted {len(permissions_data)} permissions")
# Define role hierarchy
roles_data = [
('superadmin', 'Super Administrator', 1, None, 'Full system access with all permissions'),
('admin', 'Administrator', 2, 'superadmin', 'Administrative access with most permissions'),
('manager', 'Manager', 3, 'admin', 'Management level access'),
('quality_manager', 'Quality Manager', 4, 'manager', 'Quality control and scanning operations'),
('warehouse_manager', 'Warehouse Manager', 4, 'manager', 'Warehouse operations and management'),
('quality_worker', 'Quality Worker', 5, 'quality_manager', 'Basic quality scanning operations'),
('warehouse_worker', 'Warehouse Worker', 5, 'warehouse_manager', 'Basic warehouse operations'),
]
# Insert roles
role_insert_query = """
INSERT IGNORE INTO role_hierarchy
(role_name, role_display_name, level, parent_role, description)
VALUES (%s, %s, %s, %s, %s)
"""
cursor.executemany(role_insert_query, roles_data)
print_success(f"Inserted {len(roles_data)} roles")
# Assign permissions to roles
# Get all permission IDs
cursor.execute("SELECT id, permission_key FROM permissions")
permissions = {key: id for id, key in cursor.fetchall()}
# Define role-permission mappings
role_permissions = {
'superadmin': list(permissions.values()), # All permissions
'admin': [pid for key, pid in permissions.items() if not key.startswith('permissions.audit')], # All except audit
'manager': [permissions[key] for key in permissions.keys() if any(key.startswith(prefix) for prefix in ['home.', 'settings.view', 'users.view'])],
'quality_manager': [permissions[key] for key in permissions.keys() if any(key.startswith(prefix) for prefix in ['home.', 'scan1.', 'scanfg.', 'labels.', 'print.'])],
'warehouse_manager': [permissions[key] for key in permissions.keys() if any(key.startswith(prefix) for prefix in ['home.', 'warehouse.', 'labels.'])],
'quality_worker': [permissions[key] for key in permissions.keys() if any(key.startswith(prefix) for prefix in ['home.', 'scan1.view', 'scan1.scan', 'scanfg.view', 'scanfg.scan'])],
'warehouse_worker': [permissions[key] for key in permissions.keys() if any(key.startswith(prefix) for prefix in ['home.', 'warehouse.view', 'warehouse.view_locations'])],
}
# Insert role permissions
for role, permission_ids in role_permissions.items():
for permission_id in permission_ids:
cursor.execute("""
INSERT IGNORE INTO role_permissions (role_name, permission_id)
VALUES (%s, %s)
""", (role, permission_id))
print_success("Role permissions assigned successfully")
conn.commit()
cursor.close()
conn.close()
return True
except Exception as e:
print_error(f"Failed to populate permissions data: {e}")
return False
def update_external_config():
"""Update external_server.conf with correct database settings"""
print_step(9, "Updating External Server Configuration")
try:
config_path = os.path.join(os.path.dirname(__file__), '../../instance/external_server.conf')
config_content = """server_domain=localhost
port=3306
database_name=trasabilitate
username=trasabilitate
password=Initial01!
"""
# Create instance directory if it doesn't exist
os.makedirs(os.path.dirname(config_path), exist_ok=True)
with open(config_path, 'w') as f:
f.write(config_content)
print_success("External server configuration updated")
return True
except Exception as e:
print_error(f"Failed to update external config: {e}")
return False
def verify_database_setup():
"""Verify that all tables were created successfully"""
print_step(10, "Verifying Database Setup")
try:
conn = mariadb.connect(**DB_CONFIG)
cursor = conn.cursor()
# Check MariaDB tables
cursor.execute("SHOW TABLES")
tables = [table[0] for table in cursor.fetchall()]
expected_tables = [
'scan1_orders',
'scanfg_orders',
'order_for_labels',
'warehouse_locations',
'permissions',
'role_permissions',
'role_hierarchy',
'permission_audit_log'
]
print("\n📊 MariaDB Tables Status:")
for table in expected_tables:
if table in tables:
print_success(f"Table '{table}' exists")
else:
print_error(f"Table '{table}' missing")
# Check triggers
cursor.execute("SHOW TRIGGERS")
triggers = [trigger[0] for trigger in cursor.fetchall()]
expected_triggers = [
'increment_approved_quantity',
'increment_approved_quantity_fg'
]
print("\n🔧 Database Triggers Status:")
for trigger in expected_triggers:
if trigger in triggers:
print_success(f"Trigger '{trigger}' exists")
else:
print_error(f"Trigger '{trigger}' missing")
cursor.close()
conn.close()
# Check SQLite database
instance_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../instance'))
sqlite_path = os.path.join(instance_folder, 'users.db')
if os.path.exists(sqlite_path):
print_success("SQLite database 'users.db' exists")
else:
print_error("SQLite database 'users.db' missing")
return True
except Exception as e:
print_error(f"Failed to verify database setup: {e}")
return False
def main():
"""Main function to orchestrate the complete database setup"""
print("🚀 Trasabilitate Application - Complete Database Setup")
print(f"Started at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
steps = [
test_database_connection,
create_scan_tables,
create_order_for_labels_table,
create_warehouse_locations_table,
create_permissions_tables,
create_sqlite_tables,
create_database_triggers,
populate_permissions_data,
update_external_config,
verify_database_setup
]
success_count = 0
for step in steps:
if step():
success_count += 1
else:
print(f"\n❌ Setup failed at step: {step.__name__}")
print("Please check the error messages above and resolve the issues.")
sys.exit(1)
print(f"\n{'='*60}")
print("🎉 DATABASE SETUP COMPLETED SUCCESSFULLY!")
print(f"{'='*60}")
print(f"✅ All {success_count} steps completed successfully")
print(f"📅 Completed at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print("\n📋 Setup Summary:")
print(" • MariaDB tables created with triggers")
print(" • SQLite user database initialized")
print(" • Permissions system fully configured")
print(" • Default superadmin user created (username: superadmin, password: superadmin123)")
print(" • Configuration files updated")
print("\n🚀 Your application is ready to run!")
print(" Run: python3 run.py")
if __name__ == "__main__":
main()