feat: Implement warehouse module roles with auto-schema repair and remove module access section

- Add SchemaVerifier class for automatic database schema verification and repair
- Implement warehouse_manager (Level 75) and warehouse_worker (Level 35) roles
- Add zone-based access control for warehouse workers
- Implement worker-manager binding system with zone filtering
- Add comprehensive database auto-repair on Docker initialization
- Remove Module Access section from user form (role-based access only)
- Add autocomplete attributes to password fields for better UX
- Include detailed documentation for warehouse implementation
- Update initialize_db.py with schema verification as Step 0
This commit is contained in:
Quality App Developer
2026-01-28 00:46:59 +02:00
parent e6ff40184a
commit 8de85ca87f
18 changed files with 4194 additions and 167 deletions

View File

@@ -2,6 +2,7 @@
"""
Comprehensive Database Initialization Script
Creates all required tables and initializes default data
Includes schema verification to check existing databases for correctness
This script should be run once when the application starts
"""
@@ -11,6 +12,7 @@ import sys
import logging
import hashlib
from pathlib import Path
from app.db_schema_verifier import SchemaVerifier
# Setup logging
logging.basicConfig(
@@ -58,6 +60,66 @@ def execute_sql(conn, sql, params=None, description=""):
return False
def check_and_repair_database():
"""
Check existing database for correct structure
Repair any missing tables, columns, or reference data
"""
logger.info("Step 0: Checking existing database structure...")
try:
# First check if database exists
conn = pymysql.connect(
host=DB_HOST,
port=DB_PORT,
user=DB_USER,
password=DB_PASSWORD
)
cursor = conn.cursor()
cursor.execute(f"SHOW DATABASES LIKE %s", (DB_NAME,))
if not cursor.fetchone():
# Database doesn't exist, skip verification
logger.info(" Database doesn't exist yet, skipping structure check")
conn.close()
return True
cursor.close()
conn.close()
# Database exists, now connect to it and verify/repair structure
conn = pymysql.connect(
host=DB_HOST,
port=DB_PORT,
user=DB_USER,
password=DB_PASSWORD,
database=DB_NAME
)
# Run schema verification and repair
verifier = SchemaVerifier(conn)
success, summary = verifier.verify_and_repair()
# Log the summary
for line in summary.split('\n'):
if line.strip():
logger.info(f" {line}")
conn.close()
return success
except pymysql.Error as e:
if "Unknown database" in str(e):
logger.info(" Database doesn't exist yet, skipping structure check")
return True
logger.error(f"✗ Database check failed: {e}")
return False
except Exception as e:
logger.error(f"✗ Database check error: {e}")
return False
def create_database():
"""Create the database if it doesn't exist"""
logger.info("Step 1: Creating database...")
@@ -229,6 +291,23 @@ def create_tables():
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
""", description="Table 'user_permissions'")
# Worker-Manager bindings (for warehouse module hierarchy)
execute_sql(conn, """
CREATE TABLE IF NOT EXISTS worker_manager_bindings (
id INT AUTO_INCREMENT PRIMARY KEY,
manager_id INT NOT NULL,
worker_id INT NOT NULL,
warehouse_zone VARCHAR(100),
is_active TINYINT(1) DEFAULT 1,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY unique_binding (manager_id, worker_id),
FOREIGN KEY (manager_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (worker_id) REFERENCES users(id) ON DELETE CASCADE,
CHECK (manager_id != worker_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
""", description="Table 'worker_manager_bindings'")
conn.commit()
conn.close()
logger.info("✓ All tables created successfully")
@@ -257,8 +336,10 @@ def insert_default_data():
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),
('manager', 'Manager - Quality - Full access to assigned modules', 70),
('warehouse_manager', 'Manager - Warehouse - Full warehouse module access', 75),
('worker', 'Worker - Quality - Limited access', 50),
('warehouse_worker', 'Worker - Warehouse - Input-only warehouse access', 35),
]
logger.info(" Creating roles...")
@@ -407,6 +488,7 @@ def main():
logger.info(f"Target: {DB_USER}@{DB_HOST}:{DB_PORT}/{DB_NAME}\n")
steps = [
("Check/repair existing database", check_and_repair_database),
("Create database", create_database),
("Create tables", create_tables),
("Insert default data", insert_default_data),