# Template Module Dette er template strukturen for nye BMC Hub moduler. ## Struktur ``` my_module/ ├── module.json # Metadata og konfiguration ├── README.md # Dokumentation ├── backend/ │ ├── __init__.py │ └── router.py # FastAPI routes (API endpoints) ├── frontend/ │ ├── __init__.py │ └── views.py # HTML view routes ├── templates/ │ └── index.html # Jinja2 templates └── migrations/ └── 001_init.sql # Database migrations ``` ## Opret nyt modul ```bash python scripts/create_module.py my_module "My Module Description" ``` ## Database Tables Alle tabeller SKAL bruge `table_prefix` fra module.json: ```sql -- Hvis table_prefix = "mymod_" CREATE TABLE mymod_items ( id SERIAL PRIMARY KEY, name VARCHAR(255) ); ``` Dette sikrer at moduler ikke kolliderer med core eller andre moduler. ### Customer Linking (Hvis nødvendigt) Hvis dit modul skal have sin egen kunde-tabel (f.eks. ved sync fra eksternt system): **SKAL altid linke til core customers:** ```sql CREATE TABLE mymod_customers ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, external_id VARCHAR(100), -- ID fra eksternt system hub_customer_id INTEGER REFERENCES customers(id), -- VIGTIG! active BOOLEAN DEFAULT TRUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- Auto-link trigger (se migrations/001_init.sql for komplet eksempel) CREATE TRIGGER trigger_auto_link_mymod_customer BEFORE INSERT OR UPDATE OF name ON mymod_customers FOR EACH ROW EXECUTE FUNCTION auto_link_mymod_customer(); ``` **Hvorfor?** Dette sikrer at: - ✅ E-conomic export virker automatisk - ✅ Billing integration fungerer - ✅ Ingen manuel linking nødvendig **Alternativ:** Hvis modulet kun har simple kunde-relationer, brug direkte FK: ```sql CREATE TABLE mymod_orders ( id SERIAL PRIMARY KEY, customer_id INTEGER REFERENCES customers(id) -- Direkte link ); ``` ## Konfiguration Modul-specifikke miljøvariable følger mønsteret: ```bash MODULES__MY_MODULE__API_KEY=secret123 MODULES__MY_MODULE__READ_ONLY=true ``` Tilgå i kode: ```python from app.core.config import get_module_config api_key = get_module_config("my_module", "API_KEY") read_only = get_module_config("my_module", "READ_ONLY", default="true") == "true" ``` ## Database Queries Brug ALTID helper functions fra `app.core.database`: ```python from app.core.database import execute_query, execute_insert # Fetch customers = execute_query( "SELECT * FROM mymod_customers WHERE active = %s", (True,) ) # Insert customer_id = execute_insert( "INSERT INTO mymod_customers (name) VALUES (%s)", ("Test Customer",) ) ``` ## Migrations Migrations ligger i `migrations/` og køres manuelt eller via migration tool: ```python from app.core.database import execute_module_migration with open("migrations/001_init.sql") as f: migration_sql = f.read() success = execute_module_migration("my_module", migration_sql) ``` ## Enable/Disable ```bash # Enable via API curl -X POST http://localhost:8000/api/v1/modules/my_module/enable # Eller rediger module.json { "enabled": true } # Restart app docker-compose restart api ``` ## Fejlhåndtering Moduler er isolerede - hvis dit modul crasher ved opstart: - Core systemet kører videre - Modulet bliver ikke loaded - Fejl logges til console og logs/app.log Runtime fejl i endpoints påvirker ikke andre moduler. ## Testing ```python import pytest from app.core.database import execute_query def test_my_module(): # Test bruger samme database helpers result = execute_query("SELECT 1 as test") assert result[0]["test"] == 1 ``` ## Best Practices 1. **Database isolering**: Brug ALTID `table_prefix` fra module.json 2. **Safety switches**: Tilføj `READ_ONLY` og `DRY_RUN` flags 3. **Error handling**: Log fejl, raise HTTPException med status codes 4. **Dependencies**: Deklarer i `module.json` hvis du bruger andre moduler 5. **Migrations**: Nummer sekventielt (001, 002, 003...) 6. **Documentation**: Opdater README.md med API endpoints og use cases