#!/usr/bin/env python3 """ Create Module Script Generer et nyt BMC Hub modul fra template """ import os import sys import json import shutil from pathlib import Path def create_module(module_name: str, description: str = ""): """ Opret nyt modul baseret på _template Args: module_name: Navn på nyt modul (fx "my_module") description: Beskrivelse af modul """ # Validate module name if not module_name.replace("_", "").isalnum(): print(f"❌ Ugyldigt modul navn: {module_name}") print(" Brug kun bogstaver, tal og underscore") sys.exit(1) # Paths project_root = Path(__file__).parent.parent modules_dir = project_root / "app" / "modules" template_dir = modules_dir / "_template" new_module_dir = modules_dir / module_name # Check if template exists if not template_dir.exists(): print(f"❌ Template directory ikke fundet: {template_dir}") sys.exit(1) # Check if module already exists if new_module_dir.exists(): print(f"❌ Modul '{module_name}' eksisterer allerede") sys.exit(1) print(f"📦 Opretter modul: {module_name}") print(f" Placering: {new_module_dir}") # Copy template try: shutil.copytree(template_dir, new_module_dir) print(f"✅ Kopieret template struktur") except Exception as e: print(f"❌ Kunne ikke kopiere template: {e}") sys.exit(1) # Update module.json manifest_path = new_module_dir / "module.json" try: with open(manifest_path, 'r', encoding='utf-8') as f: manifest = json.load(f) manifest["name"] = module_name manifest["description"] = description or f"BMC Hub module: {module_name}" manifest["table_prefix"] = f"{module_name}_" manifest["api_prefix"] = f"/api/v1/{module_name}" manifest["tags"] = [module_name.replace("_", " ").title()] with open(manifest_path, 'w', encoding='utf-8') as f: json.dump(manifest, f, indent=2, ensure_ascii=False) print(f"✅ Opdateret module.json") except Exception as e: print(f"❌ Kunne ikke opdatere module.json: {e}") sys.exit(1) # Update README.md readme_path = new_module_dir / "README.md" try: with open(readme_path, 'r', encoding='utf-8') as f: readme = f.read() # Replace template references readme = readme.replace("Template Module", f"{module_name.replace('_', ' ').title()} Module") readme = readme.replace("template_module", module_name) readme = readme.replace("my_module", module_name) readme = readme.replace("mymod_", f"{module_name}_") readme = readme.replace("template_", f"{module_name}_") with open(readme_path, 'w', encoding='utf-8') as f: f.write(readme) print(f"✅ Opdateret README.md") except Exception as e: print(f"⚠️ Kunne ikke opdatere README: {e}") # Update backend/router.py router_path = new_module_dir / "backend" / "router.py" try: with open(router_path, 'r', encoding='utf-8') as f: router_code = f.read() router_code = router_code.replace("Template Module", f"{module_name.replace('_', ' ').title()} Module") router_code = router_code.replace("template_module", module_name) router_code = router_code.replace("template_items", f"{module_name}_items") router_code = router_code.replace("/template/", f"/{module_name}/") with open(router_path, 'w', encoding='utf-8') as f: f.write(router_code) print(f"✅ Opdateret backend/router.py") except Exception as e: print(f"⚠️ Kunne ikke opdatere router: {e}") # Update frontend/views.py views_path = new_module_dir / "frontend" / "views.py" try: with open(views_path, 'r', encoding='utf-8') as f: views_code = f.read() views_code = views_code.replace("Template Module", f"{module_name.replace('_', ' ').title()} Module") views_code = views_code.replace("template_module", module_name) views_code = views_code.replace("template_items", f"{module_name}_items") views_code = views_code.replace("/template", f"/{module_name}") views_code = views_code.replace("_template", module_name) with open(views_path, 'w', encoding='utf-8') as f: f.write(views_code) print(f"✅ Opdateret frontend/views.py") except Exception as e: print(f"⚠️ Kunne ikke opdatere views: {e}") # Update migration SQL migration_path = new_module_dir / "migrations" / "001_init.sql" try: with open(migration_path, 'r', encoding='utf-8') as f: migration_sql = f.read() migration_sql = migration_sql.replace("Template Module", f"{module_name.replace('_', ' ').title()} Module") migration_sql = migration_sql.replace("template_items", f"{module_name}_items") migration_sql = migration_sql.replace("template_module", module_name) with open(migration_path, 'w', encoding='utf-8') as f: f.write(migration_sql) print(f"✅ Opdateret migrations/001_init.sql") except Exception as e: print(f"⚠️ Kunne ikke opdatere migration: {e}") print() print("🎉 Modul oprettet successfully!") print() print("Næste steps:") print(f"1. Kør database migration:") print(f" psql -U bmc_hub -d bmc_hub -f app/modules/{module_name}/migrations/001_init.sql") print() print(f"2. Enable modulet:") print(f" Rediger app/modules/{module_name}/module.json og sæt 'enabled': true") print() print(f"3. Restart API:") print(f" docker-compose restart api") print() print(f"4. Test endpoints:") print(f" http://localhost:8000/api/docs#{module_name.replace('_', '-').title()}") print(f" http://localhost:8000/{module_name}") print() print(f"5. Tilføj modul-specifik konfiguration til .env:") print(f" MODULES__{module_name.upper()}__READ_ONLY=false") print(f" MODULES__{module_name.upper()}__DRY_RUN=false") print() def main(): """Main entry point""" if len(sys.argv) < 2: print("Usage: python scripts/create_module.py [description]") print() print("Eksempel:") print(' python scripts/create_module.py my_feature "My awesome feature"') sys.exit(1) module_name = sys.argv[1] description = sys.argv[2] if len(sys.argv) > 2 else "" create_module(module_name, description) if __name__ == "__main__": main()