Sep 16 - Optimize code, part 1

This commit is contained in:
2026-09-16 10:52:59 -04:00
parent 4212726611
commit 7626287344
22 changed files with 587 additions and 96 deletions
+19 -6
View File
@@ -20,6 +20,8 @@ from werkzeug.utils import secure_filename
from logger_handler import log_user_activity, log_database_operations
from sqlalchemy import or_
from utils.helpers import (
QR_MANAGEMENT_ROLES,
roles_required,
admin_required,
employee_id_regex_condition,
expand_employee_id_filter,
@@ -106,6 +108,7 @@ def get_unique_qr_locations():
@bp.route('/qr-codes/create', methods=['GET', 'POST'], endpoint='create_qr_code')
@roles_required(*QR_MANAGEMENT_ROLES) # not project managers (reports only)
@login_required
@log_database_operations('qr_code_creation')
def create_qr_code():
@@ -286,6 +289,7 @@ def create_qr_code():
return render_template('create_qr_code.html', projects=projects, styles=styles)
@bp.route('/qr-codes/bulk-import', methods=['GET', 'POST'], endpoint='import_bulk_qr_codes')
@roles_required(*QR_MANAGEMENT_ROLES)
@login_required
@log_database_operations('qr_code_bulk_import')
def import_bulk_qr_codes():
@@ -400,6 +404,7 @@ def import_bulk_qr_codes():
@bp.route('/qr-codes/bulk-import/template', endpoint='download_qr_import_template')
@roles_required(*QR_MANAGEMENT_ROLES)
@login_required
def download_qr_import_template():
"""Download Excel template for bulk QR code import"""
@@ -465,6 +470,7 @@ def download_qr_import_template():
return redirect(url_for('qr_codes.import_bulk_qr_codes'))
@bp.route('/qr-codes/<int:qr_id>/edit', methods=['GET', 'POST'], endpoint='edit_qr_code')
@roles_required(*QR_MANAGEMENT_ROLES)
@login_required
@log_database_operations('qr_code_edit')
def edit_qr_code(qr_id):
@@ -744,19 +750,23 @@ def qr_checkin(qr_url):
# Get and validate employee ID
employee_id = request.form.get('employee_id', '').strip()
# At most 4 digits — counted on the base ID, so an old-style typed
# suffix ("1234SP") from a page cached before the numeric-only rule
# still passes. Refused, never truncated: a shorter ID is another person.
# 1 to 4 digits, numbers only — checked on the base ID, so an old-style
# typed suffix ("1234SP") from a page cached before the numeric-only rule
# still passes. Anything else is refused, never truncated (a shorter ID
# is another person). This also keeps text such as "=HYPERLINK(...)" out
# of attendance_data and every Excel export built from it.
if employee_id:
base_for_length, _ = parse_employee_id_for_work_type(employee_id)
if len(re.sub(r'\D', '', base_for_length)) > CHECKIN_EMPLOYEE_ID_MAX_DIGITS:
if (not re.fullmatch(r'[0-9]+', base_for_length)
or len(base_for_length) > CHECKIN_EMPLOYEE_ID_MAX_DIGITS):
logger_handler.logger.warning(
f"Check-in rejected: employee ID '{employee_id}' has more than "
f"Check-in rejected: employee ID {employee_id!r} is not 1-"
f"{CHECKIN_EMPLOYEE_ID_MAX_DIGITS} digits (QR {qr_url})"
)
return jsonify({
'success': False,
'message': 'Employee ID must be 4 digits or fewer. / El ID de empleado debe tener 4 dígitos o menos.'
'message': ('Employee ID must be 1 to 4 digits, numbers only. / '
'El ID de empleado debe tener de 1 a 4 dígitos, solo números.')
}), 400
# --- ADDED: type of work selected on the check-in page ---
@@ -1325,6 +1335,7 @@ def qr_last_work_type(qr_url):
@bp.route('/qr-codes/<int:qr_id>/toggle-status', methods=['POST'], endpoint='toggle_qr_status')
@roles_required('admin') # the dashboard shows Activate/Deactivate to admins only
@login_required
def toggle_qr_status(qr_id):
"""Toggle QR code active/inactive status"""
@@ -1406,6 +1417,7 @@ def open_qr_link(qr_id):
}), 500
@bp.route('/qr-codes/<int:qr_id>/activate', methods=['POST'], endpoint='activate_qr_code')
@roles_required('admin')
@login_required
def activate_qr_code(qr_id):
"""Activate a QR code"""
@@ -1433,6 +1445,7 @@ def activate_qr_code(qr_id):
}), 500
@bp.route('/qr-codes/<int:qr_id>/deactivate', methods=['POST'], endpoint='deactivate_qr_code')
@roles_required('admin')
@login_required
def deactivate_qr_code(qr_id):
"""Deactivate a QR code"""