refactor: complete module-driven architecture migration
This commit completes the migration to a fully module-driven architecture: ## Models Migration - Moved all domain models from models/database/ to their respective modules: - tenancy: User, Admin, Vendor, Company, Platform, VendorDomain, etc. - cms: MediaFile, VendorTheme - messaging: Email, VendorEmailSettings, VendorEmailTemplate - core: AdminMenuConfig - models/database/ now only contains Base and TimestampMixin (infrastructure) ## Schemas Migration - Moved all domain schemas from models/schema/ to their respective modules: - tenancy: company, vendor, admin, team, vendor_domain - cms: media, image, vendor_theme - messaging: email - models/schema/ now only contains base.py and auth.py (infrastructure) ## Routes Migration - Moved admin routes from app/api/v1/admin/ to modules: - menu_config.py -> core module - modules.py -> tenancy module - module_config.py -> tenancy module - app/api/v1/admin/ now only aggregates auto-discovered module routes ## Menu System - Implemented module-driven menu system with MenuDiscoveryService - Extended FrontendType enum: PLATFORM, ADMIN, VENDOR, STOREFRONT - Added MenuItemDefinition and MenuSectionDefinition dataclasses - Each module now defines its own menu items in definition.py - MenuService integrates with MenuDiscoveryService for template rendering ## Documentation - Updated docs/architecture/models-structure.md - Updated docs/architecture/menu-management.md - Updated architecture validation rules for new exceptions ## Architecture Validation - Updated MOD-019 rule to allow base.py in models/schema/ - Created core module exceptions.py and schemas/ directory - All validation errors resolved (only warnings remain) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -132,7 +132,7 @@ function adminComponents() {
|
||||
this.addedToCart = true;
|
||||
setTimeout(() => { this.addedToCart = false; }, 2000);
|
||||
if (typeof Utils !== 'undefined' && Utils.showToast) {
|
||||
Utils.showToast('Added to cart!', 'success');
|
||||
Utils.showToast(I18n.t('dev_tools.messages.added_to_cart'), 'success');
|
||||
}
|
||||
}, 800);
|
||||
},
|
||||
@@ -320,7 +320,7 @@ function adminComponents() {
|
||||
demoFilterProducts() {
|
||||
componentsLog.debug('Filtering products with:', this.demoActiveFilters);
|
||||
if (typeof Utils !== 'undefined' && Utils.showToast) {
|
||||
Utils.showToast('Filters applied!', 'info');
|
||||
Utils.showToast(I18n.t('dev_tools.messages.filters_applied'), 'info');
|
||||
}
|
||||
},
|
||||
demoSortProducts() {
|
||||
@@ -391,7 +391,7 @@ function adminComponents() {
|
||||
this.showReviewForm = false;
|
||||
this.demoNewReview = { rating: 0, title: '', content: '', images: [] };
|
||||
if (typeof Utils !== 'undefined' && Utils.showToast) {
|
||||
Utils.showToast('Review submitted successfully!', 'success');
|
||||
Utils.showToast(I18n.t('dev_tools.messages.review_submitted_successfully'), 'success');
|
||||
}
|
||||
}, 1500);
|
||||
},
|
||||
@@ -401,7 +401,7 @@ function adminComponents() {
|
||||
review.helpful_count++;
|
||||
}
|
||||
if (typeof Utils !== 'undefined' && Utils.showToast) {
|
||||
Utils.showToast('Thanks for your feedback!', 'info');
|
||||
Utils.showToast(I18n.t('dev_tools.messages.thanks_for_your_feedback'), 'info');
|
||||
}
|
||||
},
|
||||
|
||||
@@ -468,6 +468,9 @@ function adminComponents() {
|
||||
|
||||
// ✅ CRITICAL: Proper initialization with guard
|
||||
async init() {
|
||||
// Load i18n translations
|
||||
await I18n.loadModule('dev_tools');
|
||||
|
||||
componentsLog.info('=== COMPONENTS PAGE INITIALIZING ===');
|
||||
|
||||
// Prevent multiple initializations
|
||||
@@ -534,7 +537,7 @@ function adminComponents() {
|
||||
await navigator.clipboard.writeText(code);
|
||||
// Use the global Utils.showToast function
|
||||
if (typeof Utils !== 'undefined' && Utils.showToast) {
|
||||
Utils.showToast('Code copied to clipboard!', 'success');
|
||||
Utils.showToast(I18n.t('dev_tools.messages.code_copied_to_clipboard'), 'success');
|
||||
} else {
|
||||
componentsLog.warn('Utils.showToast not available');
|
||||
}
|
||||
@@ -542,7 +545,7 @@ function adminComponents() {
|
||||
} catch (error) {
|
||||
window.LogConfig.logError(error, 'Copy Code');
|
||||
if (typeof Utils !== 'undefined' && Utils.showToast) {
|
||||
Utils.showToast('Failed to copy code', 'error');
|
||||
Utils.showToast(I18n.t('dev_tools.messages.failed_to_copy_code'), 'error');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -45,6 +45,9 @@ function adminIcons() {
|
||||
|
||||
// ✅ CRITICAL: Proper initialization with guard
|
||||
async init() {
|
||||
// Load i18n translations
|
||||
await I18n.loadModule('dev_tools');
|
||||
|
||||
iconsLog.info('=== ICONS PAGE INITIALIZING ===');
|
||||
|
||||
// Prevent multiple initializations
|
||||
@@ -169,7 +172,7 @@ function adminIcons() {
|
||||
iconsLog.debug('Icon usage code copied:', iconName);
|
||||
} catch (error) {
|
||||
window.LogConfig.logError(error, 'Copy Icon Usage');
|
||||
Utils.showToast('Failed to copy code', 'error');
|
||||
Utils.showToast(I18n.t('dev_tools.messages.failed_to_copy_code'), 'error');
|
||||
}
|
||||
},
|
||||
|
||||
@@ -183,7 +186,7 @@ function adminIcons() {
|
||||
iconsLog.debug('Icon name copied:', iconName);
|
||||
} catch (error) {
|
||||
window.LogConfig.logError(error, 'Copy Icon Name');
|
||||
Utils.showToast('Failed to copy name', 'error');
|
||||
Utils.showToast(I18n.t('dev_tools.messages.failed_to_copy_name'), 'error');
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -54,6 +54,9 @@ function testingDashboard() {
|
||||
runs: [],
|
||||
|
||||
async init() {
|
||||
// Load i18n translations
|
||||
await I18n.loadModule('dev_tools');
|
||||
|
||||
// Guard against multiple initialization
|
||||
if (window._adminTestingDashboardInitialized) return;
|
||||
window._adminTestingDashboardInitialized = true;
|
||||
@@ -148,7 +151,7 @@ function testingDashboard() {
|
||||
// Start polling for status
|
||||
this.pollInterval = setInterval(() => this.pollRunStatus(), 2000);
|
||||
|
||||
Utils.showToast('Test run started...', 'info');
|
||||
Utils.showToast(I18n.t('dev_tools.messages.test_run_started'), 'info');
|
||||
|
||||
} catch (err) {
|
||||
testingDashboardLog.error('Failed to start tests:', err);
|
||||
|
||||
Reference in New Issue
Block a user