# Solution Module

Dette er template strukturen for nye BMC Hub moduler.

## Struktur

```
solution/
├── 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 solution "My Module Description"
```

## Database Tables

Alle tabeller SKAL bruge `table_prefix` fra module.json:

```sql
-- Hvis table_prefix = "solution_"
CREATE TABLE solution_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 solution_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_solution_customer
    BEFORE INSERT OR UPDATE OF name
    ON solution_customers
    FOR EACH ROW
    EXECUTE FUNCTION auto_link_solution_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 solution_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("solution", "API_KEY")
read_only = get_module_config("solution", "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 solution_customers WHERE active = %s", 
    (True,)
)

# Insert
customer_id = execute_insert(
    "INSERT INTO solution_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("solution", migration_sql)
```

## Enable/Disable

```bash
# Enable via API
curl -X POST http://localhost:8000/api/v1/modules/solution/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_solution():
    # 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
