Refactor application to MVC architecture with Flask blueprints
Major architectural refactoring to improve code organization, maintainability, and scalability:
- Implement MVC pattern with clear separation of concerns
- Organize code into blueprints for different functional areas (main, tenant, admin, api)
- Create models layer to encapsulate all database operations
- Create services layer for business logic (auth, product, barcode)
- Implement application factory pattern for better testability
- Add environment-based configuration management
- Remove old monolithic app.py and consolidate routes
New structure:
- app/models/ - Database operations (Tenant, Product, ARField, Settings)
- app/services/ - Business logic (Auth, Product, Barcode services)
- app/blueprints/ - Controllers organized by function
- app/config.py - Environment configurations
- run.py - Application entry point
All routes remain backward compatible. No changes to API or templates functionality.
2025-10-20 18:11:16 -04:00
|
|
|
from typing import Dict, List, Any
|
|
|
|
|
from .base import get_db
|
|
|
|
|
|
|
|
|
|
class ARFieldModel:
|
|
|
|
|
"""Model for custom AR field operations"""
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def get_all(tenant_id: str) -> List[Dict[str, Any]]:
|
|
|
|
|
"""Get all custom AR fields for a tenant"""
|
|
|
|
|
tenant_id = tenant_id.lower()
|
|
|
|
|
|
|
|
|
|
with get_db() as conn:
|
|
|
|
|
cursor = conn.cursor()
|
|
|
|
|
cursor.execute('''
|
|
|
|
|
SELECT id, field_name, label, field_type, editable, display_order
|
|
|
|
|
FROM custom_ar_fields
|
|
|
|
|
WHERE tenant_id = ?
|
|
|
|
|
ORDER BY display_order, id
|
|
|
|
|
''', (tenant_id,))
|
|
|
|
|
|
|
|
|
|
fields = []
|
|
|
|
|
for row in cursor.fetchall():
|
|
|
|
|
fields.append({
|
|
|
|
|
'id': row['id'],
|
|
|
|
|
'fieldName': row['field_name'],
|
|
|
|
|
'label': row['label'],
|
|
|
|
|
'fieldType': row['field_type'],
|
|
|
|
|
'editable': row['editable'],
|
|
|
|
|
'displayOrder': row['display_order']
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
return fields
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def save(tenant_id: str, field_data: Dict[str, Any]):
|
|
|
|
|
"""Save or update a custom AR field"""
|
|
|
|
|
tenant_id = tenant_id.lower()
|
|
|
|
|
|
2025-10-20 22:30:54 -04:00
|
|
|
# Strip whitespace from field name and label to prevent spacing issues
|
|
|
|
|
field_name = field_data['fieldName'].strip() if field_data.get('fieldName') else ''
|
|
|
|
|
label = field_data['label'].strip() if field_data.get('label') else ''
|
|
|
|
|
|
Refactor application to MVC architecture with Flask blueprints
Major architectural refactoring to improve code organization, maintainability, and scalability:
- Implement MVC pattern with clear separation of concerns
- Organize code into blueprints for different functional areas (main, tenant, admin, api)
- Create models layer to encapsulate all database operations
- Create services layer for business logic (auth, product, barcode)
- Implement application factory pattern for better testability
- Add environment-based configuration management
- Remove old monolithic app.py and consolidate routes
New structure:
- app/models/ - Database operations (Tenant, Product, ARField, Settings)
- app/services/ - Business logic (Auth, Product, Barcode services)
- app/blueprints/ - Controllers organized by function
- app/config.py - Environment configurations
- run.py - Application entry point
All routes remain backward compatible. No changes to API or templates functionality.
2025-10-20 18:11:16 -04:00
|
|
|
with get_db() as conn:
|
|
|
|
|
cursor = conn.cursor()
|
|
|
|
|
|
|
|
|
|
if 'id' in field_data and field_data['id']:
|
|
|
|
|
# Update existing field
|
|
|
|
|
cursor.execute('''
|
|
|
|
|
UPDATE custom_ar_fields
|
|
|
|
|
SET field_name = ?, label = ?, field_type = ?, editable = ?,
|
|
|
|
|
display_order = ?, updated_at = CURRENT_TIMESTAMP
|
|
|
|
|
WHERE id = ? AND tenant_id = ?
|
|
|
|
|
''', (
|
2025-10-20 22:30:54 -04:00
|
|
|
field_name,
|
|
|
|
|
label,
|
Refactor application to MVC architecture with Flask blueprints
Major architectural refactoring to improve code organization, maintainability, and scalability:
- Implement MVC pattern with clear separation of concerns
- Organize code into blueprints for different functional areas (main, tenant, admin, api)
- Create models layer to encapsulate all database operations
- Create services layer for business logic (auth, product, barcode)
- Implement application factory pattern for better testability
- Add environment-based configuration management
- Remove old monolithic app.py and consolidate routes
New structure:
- app/models/ - Database operations (Tenant, Product, ARField, Settings)
- app/services/ - Business logic (Auth, Product, Barcode services)
- app/blueprints/ - Controllers organized by function
- app/config.py - Environment configurations
- run.py - Application entry point
All routes remain backward compatible. No changes to API or templates functionality.
2025-10-20 18:11:16 -04:00
|
|
|
field_data['fieldType'],
|
|
|
|
|
field_data['editable'],
|
|
|
|
|
field_data['displayOrder'],
|
|
|
|
|
field_data['id'],
|
|
|
|
|
tenant_id
|
|
|
|
|
))
|
|
|
|
|
else:
|
|
|
|
|
# Insert new field
|
|
|
|
|
cursor.execute('''
|
|
|
|
|
INSERT INTO custom_ar_fields
|
|
|
|
|
(tenant_id, field_name, label, field_type, editable, display_order)
|
|
|
|
|
VALUES (?, ?, ?, ?, ?, ?)
|
|
|
|
|
''', (
|
|
|
|
|
tenant_id,
|
2025-10-20 22:30:54 -04:00
|
|
|
field_name,
|
|
|
|
|
label,
|
Refactor application to MVC architecture with Flask blueprints
Major architectural refactoring to improve code organization, maintainability, and scalability:
- Implement MVC pattern with clear separation of concerns
- Organize code into blueprints for different functional areas (main, tenant, admin, api)
- Create models layer to encapsulate all database operations
- Create services layer for business logic (auth, product, barcode)
- Implement application factory pattern for better testability
- Add environment-based configuration management
- Remove old monolithic app.py and consolidate routes
New structure:
- app/models/ - Database operations (Tenant, Product, ARField, Settings)
- app/services/ - Business logic (Auth, Product, Barcode services)
- app/blueprints/ - Controllers organized by function
- app/config.py - Environment configurations
- run.py - Application entry point
All routes remain backward compatible. No changes to API or templates functionality.
2025-10-20 18:11:16 -04:00
|
|
|
field_data['fieldType'],
|
|
|
|
|
field_data['editable'],
|
|
|
|
|
field_data['displayOrder']
|
|
|
|
|
))
|
|
|
|
|
|
|
|
|
|
conn.commit()
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def delete(tenant_id: str, field_id: int):
|
|
|
|
|
"""Delete a custom AR field"""
|
|
|
|
|
tenant_id = tenant_id.lower()
|
|
|
|
|
|
|
|
|
|
with get_db() as conn:
|
|
|
|
|
cursor = conn.cursor()
|
|
|
|
|
cursor.execute('DELETE FROM custom_ar_fields WHERE id = ? AND tenant_id = ?',
|
|
|
|
|
(field_id, tenant_id))
|
|
|
|
|
conn.commit()
|
2025-10-20 21:13:05 -04:00
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def create_default_fields(tenant_id: str):
|
|
|
|
|
"""Create default product fields for a new tenant"""
|
|
|
|
|
tenant_id = tenant_id.lower()
|
|
|
|
|
|
|
|
|
|
default_fields = [
|
|
|
|
|
{
|
|
|
|
|
'fieldName': '_name',
|
|
|
|
|
'label': 'Product Name',
|
|
|
|
|
'fieldType': 'TEXT',
|
|
|
|
|
'editable': 'true',
|
|
|
|
|
'displayOrder': 0
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'fieldName': '_id',
|
|
|
|
|
'label': 'Item ID',
|
|
|
|
|
'fieldType': 'TEXT',
|
|
|
|
|
'editable': 'false',
|
|
|
|
|
'displayOrder': 1
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'fieldName': '_price',
|
|
|
|
|
'label': 'Sale Price',
|
|
|
|
|
'fieldType': 'TEXT',
|
|
|
|
|
'editable': 'true',
|
|
|
|
|
'displayOrder': 2
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
'fieldName': '_image',
|
|
|
|
|
'label': 'Image',
|
|
|
|
|
'fieldType': 'IMAGE_URI',
|
|
|
|
|
'editable': 'true',
|
|
|
|
|
'displayOrder': 3
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
with get_db() as conn:
|
|
|
|
|
cursor = conn.cursor()
|
|
|
|
|
for field in default_fields:
|
|
|
|
|
cursor.execute('''
|
|
|
|
|
INSERT INTO custom_ar_fields
|
|
|
|
|
(tenant_id, field_name, label, field_type, editable, display_order)
|
|
|
|
|
VALUES (?, ?, ?, ?, ?, ?)
|
|
|
|
|
''', (
|
|
|
|
|
tenant_id,
|
|
|
|
|
field['fieldName'],
|
|
|
|
|
field['label'],
|
|
|
|
|
field['fieldType'],
|
|
|
|
|
field['editable'],
|
|
|
|
|
field['displayOrder']
|
|
|
|
|
))
|
|
|
|
|
conn.commit()
|