V1.0.0.5 - Refactor app.py: Split User, Session, and Admin logic into blueprints

This commit is contained in:
Javier
2026-01-23 09:14:20 -06:00
parent 2f705b1e22
commit 6789f0899a
4 changed files with 93 additions and 86 deletions

90
app.py
View File

@@ -16,11 +16,14 @@ from db import query_db, execute_db, get_db
from blueprints.data_imports import data_imports_bp from blueprints.data_imports import data_imports_bp
from blueprints.users import users_bp from blueprints.users import users_bp
from blueprints.sessions import sessions_bp from blueprints.sessions import sessions_bp
from utils import login_required, role_required from blueprints.admin_locations import admin_locations_bp
from utils import login_required
# Register Blueprints
app.register_blueprint(data_imports_bp) app.register_blueprint(data_imports_bp)
app.register_blueprint(users_bp) app.register_blueprint(users_bp)
app.register_blueprint(sessions_bp) app.register_blueprint(sessions_bp)
app.register_blueprint(admin_locations_bp)
# V1.0: Use environment variable for production, fallback to demo key for development # V1.0: Use environment variable for production, fallback to demo key for development
app.secret_key = os.environ.get('SCANLOOK_SECRET_KEY', 'scanlook-demo-key-replace-for-production') app.secret_key = os.environ.get('SCANLOOK_SECRET_KEY', 'scanlook-demo-key-replace-for-production')
@@ -241,91 +244,6 @@ def complete_location(location_count_id):
return jsonify({'success': True, 'message': 'Bin marked as complete'}) return jsonify({'success': True, 'message': 'Bin marked as complete'})
@app.route('/location/<int:location_count_id>/reopen', methods=['POST'])
@login_required
def reopen_location(location_count_id):
"""Reopen a completed location (admin/owner only)"""
# Check permissions
user = query_db('SELECT role FROM Users WHERE user_id = ?', [session['user_id']], one=True)
if not user or user['role'] not in ['owner', 'admin']:
return jsonify({'success': False, 'message': 'Permission denied'}), 403
# Verify location exists
loc = query_db('SELECT * FROM LocationCounts WHERE location_count_id = ?', [location_count_id], one=True)
if not loc:
return jsonify({'success': False, 'message': 'Location not found'})
# Reopen the location
execute_db('''
UPDATE LocationCounts
SET status = 'in_progress', end_timestamp = NULL
WHERE location_count_id = ?
''', [location_count_id])
return jsonify({'success': True, 'message': 'Bin reopened for counting'})
@app.route('/location/<int:location_count_id>/delete', methods=['POST'])
@login_required
def delete_location_count(location_count_id):
"""Delete all counts for a location (soft delete)"""
# Verify ownership
loc = query_db('SELECT * FROM LocationCounts WHERE location_count_id = ?', [location_count_id], one=True)
if not loc:
return jsonify({'success': False, 'message': 'Location not found'})
if loc['counted_by'] != session['user_id'] and session['role'] not in ['owner', 'admin']:
return jsonify({'success': False, 'message': 'Permission denied'})
# Soft delete all scan entries for this location
execute_db('''
UPDATE ScanEntries
SET is_deleted = 1
WHERE location_count_id = ?
''', [location_count_id])
# Delete the location count record
execute_db('''
DELETE FROM LocationCounts
WHERE location_count_id = ?
''', [location_count_id])
return jsonify({'success': True, 'message': 'Bin count deleted'})
@app.route('/location/<int:location_count_id>/scans')
@login_required
def get_location_scans(location_count_id):
"""Get all scans for a specific location (admin/owner only)"""
# Check permissions
user = query_db('SELECT role FROM Users WHERE user_id = ?', [session['user_id']], one=True)
if not user or user['role'] not in ['owner', 'admin']:
return jsonify({'success': False, 'message': 'Permission denied'}), 403
try:
scans = query_db('''
SELECT
se.*,
bic.system_bin as current_system_location,
bic.system_quantity as current_system_weight
FROM ScanEntries se
LEFT JOIN BaselineInventory_Current bic ON se.lot_number = bic.lot_number
WHERE se.location_count_id = ?
AND se.is_deleted = 0
ORDER BY se.scan_timestamp DESC
''', [location_count_id])
# Convert Row objects to dicts
scans_list = [dict(scan) for scan in scans] if scans else []
return jsonify({'success': True, 'scans': scans_list})
except Exception as e:
return jsonify({'success': False, 'message': str(e)})
@app.route('/count/<int:session_id>/location/<int:location_count_id>') @app.route('/count/<int:session_id>/location/<int:location_count_id>')
@login_required @login_required
def count_location(session_id, location_count_id): def count_location(session_id, location_count_id):

