BISO verwendet crunz als zentralen Task-Scheduler. Anstatt für jede wiederkehrende Aufgabe einen eigenen Cronjob einzurichten, wird nur ein einziger Cronjob benötigt. Der Scheduler prüft selbständig, welche Tasks fällig sind und führt diese aus.
Die Task-Dateien befinden sich im Verzeichnis webroot/backend/scheduler/tasks/. Einzelne Tasks
werden je nach Konfiguration (Config) oder Parameter (Admin > Parameter) bedingt aktiviert.
Auf dem Kundensystem muss ein einziger Crontab-Eintrag eingerichtet werden, der jede Minute läuft:
* * * * * www-data /usr/bin/php /var/www/biso/webroot/biso-cli scheduler run
Hinweis: Der Pfad
/var/www/biso/webroot/muss an die jeweilige Installation angepasst werden.
Der Scheduler delegiert an crunz, welches die einzelnen Task-Dateien einliest und nur die zum
jeweiligen Zeitpunkt fälligen Tasks ausführt. Überlappende Ausführungen werden durch
preventOverlapping() verhindert.
| Befehl | Beschreibung |
|---|---|
php biso-cli scheduler list |
Alle registrierten Tasks mit Zeitplan anzeigen |
php biso-cli scheduler run |
Fällige Tasks ausführen |
php biso-cli scheduler run --force |
Alle Tasks sofort ausführen (unabhängig vom Zeitplan) |
php biso-cli scheduler run --task=N |
Bestimmten Task nach Nummer ausführen |
Um einen neuen Scheduler-Task hinzuzufügen, wird eine neue PHP-Datei im Verzeichnis
webroot/backend/scheduler/tasks/ erstellt. Der Dateiname muss auf Tasks.php enden
(z.B. MeinNeuerTasks.php).
Grundstruktur einer Task-Datei:
<?php
use Crunz\Schedule;
require_once __DIR__ . '/../../../components/composer/kadenpartner/gaia/bootstrap.php';
$schedule = new Schedule();
// Bedingte Aktivierung (optional):
if (Param::get('mein_feature_aktiv', false)) {
$schedule->run(PHP_BINARY . ' ' . Config::get('rootdir') . '/biso-cli mein-command')
->daily()->at('08:00')
->description('Beschreibung des Tasks')
->preventOverlapping()
->appendOutputTo(Config::get('tmpdir') . '/mein-task.log');
}
return $schedule;
| Methode | Beschreibung |
|---|---|
->everyMinute() |
Jede Minute |
->hourly() |
Stündlich |
->hourlyAt('15') |
Stündlich um Minute 15 |
->daily() |
Täglich um Mitternacht |
->daily()->at('08:00') |
Täglich um 08:00 |
->weekly() |
Wöchentlich |
->weeklyOn(1, '13:30') |
Wöchentlich am Montag um 13:30 (0=Sonntag) |
->monthly() |
Monatlich |
->cron('30 8 * * Mon,Fri') |
Beliebiger Cron-Ausdruck |
->preventOverlapping() verwenden, um parallele Ausführungen desselben Tasks zu verhindern->appendOutputTo(Config::get('tmpdir') . '/taskname.log') verwenden, um Output in eine Log-Datei zu schreiben->description('...') setzen, damit der Task in scheduler list identifizierbar istJeder Task schreibt seine Ausgabe in eine eigene Log-Datei im Verzeichnis data/tmp/:
BISO versendet alle ausgehenden E-Mails zentral
über MailManager (bzw. die
PHPMailer-Subklasse BisoMailer)
und ist damit der einzige Ort, an dem die SMTP-Konfiguration wirkt. Wird
smtp_server leer gelassen, versendet BISO keine Mails (alle Aufrufe geben
wahr zurück, ohne eine Verbindung aufzubauen).
Die folgenden Konfigurationswerte werden in der config.php gesetzt.
Mit den fünf smtp_*-Schlüsseln wird die SMTP-Verbindung und der
Standard-Absender konfiguriert. Die Werte werden beim Erzeugen der
PHPMailer-Instanz einmalig gesetzt.
// config.php
// SMTP-Server (Hostname oder IP). Leer = kein Mailversand.
Config::set('smtp_server', 'mail.example.com');
// SMTP-Authentifizierung. Leer = offenes SMTP ohne Login.
Config::set('smtp_user', '');
Config::set('smtp_pass', '');
// Zusätzliche PHPMailer-Optionen. Beliebige PHPMailer-Properties
// können hier gesetzt werden (häufig verwendet: Port, SMTPAuth,
// SMTPSecure, SMTPOptions, SMTPDebug, ...).
Config::set('smtp_options', array(
'Port' => 25,
'SMTPAuth' => false,
'SMTPSecure' => false,
'SMTPOptions' => array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true,
),
),
));
// Standard-Absender-Adresse des Systems (From: bei intern
// ausgelösten Mails wie Termin-Einladungen, Cronjob-Benachrichtigungen,
// CMBB-TG-Fallabschluss-Mails).
Config::set('smtp_sender', 'admin@biso.ch');
| Schlüssel | Pflicht | Bedeutung |
|---|---|---|
smtp_server |
ja (für Versand) | SMTP-Server (Hostname oder IP). Leer deaktiviert den gesamten Mailversand. |
smtp_user |
bei Auth | SMTP-Benutzername. Leer bei offenem SMTP. |
smtp_pass |
bei Auth | SMTP-Passwort. |
smtp_options |
nein | Array mit beliebigen PHPMailer-Properties (z.B. Port, SMTPAuth, SMTPSecure, SMTPOptions). Jeder Schlüssel wird auf der Mailer-Instanz gesetzt. |
smtp_sender |
empfohlen | Standard-Absender-Adresse für vom System intern ausgelöste Mails (Cronjobs, Termin-Einladungen, kantonale Delegate). |
Einige authentifizierte SMTP-Server verweigern Mails, deren SMTP-Envelope-Absender
(MAIL FROM / PHPMailer-Property Sender) von der Mailbox des
SMTP-Authentifizierungs-Benutzers abweicht. Standardmässig verwendet BISO für
jede Mail die tatsächliche Benutzer-E-Mail-Adresse als Envelope. Mit den drei
folgenden Schlüsseln lässt sich der Envelope - und optional auch der sichtbare
From:-Header - durch eine fixe, systemeigene Adresse ersetzen.
Der Override wird zentral in BisoMailer::send() angewendet und wirkt damit für
jeden Mailaufruf (regulärer Versand via MailManager::sendEmail() und
direkte Aufrufer wie die VCalendar-Entities).
// config.php
// SMTP-Envelope (MAIL FROM / Sender) ersetzen. null/leer = kein
// Override (BISO verwendet die ursprüngliche Benutzer-Adresse).
Config::set('smtp_envelope_sender', 'noreply@example.com');
// Auch den sichtbaren "From:"-Header durch die Envelope-Adresse
// ersetzen. Der display name (FromName) des ursprünglichen Senders
// bleibt erhalten (Empfänger sieht z.B. "Max Muster <noreply@example.com>").
// false = "From:" bleibt die ursprüngliche Benutzer-Adresse.
Config::set('smtp_force_envelope_sender_as_from', true);
// Die ursprüngliche "From:"-Adresse als "Reply-To:" setzen, damit
// Antworten weiterhin den ursprünglichen Sender erreichen. Wirkt nur,
// wenn "From:" tatsächlich überschrieben wurde.
// false = kein Reply-To hinzufügen (Antworten gehen an die Envelope-Adresse).
Config::set('smtp_use_from_as_replyto', true);
| Schlüssel | Default | Wirkung |
|---|---|---|
smtp_envelope_sender |
null |
Fixe Envelope-Adresse. null deaktiviert alle drei Overrides. |
smtp_force_envelope_sender_as_from |
false |
true ersetzt zusätzlich den sichtbaren From:-Header. |
smtp_use_from_as_replyto |
false |
true fügt - nur bei tatsächlich überschriebenem From: - die ursprüngliche From:-Adresse als Reply-To: hinzu. |
Verhaltensmatrix:
smtp_envelope_sender |
smtp_force_envelope_sender_as_from |
smtp_use_from_as_replyto |
Resultat |
|---|---|---|---|
null |
egal | egal | Kein Override. From: und Envelope = ursprünglicher Sender. |
| gesetzt | false |
false |
Envelope = fix, From: = ursprünglicher Sender. |
| gesetzt | false |
true |
Envelope = fix, From: = ursprünglicher Sender (Reply-To redundant). |
| gesetzt | true |
false |
Envelope und From: = fix, Displayname erhalten. |
| gesetzt | true |
true und Original ≠ Envelope |
Envelope und From: = fix, ursprüngliche From:-Adresse als Reply-To:. |
| gesetzt | true |
true und Original = Envelope |
Envelope und From: = fix, kein selbst-Reply-To (Deduplizierung). |
Der Mailversand schreibt in den eigenen Logger mailer (siehe
webroot/config.orig.php). Für gezielte Fehlerdiagnose empfiehlt sich ein
eigenes Log-File:
// config.php:
Config::set('gaia.logging', [
'mailer' => [
'type' => 'file', // 'file' | 'console' | 'none'
'level' => 'DEBUG', // 'DEBUG' | 'INFO' | 'WARNING' | 'ERROR'
'console' => 'output',
'logfile' => Config::get('tmpdir') . '/biso-mailer.log',
],
]);
incamail.*).BISO unterstützt verschiedene SMS-Provider. Die Auswahl erfolgt über die Konfigurationsoption sms_driver (siehe unten). Per Default ist der historische Mail-to-SMS-Gateway-Versand aktiv (sms_driver = 'email'), womit bestehende Installationen ohne Anpassung weiterlaufen.
Hinweis für bestehende Installationen: Die neue Provider-Architektur ist rückwärtskompatibel. Wird
sms_drivernicht explizit gesetzt, bleibt das Verhalten identisch zur bisherigen Lösung (Mail-Gateway viasms_gateway_mail_domain/sms_gateway_mail_sender). Die Umstellung auf Swisscom REST-API, ASP SMS REST-API oder den Dummy-Treiber erfolgt durch Setzen der entsprechenden Konfigurationswerte.
| Treiber | Transport | Konfiguration erforderlich | Anwendungsfall |
|---|---|---|---|
email (Default) |
SMTP-Mail an <mobile>@<sms_gateway_mail_domain> |
sms_gateway_mail_domain, optional sms_gateway_mail_sender |
Bestehende Bundes-SMS-Gateway-Lösungen (z.B. smsc.admin.ch), Kunden mit Mail-to-SMS-Bridge. |
swisscom |
HTTPS POST an Swisscom Web-to-SMS REST-API | sms_swisscom_api_key (Pflicht), optional sms_swisscom_api_url, sms_swisscom_sender, sms_swisscom_max_msg_parts, sms_swisscom_validity_minutes |
Kantone mit Swisscom-Vertrag, die reine REST-Anbindung verlangen. |
aspsms |
HTTPS POST an ASP SMS JSON-API (/SendSimpleTextSMS) |
sms_aspsms_userkey (Pflicht), sms_aspsms_password (Pflicht), optional sms_aspsms_api_url, sms_aspsms_sender |
Kunden mit ASP-SMS-Vertrag (aspsms.ch), die den JSON-Endpoint von ASP nutzen. |
dummy |
Kein Versand, nur Log-Eintrag | – | Test- und DEV-Umgebungen. |
In der config.php:
Config::set('sms_driver', 'email'); // default, rückwärtskompatibel
// oder
Config::set('sms_driver', 'swisscom');
// oder
Config::set('sms_driver', 'aspsms');
// oder
Config::set('sms_driver', 'dummy'); // für Tests / Staging
Config::set('sms_gateway_mail_domain', 'smsc.admin.ch');
Config::set('sms_gateway_mail_sender', 'info@kunde.ch');
Config::set('sms_ausloeser_username', 'admin');
Config::set('sms_versand_iso_encoding', true); // Body nach ISO-8859-1 encoden
Bemerkungen:
sms_gateway_mail_sender = null → es wird die Berater-Email verwendet.sms_gateway_mail_sender = '' → kein Absender.swisscom) erwartet immer UTF-8. Der Encoding-Switch betrifft nur den email-Treiber.Implementation gemäss Swisscom Benutzerhandbuch "Web to SMS" (Stand September 2025). Der SMS-Versand erfolgt via HTTPS-POST an die Swisscom Web-to-SMS REST-Schnittstelle. Die Authentifizierung erfolgt per API-Key im HTTP-Header HTTP_X_APIKEY.
Mindestens erforderlich ist der API-Key (Pflichtfeld). Alle anderen Werte haben sinnvolle Defaults gemäss Swisscom-Spezifikation.
Config::set('sms_driver', 'swisscom');
// Pflicht: API-Key aus dem SMMS-Portal
Config::set('sms_swisscom_api_key', '<api-key-aus-smms-portal>');
// Optional mit Default-Werten:
Config::set('sms_swisscom_api_url', 'https://web2sms.swisscom.com/v8/api/rest/sms'); // default
Config::set('sms_swisscom_sender', '<originator: 1-16 numerisch oder 1-11 alphanumerisch>');
Config::set('sms_swisscom_max_msg_parts', 5); // 1-9, default 5
Config::set('sms_swisscom_validity_minutes', 720); // 1-10080, default 720 (12h)
| Konfigurationswert | Typ | Default | Bedeutung |
|---|---|---|---|
sms_swisscom_api_key |
string | – | Pflicht. API-Key aus dem SMMS-Portal. Wird im HTTP-Header HTTP_X_APIKEY übermittelt. |
sms_swisscom_api_url |
string | https://web2sms.swisscom.com/v8/api/rest/sms |
REST-Endpoint. In der Regel nicht ändern. |
sms_swisscom_sender |
string | – | Originator gemäss Swisscom-Vertrag. Wird im JSON-Feld smsorig übermittelt. |
sms_swisscom_max_msg_parts |
int | 5 |
Maximale Anzahl SMS-Splits (1-9). Bei Überschreiten wird der Text abgeschnitten. |
sms_swisscom_validity_minutes |
int | 720 |
Gültigkeitsdauer der SMS im SMSC in Minuten (1-10080). Nach Ablauf erfolgt ein Nicht-Zustellbericht. |
Pro SMS sendet BISO folgenden JSON-Body an Swisscom:
{
"recipient": "+41790001122",
"msg": "<SMS-Body, UTF-8, max. 1377 Zeichen>",
"smsorig": "<aus sms_swisscom_sender oder Berater-Absender>",
"maxMsgParts": 5,
"validity": 720
}
BISO normalisiert Empfänger-Nummern aus dem internen 0041…-Format ins internationale E.164-Format +41…, wie es die Swisscom-API verlangt.
2xx → Versand akzeptiert>= 400 → Exception mit HTTP-Code und gekürztem Response-BodyExceptionHinweis: Delivery Reports (Zustellbestätigungen) und SMS-Antworten werden von Swisscom asynchron an einen im SMMS-Portal konfigurierten Antwortkanal (URL oder E-Mail) zugestellt. BISO konsumiert diese in dieser Version nicht.
Implementation gemäss ASPSMS JSON-API. Der SMS-Versand erfolgt via HTTPS-POST an den Endpoint /SendSimpleTextSMS. Authentifizierung und alle SMS-Parameter werden als JSON-Body übermittelt (kein Query-String).
Erforderlich sind Userkey und Password (Pflicht). Der Originator (Sender) ist optional und fällt auf BISO zurück, falls nicht gesetzt.
Config::set('sms_driver', 'aspsms');
// Pflicht: API-Credentials aus dem ASP-Konto
Config::set('sms_aspsms_userkey', '<userkey-aus-aspsms-konto>');
Config::set('sms_aspsms_password', '<password-aus-aspsms-konto>');
// Optional mit Default-Werten:
Config::set('sms_aspsms_api_url', 'https://json.aspsms.com'); // Basis-URL; default
Config::set('sms_aspsms_sender', '<originator: numeric oder alphanumeric, max. 11 Zeichen>'); // default: 'BISO'
| Konfigurationswert | Typ | Default | Bedeutung |
|---|---|---|---|
sms_aspsms_userkey |
string | – | Pflicht. API-Userkey aus dem ASP-Konto. Wird als JSON-Feld UserName übermittelt. |
sms_aspsms_password |
string | – | Pflicht. API-Password aus dem ASP-Konto. Wird als JSON-Feld Password übermittelt. |
sms_aspsms_api_url |
string | https://json.aspsms.com |
Basis-URL der ASP JSON-API. An diese URL wird der Suffix /SendSimpleTextSMS angehängt. In der Regel nicht ändern (z.B. für Test-Mandanten möglich). |
sms_aspsms_sender |
string | BISO |
Originator des SMS (Absender-Kennung). Numeric oder alphanumeric, max. 11 Zeichen. Wird als JSON-Feld Originator übermittelt. |
Pro SMS sendet BISO folgenden POST-Request an ASP:
POST https://json.aspsms.com/SendSimpleTextSMS
Content-Type: application/json; charset=utf-8
{
"UserName": "...",
"Password": "...",
"Originator": "BISO",
"Recipients": ["+41790001122"],
"MessageText": "..."
}
| JSON-Feld | Typ | Wertebereich | Bedeutung |
|---|---|---|---|
UserName |
string | – | API-Userkey (Pflicht). |
Password |
string | – | API-Password (Pflicht). |
Originator |
string | numeric oder alphanumeric, max. 11 Zeichen | Absender-Kennung. Default: BISO. |
Recipients |
string[] | E.164-Format +41790001122 |
Empfänger-Mobilnummern als JSON-Array. BISO sendet je Nummer einen Request mit einem Array-Element und normalisiert Nummern aus Person::getMobileNumbers() ins E.164-Format +41…. |
MessageText |
string | UTF-8 | SMS-Body (UTF-8). |
BISO normalisiert Empfänger-Nummern aus dem internen 0041… oder 079…-Format ins E.164-Format +41790001122, wie es die ASP JSON-API-Beispiele zeigen.
Erfolg wird ausschliesslich über den HTTP-Status ermittelt. Der JSON-Body der Antwort ({"StatusCode": …, "StatusInfo": …}) wird nicht ausgewertet.
2xx → Versand akzeptiert>= 400 → Exception mit HTTP-Code und gekürztem Response-BodyExceptionConfig::set('sms_driver', 'dummy');
Keine zusätzliche Konfiguration erforderlich. Der Versand wird vollständig im Logger-Kanal sms protokolliert; es findet kein externer HTTP- oder Mail-Versand statt.
SMS-Erinnerungen sind ein Spezialfall innerhalb der SMS-Konfiguration: sie werden zeitgesteuert vor einem Termin an die Kunden-Mobilnummer versendet.
Folgende Parameter (Admin > Parameter) sind im Admin-Panel verfügbar:
| Parameter | Bezeichnung | Bedeutung |
|---|---|---|
sms_versand |
Mit Termin-SMS | Termin-SMS Modul ein/aus |
sms_notification_time |
Erinnerungs-Distanz in Stunden | Definiert die zeitliche Distanz vor dem Termin, in der eine SMS-Erinnerung ausgelöst wird |
sms_versand_manuell |
manuell Auslösen | SMS kann über die Termin-Oberfläche manuell ausgelöst werden |
sms_text_max_length |
SMS-Text Maximallänge | Frontend-Textarea-Max-Länge (z.B. 160 Zeichen für 1 SMS). Default deaktiviert. |
mit_sms_suppression |
SMS-Suppression aktivieren | Aktiviert die Suppression via Treffpunkt und Besprechungsart (Default: false). |
Die SMS-Texte selbst sind keine Parameter mehr, sondern Briefvorlagen vom Typ SMS (Werteliste > Briefvorlagen > Neu > SMS-Vorlage). Damit lassen sich pro Anwendungsfall mehrere Vorlagen führen und über Filterkriterien (Sprache, Alter, Kostenpflicht, Beratungsart, Fall-Typen, Regionalstellen) unterscheiden.
Jede SMS-Vorlage hat einen SMS-Typ (Spalte brief_typ, dieselbe wie bei Brief-Vorlagen):
| SMS-Typ | Verwendung |
|---|---|
sms_termin |
Termin-Erinnerung (Cron-Job und manueller Versand am BF-Termin) |
sms_workshop |
Erinnerung an Gruppentest-/Workshop-Termine |
sms_brief_info |
Info-SMS bei Brieferstellung (Checkbox im Dokument-Versand) |
Beim Versand wird die Vorlage gewählt, deren gesetzte Filter alle zutreffen. Treffen mehrere Vorlagen zu, gewinnt die spezifischste (die meisten zutreffenden Kriterien); es wird immer nur eine SMS verschickt. Haben zwei Vorlagen gleich viele Treffer, gewinnt die mit passendem Sprachfilter — so bekommt niemand einen Text in der falschen Sprache. Am besten kombiniert man überlappende Kriterien direkt in einer Vorlage (z. B. Regionalstelle und Sprache), dann ist die Auswahl eindeutig. Eine Vorlage ganz ohne Filter dient als Default. Gibt es keine passende Vorlage, wird keine SMS versendet und der Fehler im SMS-Log vermerkt.
Die Sprache wird nicht an der Vorlage eingestellt: eine SMS wird immer in der Sprache des
Empfängers gerendert (Beratungssprache des Kunden, ersatzweise die des Beraters, sonst
Deutsch) — also in derselben, gegen die auch der Sprachfilter prüft. Das wirkt sich auf
Wochentags- und Monatsnamen (%A, %B) und auf die Anrede-Platzhalter aus. Für einen eigenen
französischen Text legt man eine zweite Vorlage mit dem Sprachfilter "Kunde spricht
Französisch" an.
Als Platzhalter steht derselbe Smarty-Umfang wie bei Email-Vorlagen zur Verfügung
({$kunde.*}, {$berater.*}, {$termin.*}, {$institution.*}, {$treffpunkt.*},
{$beratungsfall.*}, {$anrede.*}, {$mentor.*}, bei Workshops zusätzlich
{$workshop_plan.*}). Im Formular fügen Auswahlboxen die Platzhalter an der Cursorposition
ein.
Die früheren Parameter
sms_versand_termin_vorlage[_fr],sms_versand_workshop_vorlage[_fr]undsms_versand_einladungsbrief_vorlage[_fr]wurden per DB-Migration in solche Vorlagen überführt. Die_fr-Variante wurde dabei zu einer Vorlage mit dem Sprachfilter "Kunde spricht Französisch", die deutsche zur filterlosen Default-Vorlage.Die alten
param-Zeilen bleiben vorerst als Backup in der Datenbank, werden aber nicht mehr gelesen und sind im Parameter-Formular nicht mehr sichtbar. Änderungen daran haben keine Wirkung — massgebend ist ausschliesslich die Vorlage.
Damit die Termin-SMS an den konfigurierten Transport gesendet werden, muss in regelmässigen Abständen
das CLI-Command biso-cli termin-sms --do-it ausgeführt werden.
Beispiel Linux Crontab:
0 * * * * www-data /usr/bin/php /var/www/biso/webroot/biso-cli termin-sms --do-it
Alternativ kann der SmsReminderTasks-Crunz-Scheduler aktiviert werden (siehe
webroot/backend/scheduler/tasks/SmsReminderTasks.php).
Dieser ruft denselben CLI-Befehl stündlich auf.
Für Testversand in DEV/Staging empfiehlt sich sms_driver = 'dummy' (siehe oben).
(siehe oben, Parameter mit_sms_suppression).
Für Termine, bei denen kein SMS-Versand erwünscht ist, kann die Suppression pro Treffpunkt oder Besprechungsart aktiviert werden.
Zusätzlich existieren zwei Tabellen-Felder, die das Verhalten steuern:
Treffpunkt.suppress_sms (boolean): SMS für Termine an diesem Treffpunkt unterdrücken.BfTerminBesprechungsart.suppress_sms (boolean): SMS für Termine mit dieser Besprechungsart unterdrücken.Die Suppression gilt sowohl für die automatische Termin-Erinnerung als auch für die manuelle
Auslösung über die Termin-Oberfläche. Im Brief-Info-SMS-Flow (sendBriefInfo) wird bei aktiver
Suppression der Versand still übersprungen.
SMS-Versand-Ereignisse werden im separaten Logger-Kanal sms protokolliert. Die Logs landen im konfigurierten sms-Logger:
// config.php (siehe system_config.php für Defaults):
Config::set('LOGGING', [
'sms' => [
'type' => 'file',
'level' => 'DEBUG',
'console' => 'output',
'logfile' => Config::get('tmpdir') . '/biso-sms.log',
],
]);
Nach Fallabschluss können Fälle mit einem Nachbefragungs-Email beliefert werden. Dazu sind folgende Voraussetzungen notwendig:
Die Nachbefragung wird via Cron-Job z.B. täglich angestossen:
$ php webroot/biso-cli send-nachbefragung
Folgende Konfigurationen sind für die Nachbefragung relevant:
Kunden-Spezialconfigs
Config::set('nachbefragung.ausnahme_termin_distanz_tage', 14): Ausnahme: Wenn der letzte Termin
x Tage vor dem Fallabschluss liegt, wird kein Versand ausgelöstDer Nachbefragungs-CLI-Job loggt seinen Output in ein separates Logging-Target:
SendNachbefragung
Die Logs können somit in ein eigenes Logfile oder auf die Konsole geleitet werden:
// config.php:
Config::set('LOGGING', [
'SendNachbefragung' => [
'type' => Logger::TYPE_CONSOLE,
'level' => Logger::DEBUG,
]
]);
Das Log-System setzt eine zweite Datenbank mit der Tabelle Log voraus.
CREATE DATABASE biso_log
WITH
OWNER = bisoadm
ENCODING = 'UTF8'
LC_COLLATE = 'de_CH.utf8'
LC_CTYPE = 'de_CH.utf8'
TABLESPACE = pg_default
CONNECTION LIMIT = -1
CREATE TABLE IF NOT EXISTS log
(
id serial NOT NULL,
logtime timestamp,
context text,
benutzer text,
action text,
record_id int,
record text ,
CONSTRAINT log_pkey PRIMARY KEY (id)
)
In der config.php muss man eine zweite DB-Connection log eintragen,
und das Log-System für Schreiben (LOG_STORE) und Löschen (LOG_DESTROY) aktivieren:
Config::set('gaia.db',[
'main' => [ /* .... */],
'log' => [
'driver' => 'pdo_pgsql',
'dbname' => 'biso_log',
'host' => 'db',
'port' => 5432,
'user' => 'xxxxxx',
'password' => 'yyyyy',
'schema' => 'biso'
],
])
Config::set('LOG_STORE', false);
Config::set('LOG_DESTROY', true);
Siehe Background-Task-System für die vollständige Dokumentation.
Die Task-Queue wird durch den biso-Scheduler ausgeführt. Die Anzahl parallel laufender Worker ist konfigurierbar:
// config.php:
Config::set('crunz.scheduler.queue.workers', 3);
So werden bis zu 3 Worker-Prozesse pro Minute gestartet. Läuft ein Worker noch, verhindert preventOverlapping() eine zweite Instanz desselben Workers.
BISO stellt eine anonyme HTTP-Route zur Verfügung, die von Monitoring-Tools (z.B. Docker, Kubernetes, Prometheus-Blackbox-Exporter, Nagios, Uptime-Kuma) periodisch aufgerufen werden kann, um die Verfügbarkeit der Applikation zu prüfen.
GET /backend/status
GET erlaubt. Andere HTTP-Methoden liefern kein Resultat.text/plain; charset=utf-8 mit Cache-Control: no-store.Die Route führt zwei Prüfungen gegen die in config.php unter gaia.db.main konfigurierte
Datenbankverbindung aus:
SELECT count(*) FROM param kann ausgeführt werden.Schlagen eine oder beide Prüfungen fehl, liefert die Route HTTP 503 Service Unavailable.
Bei erfolgreicher Prüfung (HTTP 200 OK):
BISO-Status: OK
DB connection to <dbname>: OK
Dabei ist <dbname> der in config.php konfigurierte dbname der main-Verbindung
(z.B. bisodev in der lokalen Dev-Umgebung).
Bei Fehler (HTTP 503 Service Unavailable) wird OK durch ERROR ersetzt:
BISO-Status: ERROR
DB connection to <dbname>: ERROR
Die mitgelieferte docker-compose.yml definiert für die Services web85 und web83 einen
healthcheck, der die Route alle 10 Sekunden aufruft:
healthcheck:
test: ["CMD-SHELL", "curl -fsS http://localhost/backend/status || exit 1"]
interval: 10s
timeout: 5s
retries: 3
start_period: 30s
Der Status eines Containers lässt sich dann z.B. so abfragen:
docker compose ps
docker inspect --format '{{json .State.Health}}' <container>
Externe Tools sprechen die Route über die öffentliche URL der BISO-Installation an, also
z.B. https://biso.example.com/backend/status. Erwartet wird HTTP 200; jeder andere
Statuscode (insbesondere 503) signalisiert "nicht verfügbar".
Kurze Tests von der Kommandozeile:
# Status und Body inspizieren
curl -i https://biso.example.com/backend/status
# Nur den HTTP-Statuscode auswerten
curl -fsS -o /dev/null -w "%{http_code}\n" https://biso.example.com/backend/status
Hinweis: Hinter einem Reverse-Proxy / Loadbalancer ist sicherzustellen, dass diese Route nicht durch Auth-Layer (z.B. OIDC-Redirect) blockiert wird. Der Proxy muss
GET /backend/statusohne Auth-Requirement an den BISO-Web-Container weiterleiten.
Die Konfiguration des OIDC-Logins (Apache mod_auth_openidc, oidc.auto_provision,
oidc.sync_existing, oidc.userinfo_endpoint, oidc.roles_claim, Log-Kanal)
ist beschrieben unter
OIDC Auto-Provisionierung. Die kundenspezifische Genfer
Konfiguration (GINA, ID-Mapping oidc.ge.*) siehe
Kanton Genf: OIDC/GINA-Benutzerprovisionierung.