More annotation added to the program

This commit is contained in:
2026-05-30 12:44:44 +08:00
parent b3f29398f0
commit bf223b52ac
22 changed files with 729 additions and 353 deletions
+20 -3
View File
@@ -10,21 +10,24 @@ import os
from werkzeug.security import generate_password_hash
from datetime import datetime
# Save the database in the backend folder
# Store application data in the shared database folder so all backend modules
# use the same SQLite file regardless of their import path.
DB_FILE = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "database", "mxpic_data.db"))
def connect_db():
"""Open a SQLite connection with row-style access for application data queries."""
conn = sqlite3.connect(DB_FILE, timeout=20)
conn.execute("PRAGMA journal_mode=WAL")
conn.execute("PRAGMA busy_timeout=20000")
return conn
def init_db():
"""Create the user, profile, and audit-log tables required by the backend."""
os.makedirs(os.path.dirname(DB_FILE), exist_ok=True)
conn = connect_db()
cursor = conn.cursor()
# Create Users Table
# Core account table used by login, profile, and role-based PDK access.
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -33,6 +36,8 @@ def init_db():
)
''')
# Audit log table used by dashboard activity history and backend action
# tracing.
cursor.execute('''
CREATE TABLE IF NOT EXISTS user_logs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -48,6 +53,8 @@ def init_db():
)
''')
# Lightweight migrations keep older local SQLite files compatible after
# profile, credit, occupation, and role fields were added.
cursor.execute("PRAGMA table_info(users)")
existing_columns = {row[1] for row in cursor.fetchall()}
migrations = {
@@ -66,7 +73,8 @@ def init_db():
cursor.execute("UPDATE users SET user_group = 'developers' WHERE username = 'engineer'")
cursor.execute("UPDATE users SET user_group = 'user' WHERE user_group IS NULL OR user_group = ''")
# Insert default users for local multi-account development.
# Default local accounts let developers test manager/developer/user access
# without manually editing the database.
cursor.execute("SELECT * FROM users WHERE username = 'admin'")
if not cursor.fetchone():
test_hash = generate_password_hash("123456")
@@ -89,6 +97,7 @@ def init_db():
conn.close()
def get_user(username):
"""Fetch login credentials and account status for a username."""
conn = connect_db()
cursor = conn.cursor()
cursor.execute("SELECT id, username, password_hash, user_group FROM users WHERE username = ?", (username,))
@@ -97,6 +106,7 @@ def get_user(username):
return user
def get_user_profile(user_id):
"""Fetch editable profile details for an authenticated user."""
conn = connect_db()
cursor = conn.cursor()
cursor.execute(
@@ -108,6 +118,7 @@ def get_user_profile(user_id):
return user
def get_user_auth_by_id(user_id):
"""Fetch password and account metadata by user id."""
conn = connect_db()
cursor = conn.cursor()
cursor.execute("SELECT id, username, password_hash FROM users WHERE id = ?", (user_id,))
@@ -116,6 +127,7 @@ def get_user_auth_by_id(user_id):
return user
def update_user_occupation(user_id, occupation):
"""Persist a user profile occupation update."""
conn = connect_db()
cursor = conn.cursor()
cursor.execute("UPDATE users SET occupation = ? WHERE id = ?", (occupation, user_id))
@@ -123,6 +135,7 @@ def update_user_occupation(user_id, occupation):
conn.close()
def update_user_password(user_id, password):
"""Persist a newly hashed password for a user."""
conn = connect_db()
cursor = conn.cursor()
cursor.execute("UPDATE users SET password_hash = ? WHERE id = ?", (generate_password_hash(password), user_id))
@@ -130,6 +143,7 @@ def update_user_password(user_id, password):
conn.close()
def add_user_log(user_id, username, action, project=None, cell=None, detail=None, ip_address=None):
"""Record an auditable user action with optional project and cell context."""
conn = connect_db()
cursor = conn.cursor()
cursor.execute(
@@ -152,6 +166,7 @@ def add_user_log(user_id, username, action, project=None, cell=None, detail=None
conn.close()
def list_user_logs(user_id, limit=200):
"""Return recent audit-log entries for display in the account page."""
conn = connect_db()
cursor = conn.cursor()
cursor.execute(
@@ -169,5 +184,7 @@ def list_user_logs(user_id, limit=200):
return rows
if __name__ == "__main__":
# Allow this module to be run directly when a fresh local database needs to
# be initialized outside the Flask server.
init_db()
print("Database initialized successfully.")