feat: Major system improvements and production deployment

 New Features:
- Added view_orders route with proper table display
- Implemented CSV upload with preview workflow and date parsing
- Added production WSGI server configuration with Gunicorn
- Created comprehensive production management scripts

🔧 Bug Fixes:
- Fixed upload_data route column mapping for actual CSV structure
- Resolved print module database queries and template rendering
- Fixed view orders navigation routing (was pointing to JSON API)
- Corrected barcode display width constraints in print module
- Added proper date format parsing for MySQL compatibility

🎨 UI/UX Improvements:
- Updated view_orders template with theme-compliant styling
- Hidden barcode text in print module preview for cleaner display
- Enhanced CSV upload with two-step preview-then-save workflow
- Improved error handling and debugging throughout upload process

🚀 Production Infrastructure:
- Added Gunicorn WSGI server with proper configuration
- Created systemd service for production deployment
- Implemented production management scripts (start/stop/status)
- Added comprehensive logging setup
- Updated requirements.txt with production dependencies

📊 Database & Data:
- Enhanced order_for_labels table compatibility
- Fixed column mappings for real CSV data structure
- Added proper date parsing and validation
- Improved error handling with detailed debugging

🔧 Technical Debt:
- Reorganized database setup documentation
- Added proper error handling throughout upload workflow
- Enhanced debugging capabilities for troubleshooting
- Improved code organization and documentation
This commit is contained in:
Quality System Admin
2025-10-11 23:31:32 +03:00
parent af62fa478f
commit d264bcdca9
20 changed files with 1295 additions and 193 deletions

72
py_app/gunicorn.conf.py Normal file
View File

@@ -0,0 +1,72 @@
# Gunicorn Configuration File for Trasabilitate Application
# Production-ready WSGI server configuration
import multiprocessing
import os
# Server socket
bind = "0.0.0.0:8781"
backlog = 2048
# Worker processes
workers = multiprocessing.cpu_count() * 2 + 1
worker_class = "sync"
worker_connections = 1000
timeout = 30
keepalive = 2
# Restart workers after this many requests, to prevent memory leaks
max_requests = 1000
max_requests_jitter = 50
# Logging
accesslog = "/srv/quality_recticel/logs/access.log"
errorlog = "/srv/quality_recticel/logs/error.log"
loglevel = "info"
access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" %(D)s'
# Process naming
proc_name = 'trasabilitate_app'
# Daemon mode (set to True for production deployment)
daemon = False
# User/group to run worker processes
# user = "www-data"
# group = "www-data"
# Preload application for better performance
preload_app = True
# Enable automatic worker restarts
max_requests = 1000
max_requests_jitter = 100
# SSL Configuration (uncomment if using HTTPS)
# keyfile = "/path/to/ssl/private.key"
# certfile = "/path/to/ssl/certificate.crt"
# Security
limit_request_line = 4094
limit_request_fields = 100
limit_request_field_size = 8190
def when_ready(server):
"""Called just after the server is started."""
server.log.info("Trasabilitate Application server is ready. Listening on: %s", server.address)
def worker_int(worker):
"""Called just after a worker exited on SIGINT or SIGQUIT."""
worker.log.info("Worker received INT or QUIT signal")
def pre_fork(server, worker):
"""Called just before a worker is forked."""
server.log.info("Worker spawned (pid: %s)", worker.pid)
def post_fork(server, worker):
"""Called just after a worker has been forked."""
server.log.info("Worker spawned (pid: %s)", worker.pid)
def worker_abort(worker):
"""Called when a worker received the SIGABRT signal."""
worker.log.info("Worker received SIGABRT signal")