From a727796ed2ab53199c0a0a853e3286f96c9c8dda Mon Sep 17 00:00:00 2001 From: Matt Hills Date: Mon, 20 Oct 2025 21:13:05 -0400 Subject: [PATCH 1/2] Add optional default product fields on tenant creation When creating a new tenant, users can now choose to initialize with default product fields (Product Name, Item ID, Sale Price, and Image). The option is presented via a checkbox in the tenant creation modal and is enabled by default. --- src/app/blueprints/tenant/routes.py | 13 +++++- src/app/models/ar_field.py | 53 +++++++++++++++++++++++++ src/app/templates/tenant_selection.html | 16 +++++++- 3 files changed, 80 insertions(+), 2 deletions(-) diff --git a/src/app/blueprints/tenant/routes.py b/src/app/blueprints/tenant/routes.py index d6bfc37..967e23c 100644 --- a/src/app/blueprints/tenant/routes.py +++ b/src/app/blueprints/tenant/routes.py @@ -13,9 +13,20 @@ def index(tenant_id): if tenant is None: return jsonify({"error": f"'{tenant_id}' is a reserved name and cannot be used as a tenant ID"}), 404 - products = ProductModel.get_all(tenant_id) + # Check if we should create default fields for a new tenant + create_defaults = request.args.get('create_defaults', '0') == '1' custom_fields = ARFieldModel.get_all(tenant_id) + # If no custom fields exist and user requested defaults, create them + if create_defaults and not custom_fields: + ARFieldModel.create_default_fields(tenant_id) + custom_fields = ARFieldModel.get_all(tenant_id) + flash('Tenant created with default product fields!', 'success') + # Redirect to remove the query parameter + return redirect(f'/{tenant_id}/') + + products = ProductModel.get_all(tenant_id) + return render_template('index.html', tenant=tenant, products=products, custom_fields=custom_fields) @tenant_bp.route('/delete', methods=['POST']) diff --git a/src/app/models/ar_field.py b/src/app/models/ar_field.py index 8e63f7c..80aed46 100644 --- a/src/app/models/ar_field.py +++ b/src/app/models/ar_field.py @@ -82,3 +82,56 @@ class ARFieldModel: cursor.execute('DELETE FROM custom_ar_fields WHERE id = ? AND tenant_id = ?', (field_id, tenant_id)) conn.commit() + + @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() diff --git a/src/app/templates/tenant_selection.html b/src/app/templates/tenant_selection.html index 7540360..ab4de58 100644 --- a/src/app/templates/tenant_selection.html +++ b/src/app/templates/tenant_selection.html @@ -160,6 +160,15 @@ Only letters, numbers, hyphens, and underscores allowed +
+
+ + +
+ Adds: Product Name, Item ID, Sale Price, and Image fields +
Default credentials: admin / admin @@ -237,13 +246,18 @@ document.getElementById('newTenantForm').addEventListener('submit', function(e) { e.preventDefault(); const tenantId = document.getElementById('tenantId').value; + const createDefaults = document.getElementById('createDefaultFields').checked; + if (tenantId) { const normalizedId = tenantId.toLowerCase(); if (reservedIds.includes(normalizedId)) { alert(`"${tenantId}" is a reserved name and cannot be used as a tenant ID.`); return; } - window.location.href = '/' + normalizedId + '/'; + + // Redirect with query parameter for default fields + const url = '/' + normalizedId + '/' + (createDefaults ? '?create_defaults=1' : ''); + window.location.href = url; } }); From 03b4264239729ccd2a9c7dde553d45fab4673a8a Mon Sep 17 00:00:00 2001 From: Matt Hills Date: Mon, 20 Oct 2025 21:36:01 -0400 Subject: [PATCH 2/2] Fix foreign key cascades and add validation for missing AR fields - Enable SQLite foreign key constraints to properly cascade deletes - Add validation to prevent adding products when no AR fields configured - Display helpful warnings on product pages when fields are missing - Redirect users to AR field configuration when needed --- src/app/blueprints/admin/routes.py | 5 +++++ src/app/models/base.py | 2 ++ src/app/templates/admin/add_product.html | 16 ++++++++++++++++ src/app/templates/index.html | 15 ++++++++++++++- 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/app/blueprints/admin/routes.py b/src/app/blueprints/admin/routes.py index 7a392c7..fa14396 100644 --- a/src/app/blueprints/admin/routes.py +++ b/src/app/blueprints/admin/routes.py @@ -10,6 +10,11 @@ def add_product(tenant_id): """Add a new product""" custom_fields = ARFieldModel.get_all(tenant_id) + # Prevent adding products if no fields are configured + if not custom_fields: + flash('Cannot add products. Please configure AR fields first.', 'warning') + return redirect(url_for('admin.manage_ar_fields', tenant_id=tenant_id)) + if request.method == 'POST': product_id = request.form.get('product_id') diff --git a/src/app/models/base.py b/src/app/models/base.py index 6aa7ff6..31e1775 100644 --- a/src/app/models/base.py +++ b/src/app/models/base.py @@ -8,6 +8,8 @@ def get_db(): db_path = current_app.config['DATABASE_PATH'] conn = sqlite3.connect(db_path) conn.row_factory = sqlite3.Row + # Enable foreign key constraints + conn.execute('PRAGMA foreign_keys = ON') try: yield conn finally: diff --git a/src/app/templates/admin/add_product.html b/src/app/templates/admin/add_product.html index d38843b..7df582f 100644 --- a/src/app/templates/admin/add_product.html +++ b/src/app/templates/admin/add_product.html @@ -10,6 +10,21 @@

Add New Product

+ {% if not custom_fields %} + + {% else %}
@@ -71,6 +86,7 @@
+ {% endif %}
diff --git a/src/app/templates/index.html b/src/app/templates/index.html index 714a997..beac3fa 100644 --- a/src/app/templates/index.html +++ b/src/app/templates/index.html @@ -16,6 +16,18 @@
+ {% if not custom_fields %} + + {% else %}

Products

@@ -27,7 +39,7 @@
- + {% if products %}
@@ -91,6 +103,7 @@ No products available yet. Click "Add New Product" to get started. {% endif %} + {% endif %}