Binary file not shown.

View File

@@ -0,0 +1,89 @@
from flask import Blueprint, jsonify, session
from db import query_db, execute_db
from utils import login_required
admin_locations_bp = Blueprint('admin_locations', __name__)
@admin_locations_bp.route('/location/<int:location_count_id>/reopen', methods=['POST'])
@login_required
def reopen_location(location_count_id):
"""Reopen a completed location (admin/owner only)"""
# Check permissions
user = query_db('SELECT role FROM Users WHERE user_id = ?', [session['user_id']], one=True)
if not user or user['role'] not in ['owner', 'admin']:
return jsonify({'success': False, 'message': 'Permission denied'}), 403
# Verify location exists
loc = query_db('SELECT * FROM LocationCounts WHERE location_count_id = ?', [location_count_id], one=True)
if not loc:
return jsonify({'success': False, 'message': 'Location not found'})
# Reopen the location
execute_db('''
UPDATE LocationCounts
SET status = 'in_progress', end_timestamp = NULL
WHERE location_count_id = ?
''', [location_count_id])
return jsonify({'success': True, 'message': 'Bin reopened for counting'})
@admin_locations_bp.route('/location/<int:location_count_id>/delete', methods=['POST'])
@login_required
def delete_location_count(location_count_id):
"""Delete all counts for a location (soft delete)"""
# Verify ownership
loc = query_db('SELECT * FROM LocationCounts WHERE location_count_id = ?', [location_count_id], one=True)
if not loc:
return jsonify({'success': False, 'message': 'Location not found'})
if loc['counted_by'] != session['user_id'] and session['role'] not in ['owner', 'admin']:
return jsonify({'success': False, 'message': 'Permission denied'})
# Soft delete all scan entries for this location
execute_db('''
UPDATE ScanEntries
SET is_deleted = 1
WHERE location_count_id = ?
''', [location_count_id])
# Delete the location count record
execute_db('''
DELETE FROM LocationCounts
WHERE location_count_id = ?
''', [location_count_id])
return jsonify({'success': True, 'message': 'Bin count deleted'})
@admin_locations_bp.route('/location/<int:location_count_id>/scans')
@login_required
def get_location_scans(location_count_id):
"""Get all scans for a specific location (admin/owner only)"""
# Check permissions
user = query_db('SELECT role FROM Users WHERE user_id = ?', [session['user_id']], one=True)
if not user or user['role'] not in ['owner', 'admin']:
return jsonify({'success': False, 'message': 'Permission denied'}), 403
try:
scans = query_db('''
SELECT
se.*,
bic.system_bin as current_system_location,
bic.system_quantity as current_system_weight
FROM ScanEntries se
LEFT JOIN BaselineInventory_Current bic ON se.lot_number = bic.lot_number
WHERE se.location_count_id = ?
AND se.is_deleted = 0
ORDER BY se.scan_timestamp DESC
''', [location_count_id])
# Convert Row objects to dicts
scans_list = [dict(scan) for scan in scans] if scans else []
return jsonify({'success': True, 'scans': scans_list})
except Exception as e:
return jsonify({'success': False, 'message': str(e)})

Binary file not shown.