bmc_hub/app/modules/_template/README.md
Christian 38fa3b6c0a feat: Add subscriptions lock feature to customers
- Added a new column `subscriptions_locked` to the `customers` table to manage subscription access.
- Implemented a script to create new modules from a template, including updates to various files (module.json, README.md, router.py, views.py, and migration SQL).
- Developed a script to import BMC Office subscriptions from an Excel file into the database, including error handling and statistics reporting.
- Created a script to lookup and update missing CVR numbers using the CVR.dk API.
- Implemented a script to relink Hub customers to e-conomic customer numbers based on name matching.
- Developed scripts to sync CVR numbers from Simply-CRM and vTiger to the local customers database.
2025-12-13 12:06:28 +01:00

3.0 KiB

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

python scripts/create_module.py my_module "My Module Description"

Database Tables

Alle tabeller SKAL bruge table_prefix fra module.json:

-- Hvis table_prefix = "mymod_"
CREATE TABLE mymod_customers (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255)
);

Dette sikrer at moduler ikke kolliderer med core eller andre moduler.

Konfiguration

Modul-specifikke miljøvariable følger mønsteret:

MODULES__MY_MODULE__API_KEY=secret123
MODULES__MY_MODULE__READ_ONLY=true

Tilgå 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", default="true") == "true"

Database Queries

Brug ALTID helper functions fra app.core.database:

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:

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

# 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

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