{% extends "shared/frontend/base.html" %} {% block title %}Indstillinger - BMC Hub{% endblock %} {% block extra_css %}
{% endblock %} {% block content %}

## Indstillinger

System konfiguration og brugerstyring

##### Firma Oplysninger

##### vTiger CRM

##### e-conomic

##### Nextcloud

Administrer kunde‑instanser, credentials og audit‑log

Kunde | Base URL | Bruger | Status | Sidst opdateret | Handlinger
--- | --- | --- | --- | --- | ---

###### Audit‑log retention

Manuel sletning pr. kunde (tidsbaseret)

##### Click-to-Call (Action URL)

Konfigurer URL-template til at starte opkald via telefon/PBX endpoint.

Callback shared secret
Bruges som `?token=...` på established/terminated callback URLs.
Aktivér click-to-call
Standard extension (valgfri) Bruges som fallback i test og i senere call-knapper.
Template preset
Action URL template Pladsholdere: `{number}` (påkrævet), `{raw_number}`, `{extension}`, `{phone_ip}`, `{phone_username}`, `{phone_password}`.
Preview
-

##### Yealink URL Builder

Generér de præcise URL-strenge til telefonernes Action URL felter (Established + Terminated).

Brug Yealink variable values (fx `$call_id`, `$remote`, `$local`, `$active_user`). Ikke-dokumenterede placeholders som `$callid`/`$caller`/`$callee` bliver ofte ikke erstattet.
Hub base URL Eksempel: http://hub.local eller https://hub.bmcnetworks.dk
Shared secret token (valgfri) Hvis udfyldt, tilføjes `?token=...` automatisk.
Established URL
Terminated URL

##### Test opkald

Nummer
Extension (valgfri)
-

##### Notifikation Indstillinger

##### Email Skabeloner

Administrer system- og kundespecifikke email skabeloner

Kategori
Kunde

Navn | Emne | Kategori | Type | Sidst opdateret | Handlinger
--- | --- | --- | --- | --- | ---

##### Brugere

Opret og administrer brugere og deres grupper

Bruger | Email | Grupper | Status | Telefoni ext. | Telefoni IP | Telefoni bruger | Telefoni kode | Telefoni aktiv | Oprettet | Handlinger
--- | --- | --- | --- | --- | --- | --- | --- | --- | --- | ---

##### Grupper & Rettigheder

Opret grupper og tildel rettigheder

Gruppe | Rettigheder | Handlinger
--- | --- | ---

##### Tag Administration

Administrer tags der bruges på tværs af hele systemet

0
Total Tags
0
Workflow
0
Status
0
Category
0
Priority
0
Billing
Alle Workflow Status Category Priority Billing
Vis inaktive

##### Pipeline Stages

Administrer faser i salgspipelinen

Navn | Sortering | Standard % | Status | Handling
--- | --- | --- | --- | ---

##### Data Synkronisering

Synkroniser firmaer og kontakter fra vTiger og e-conomic

Sync bruger integration credentials fra miljøvariabler (.env) ved runtime.
Firmaer i Hub
-
Med vTiger ID
-
Med e-conomic ID
-

###### Sync fra vTiger

Hent firmaer og kontakter fra vTiger CRM. Matcher på CVR nummer eller firma navn.

Sidst synkroniseret: Aldrig

###### Sync fra e-conomic

Hent kunder fra e-conomic. Matcher kun på entydigt e-conomic kundenummer.

Sidst synkroniseret: Aldrig
CVR-søgning er slået fra midlertidigt for stabil drift.

###### Synkroniserings Log

Indlæser log...

##### AI System Prompts

Her kan du se de prompts der bruges til forskellige AI funktioner i systemet.

##### 📦 Modul System

Dynamisk feature loading - udvikl moduler isoleret fra core systemet

API ikke implementeret endnu

###### Quick Start

Opret nyt modul på 5 minutter:

    # 1. Opret modul
    python3 scripts/create_module.py invoice_scanner "Scan fakturaer"

    # 2. Kør migration
    docker-compose exec db psql -U bmc_hub -d bmc_hub \\
      -f app/modules/invoice_scanner/migrations/001_init.sql

    # 3. Enable modul (rediger module.json)
    "enabled": true

    # 4. Restart API
    docker-compose restart api

    # 5. Test
    curl http://localhost:8000/api/v1/invoice_scanner/health

###### Aktive Moduler

Indlæser moduler...

###### Safety First

- ✅ Moduler starter disabled
- ✅ READ_ONLY og DRY_RUN defaults
- ✅ Error isolation - crashes påvirker ikke core
- ✅ Graceful degradation

###### Database Isolering

