- Implemented user notification preferences table for managing default notification settings. - Created sag_reminders table to define reminder rules with various trigger types and recipient configurations. - Developed sag_reminder_queue for processing reminder events triggered by status changes or scheduled times. - Added sag_reminder_logs to track reminder notifications and user interactions. - Introduced frontend notification system using Bootstrap 5 Toast for displaying reminders. - Created email template for sending reminders with case details and action links. - Implemented rate limiting for user notifications to prevent spamming. - Added triggers and functions for automatic updates and reminder processing. |
||
|---|---|---|
| .. | ||
| backend | ||
| frontend | ||
| migrations | ||
| templates | ||
| module.json | ||
| README.md | ||
Webshop Module
Dette er template strukturen for nye BMC Hub moduler.
Struktur
webshop/
├── 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 webshop "My Module Description"
Database Tables
Alle tabeller SKAL bruge table_prefix fra module.json:
-- Hvis table_prefix = "webshop_"
CREATE TABLE webshop_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:
CREATE TABLE webshop_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_webshop_customer
BEFORE INSERT OR UPDATE OF name
ON webshop_customers
FOR EACH ROW
EXECUTE FUNCTION auto_link_webshop_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:
CREATE TABLE webshop_orders (
id SERIAL PRIMARY KEY,
customer_id INTEGER REFERENCES customers(id) -- Direkte link
);
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("webshop", "API_KEY")
read_only = get_module_config("webshop", "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 webshop_customers WHERE active = %s",
(True,)
)
# Insert
customer_id = execute_insert(
"INSERT INTO webshop_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("webshop", migration_sql)
Enable/Disable
# Enable via API
curl -X POST http://localhost:8000/api/v1/modules/webshop/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_webshop():
# Test bruger samme database helpers
result = execute_query("SELECT 1 as test")
assert result[0]["test"] == 1
Best Practices
- Database isolering: Brug ALTID
table_prefixfra module.json - Safety switches: Tilføj
READ_ONLYogDRY_RUNflags - Error handling: Log fejl, raise HTTPException med status codes
- Dependencies: Deklarer i
module.jsonhvis du bruger andre moduler - Migrations: Nummer sekventielt (001, 002, 003...)
- Documentation: Opdater README.md med API endpoints og use cases