diff --git a/main.py b/main.py index 24d80fda..c0c177b4 100644 --- a/main.py +++ b/main.py @@ -178,13 +178,10 @@ logger.info("=" * 80) # ======================================== # MOUNT STATIC FILES - Use absolute path # ======================================== -if STATIC_DIR.exists(): - app.mount("/static", StaticFiles(directory=str(STATIC_DIR)), name="static") - logger.info(f"Mounted static files from: {STATIC_DIR}") -else: - logger.warning(f"Static directory not found at {STATIC_DIR}") +# NOTE: Mount order matters in FastAPI - more specific paths must come FIRST +# Module static files must be mounted before the main /static mount -# Mount module static files (self-contained modules) +# Mount module static files FIRST (self-contained modules) MODULES_DIR = BASE_DIR / "app" / "modules" if MODULES_DIR.exists(): for module_dir in sorted(MODULES_DIR.iterdir()): @@ -197,6 +194,13 @@ if MODULES_DIR.exists(): app.mount(mount_path, StaticFiles(directory=str(module_static)), name=f"{module_name}_static") logger.info(f"Mounted module static files: {mount_path} -> {module_static}") +# Mount main static directory AFTER module statics +if STATIC_DIR.exists(): + app.mount("/static", StaticFiles(directory=str(STATIC_DIR)), name="static") + logger.info(f"Mounted static files from: {STATIC_DIR}") +else: + logger.warning(f"Static directory not found at {STATIC_DIR}") + # Mount uploads directory for user-uploaded media files UPLOADS_DIR = BASE_DIR / "uploads" if UPLOADS_DIR.exists(): diff --git a/scripts/validate_architecture.py b/scripts/validate_architecture.py index 23a37bae..04bb26c0 100755 --- a/scripts/validate_architecture.py +++ b/scripts/validate_architecture.py @@ -2906,10 +2906,13 @@ class ArchitectureValidator: print("🟨 Validating JavaScript...") # Include admin, vendor, and shared JS files + # Also include self-contained module JS files js_files = ( list(target_path.glob("static/admin/js/**/*.js")) + list(target_path.glob("static/vendor/js/**/*.js")) + list(target_path.glob("static/shared/js/**/*.js")) + + list(target_path.glob("app/modules/*/static/admin/js/**/*.js")) + + list(target_path.glob("app/modules/*/static/vendor/js/**/*.js")) ) self.result.files_checked += len(js_files) @@ -3237,10 +3240,13 @@ class ArchitectureValidator: print("📄 Validating templates...") # Include admin, vendor, and shop templates + # Also include self-contained module templates template_files = ( list(target_path.glob("app/templates/admin/**/*.html")) + list(target_path.glob("app/templates/vendor/**/*.html")) + - list(target_path.glob("app/templates/shop/**/*.html")) + list(target_path.glob("app/templates/shop/**/*.html")) + + list(target_path.glob("app/modules/*/templates/*/admin/**/*.html")) + + list(target_path.glob("app/modules/*/templates/*/vendor/**/*.html")) ) self.result.files_checked += len(template_files) @@ -3330,7 +3336,19 @@ class ArchitectureValidator: js_dir = None if js_dir: + # Check standard static path first js_file = target_path / f"static/{js_dir}/js/{template_name}.js" + + # For module templates, check module static path + # e.g., app/modules/cms/templates/cms/admin/content-pages.html + # -> app/modules/cms/static/admin/js/content-pages.js + if not js_file.exists() and "/modules/" in file_path_str: + # Extract module name from path + parts = file_path_str.split("/modules/") + if len(parts) > 1: + module_part = parts[1].split("/")[0] # e.g., "cms" + js_file = target_path / f"app/modules/{module_part}/static/{js_dir}/js/{template_name}.js" + if js_file.exists(): js_content = js_file.read_text() self._check_alpine_template_vars(file_path, content, lines, js_content)