- ✅ Table prefix pattern (fx `mymod_customers`)
- ✅ Separate migration tracking
- ✅ Helper functions til queries
- ✅ Core database uberørt

###### Modul Struktur

    app/modules/my_module/
    ├── module.json          # Metadata og konfiguration
    ├── README.md            # Dokumentation
    ├── backend/
    │   ├── __init__.py
    │   └── router.py        # FastAPI endpoints (API)
    ├── frontend/
    │   ├── __init__.py
    │   └── views.py         # HTML view routes
    ├── templates/
    │   └── index.html       # Jinja2 templates
    └── migrations/
        └── 001_init.sql     # Database migrations

###### Konfiguration

Modul-specifik konfiguration i `.env`:

    # Pattern: MODULES__{MODULE_NAME}__{KEY}
    MODULES__MY_MODULE__API_KEY=secret123
    MODULES__MY_MODULE__READ_ONLY=false
    MODULES__MY_MODULE__DRY_RUN=false

I kode:

    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", "true")

###### Eksempel: API Endpoint

    from fastapi import APIRouter, HTTPException
    from app.core.database import execute_query, execute_insert
    from app.core.config import get_module_config

    router = APIRouter()

    @router.post("/my_module/scan")
    async def scan_document(file_path: str):
        """Scan et dokument"""

        # Safety check
        read_only = get_module_config("my_module", "READ_ONLY", "true")
        if read_only == "true":
            return {"error": "READ_ONLY mode enabled"}

        # Process document
        result = process_file(file_path)

        # Gem i database (bemærk table prefix!)
        doc_id = execute_insert(
            "INSERT INTO mymod_documents (path, result) VALUES (%s, %s)",
            (file_path, result)
        )

        return {"success": True, "doc_id": doc_id}

###### Dokumentation

###### Quick Start

5 minutter guide til at komme i gang

`docs/MODULE_QUICKSTART.md`

###### Full Guide

Komplet reference (6000+ ord)

`docs/MODULE_SYSTEM.md`

###### Template

Working example modul

`app/modules/_template/`

###### ✅ DO

- Brug `create_module.py` CLI tool
- Brug table prefix konsistent
- Enable safety switches i development
- Test isoleret før enable i production
- Log med emoji prefix (🔄 ✅ ❌)
- Dokumenter API endpoints
- Version moduler semantisk

###### ❌ DON'T

- Skip table prefix
- Hardcode credentials
- Disable safety uden grund
- Tilgå andre modulers tabeller direkte
- Glem at køre migrations
- Commit `.env` files
- Enable direkte i production

##### Standard Dashboard

Dashboard vises altid fra roden af sitet via `/`. Vælg her hvilken side der skal åbnes som dit standard-dashboard.

Dashboard
Vælg et gyldigt dashboard fra listen.

##### System Indstillinger

##### Sags-typer

Administrer tilladte typer for sager

Indlæser...

##### Standardmoduler pr. sagstype

Vælg hvilke moduler der vises som standard for hver sagstype. Moduler med indhold vises altid.

Sagstype
Indlæser...

##### Opret Ny Bruger

Brugernavn *
Email *
Fulde Navn
Adgangskode *
Grupper
Indlæser grupper...
Superadmin
Aktiv

##### Tildel Grupper

Indlæser grupper...

##### Opret Ny Gruppe

Navn *
Beskrivelse

##### Rediger Rettigheder

Indlæser rettigheder...

##### Opret stage

Navn *
Beskrivelse
Sortering
Standard sandsynlighed (%)
Farve
Vundet
Tabt
Aktiv

##### Opret Nextcloud instans

Kunde
Base URL
Auth type
Brugernavn
Password

##### Rotér credentials

Nyt password

##### Slet audit‑log

Kunde
Slet events før dato
Dette kan ikke fortrydes.
{% endblock %} {% block extra_js %}

##### Opret Tag

Navn *
Type *
Beskrivelse Forklaring af hvad tagget gør eller betyder
Farve *
Hex color code (fx #0f4c75)
Ikon (valgfrit) Bootstrap Icons navn (fx: bi-star, bi-flag, bi-check-circle)
Aktiv

##### Opret Email Skabelon

Skabelon Navn * Internt navn til identifikation
Slug (Unik ID) * Bruges i koden (f.eks. 'nextcloud_welcome')
Kategori
Kunde (Valgfri)
Vælg en kunde for at lave en specifik override

Emne *
Indhold *
Beskrivelse

###### Tilgængelige Variabler

Klik på en variabel for at kopiere den til udklipsholderen.

###### Tilføj Variabel info

Definer hvilke variabler systemet understøtter for denne slug.

JSON format
{% endblock %}