11 KiB
11 KiB
Quality App v2 - Architecture & Development Guide
Architecture Overview
Quality App v2 is built on a modular, scalable Flask architecture with the following design principles:
Layered Architecture
┌─────────────────────────────────────┐
│ User Interface (Templates) │ Jinja2 Templates, HTML/CSS/JS
├─────────────────────────────────────┤
│ Flask Routes & Views │ Route handlers, request processing
├─────────────────────────────────────┤
│ Business Logic & Services │ Authentication, authorization
├─────────────────────────────────────┤
│ Database Layer (Models) │ Direct SQL queries with pooling
├─────────────────────────────────────┤
│ External Services (MariaDB) │ Persistent data storage
└─────────────────────────────────────┘
Application Initialization Flow
-
App Factory (
app/__init__.py)- Creates Flask application instance
- Loads configuration
- Initializes logging
- Registers blueprints
- Sets up error handlers
- Configures request/response handlers
-
Configuration Loading (
app/config.py)- Loads environment variables
- Sets Flask configuration
- Manages different environments (dev, test, prod)
-
Database Initialization (
app/database.py)- Creates connection pool
- Manages connections
- Executes queries safely
-
Route Registration
- Main routes (login, dashboard, logout)
- Module routes (quality, settings)
- Error handlers
Authentication Flow
User Input
↓
Login Form POST
↓
authenticate_user() in auth.py
↓
Query User from Database
↓
Verify Password Hash
↓
Store in Session
↓
Redirect to Dashboard
Password Security
- Passwords hashed using SHA256
- Salt-based hashing recommended for production
- Never stored in plain text
- Separate credentials table for additional security
Database Connection Management
Connection Pooling
- Uses
DBUtils.PooledDBfor connection pooling - Prevents connection exhaustion
- Automatic connection recycling
- Thread-safe operations
# Connection flow:
get_db() → Check if connection exists in g
→ Get from pool if not
→ Return connection
close_db() → Called on request teardown
→ Returns connection to pool
Module Architecture
Module Structure
Each module follows this pattern:
app/modules/[module_name]/
├── __init__.py # Package initialization
└── routes.py # Module routes and views
Adding a New Module
-
Create module directory:
mkdir app/modules/new_module -
Create
__init__.py:# Module initialization -
Create
routes.py:from flask import Blueprint new_module_bp = Blueprint('new_module', __name__, url_prefix='/new-module') @new_module_bp.route('/', methods=['GET']) def index(): return render_template('modules/new_module/index.html') -
Register in
app/__init__.py:from app.modules.new_module.routes import new_module_bp app.register_blueprint(new_module_bp) -
Create templates in
app/templates/modules/new_module/
Request/Response Lifecycle
Request Received
↓
check_license_middleware() [if applicable]
↓
check_authentication() [before_request]
↓
Route Handler Execution
↓
Template Rendering / JSON Response
↓
after_request() processing
↓
close_db() [teardown]
↓
Response Sent
Template Hierarchy
Base Template (base.html)
- Navigation bar (except on login page)
- Flash message display
- Main content area
- Footer
- Script includes
Child Templates
All pages extend base.html:
{% extends "base.html" %}
{% block title %}Page Title{% endblock %}
{% block extra_css %}
<!-- Page-specific CSS -->
{% endblock %}
{% block content %}
<!-- Page content -->
{% endblock %}
{% block extra_js %}
<!-- Page-specific JS -->
{% endblock %}
Static Files Organization
CSS
base.css- Common styles, responsive designlogin.css- Login page specific styles- Module-specific CSS can be added as needed
JavaScript
base.js- Common utilities, bootstrap initialization- Module-specific JS can be added as needed
Images
- Logo files
- Module icons
- User avatars (future enhancement)
Database Schema
Users Table
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(255) UNIQUE,
email VARCHAR(255),
full_name VARCHAR(255),
role VARCHAR(50),
is_active TINYINT(1),
created_at TIMESTAMP,
updated_at TIMESTAMP
);
User Credentials Table
CREATE TABLE user_credentials (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT FOREIGN KEY,
password_hash VARCHAR(255),
created_at TIMESTAMP,
updated_at TIMESTAMP
);
Quality Inspections Table
CREATE TABLE quality_inspections (
id INT PRIMARY KEY AUTO_INCREMENT,
inspection_type VARCHAR(100),
status VARCHAR(50),
inspector_id INT FOREIGN KEY,
inspection_date DATETIME,
notes TEXT,
created_at TIMESTAMP,
updated_at TIMESTAMP
);
Application Settings Table
CREATE TABLE application_settings (
id INT PRIMARY KEY AUTO_INCREMENT,
setting_key VARCHAR(255) UNIQUE,
setting_value LONGTEXT,
setting_type VARCHAR(50),
created_at TIMESTAMP,
updated_at TIMESTAMP
);
Error Handling
Error Pages
404.html- Page not found500.html- Internal server error403.html- Access forbidden
Error Handlers
@app.errorhandler(404)
def page_not_found(e):
return render_template('errors/404.html'), 404
Logging
Configuration
- Location:
/app/data/logs/app.log - Format:
timestamp - logger - level - message - Rotating file handler (10 files, 10MB each)
- Configurable log level via environment variable
Usage
import logging
logger = logging.getLogger(__name__)
logger.info("Information message")
logger.warning("Warning message")
logger.error("Error message")
Configuration Management
Development vs Production
class DevelopmentConfig(Config):
DEBUG = True
SESSION_COOKIE_SECURE = False
class ProductionConfig(Config):
DEBUG = False
SESSION_COOKIE_SECURE = True
Environment Variables
All sensitive configuration through .env:
- Database credentials
- Flask secret key
- API keys (future)
- Feature flags
Security Considerations
Implemented
- ✅ CSRF protection (Flask default)
- ✅ SQL injection prevention (parameterized queries)
- ✅ Secure password hashing
- ✅ Session security (HTTPOnly cookies)
- ✅ Authentication on protected routes
Recommended for Production
- 🔒 HTTPS/TLS
- 🔒 Content Security Policy (CSP) headers
- 🔒 CORS configuration
- 🔒 Rate limiting
- 🔒 Audit logging
- 🔒 Two-factor authentication
Testing Strategy
Unit Tests (Future)
# tests/test_auth.py
def test_authenticate_user_valid_credentials():
# Test successful authentication
def test_authenticate_user_invalid_password():
# Test password validation
Integration Tests (Future)
# tests/test_routes.py
def test_login_page_loads():
# Test login page accessibility
def test_dashboard_requires_authentication():
# Test authentication requirement
Performance Optimization
Database
- Connection pooling
- Query optimization
- Indexed lookups
- Prepared statements
Frontend
- Bootstrap CDN (cached by browser)
- Minified CSS/JS
- Image optimization
Application
- Request/response compression
- Caching headers
- Session caching
Docker Deployment Considerations
Multi-stage Build (Future Enhancement)
# Builder stage
FROM python:3.11 AS builder
# ... build dependencies ...
# Runtime stage
FROM python:3.11-slim
# ... copy only necessary files ...
Security Best Practices
- Non-root user (future enhancement)
- Health checks configured
- Minimal base image
- No unnecessary packages
Git Workflow
Branching Strategy
main (production)
↑
develop (staging)
↑
feature/* (development)
Commit Messages
[type]: [description]
Types: feat, fix, docs, style, refactor, test, chore
Deployment Pipeline
- Development → Push to feature branch
- Testing → Merge to develop, run tests
- Staging → Deploy to staging environment
- Production → Merge to main, deploy
Monitoring & Logging
Application Logs
- Location:
/app/data/logs/app.log - Includes: Errors, warnings, info messages
- Rotation: 10 files x 10MB
Database Logs
- Enable in MariaDB:
general_log = 1 - Monitor slow queries:
slow_query_log = 1
Container Health
docker-compose ps # View health status
Scaling Strategies
Horizontal Scaling
- Load balancer (Nginx/HAProxy)
- Multiple app instances
- Shared database
Vertical Scaling
- Increase container resources
- Optimize database queries
- Add caching layer
Documentation Standards
Docstrings
def function_name(param1, param2):
"""
Short description.
Longer description if needed.
Args:
param1: Description
param2: Description
Returns:
Description of return value
"""
pass
Comments
- Explain WHY, not WHAT
- Use for complex logic
- Keep up-to-date
Code Style
Python (PEP 8)
- 4 spaces indentation
- Max line length 100 characters
- Meaningful variable names
- Docstrings for public functions
HTML/CSS/JavaScript
- 4 spaces indentation
- Semantic HTML
- BEM naming for CSS classes
- ES6+ JavaScript
Future Architecture Enhancements
- API Layer - REST API for mobile apps
- Caching - Redis for session/query caching
- Queue System - Celery for async tasks
- Microservices - Separate services for scaling
- Monitoring - Prometheus + Grafana
- Message Queue - RabbitMQ/Kafka
- Search Engine - Elasticsearch
- CDN - Static file distribution
References
- Flask Documentation: https://flask.palletsprojects.com/
- SQLAlchemy (for future migration): https://www.sqlalchemy.org/
- Bootstrap 5: https://getbootstrap.com/
- MariaDB: https://mariadb.com/kb/
- Docker: https://docs.docker.com/