Shift Planner Jobs
Scheduler modul pro automaticke vyhodnoceni zamykani smen.
Co dela
- scheduler spousti job
auto_shift_lock.pypodleAUTO_SHIFT_LOCK_CRONvconf/shift-planner-jobs.conf - job vyhodnocuje interval
dnes .. dnes+N dnipro vsechny sklady (AUTO_SHIFT_LOCK_LOOKAHEAD_DAYSvconf/shift-planner-jobs.conf, default30) - auto-lock je povolen pouze tam, kde
sp-shift-lock-YYYY-MM.csvobsahujeauto_shift_lock_enabled = 1(chybne/chybejici zaznamy se berou jako1) - "cerveny den" odpovida UI logice:
planned_hours > expected_hours + 100 - pokud selze nacitani vstupnich dat (API/DB), cele kolo vyhodnoceni se preskoci
(
AUTO_SHIFT_LOCK_ROUND_SKIPPED) - pokud je
expected_hours <= 0, den se nikdy nevyhodnoti jako kandidat na lock (AUTO_SHIFT_LOCK_SKIP reason=expected_hours_non_positive) - v DRY-RUN modu (
AUTO_SHIFT_LOCK_DRY_RUN=1) nic nezamyka, pouze loguje kandidaty na zamknuti (AUTO_SHIFT_LOCK_DRY_RUN) - v LIVE modu (
AUTO_SHIFT_LOCK_DRY_RUN=0) opravdu vola lock API a zamyka smeny (AUTO_SHIFT_LOCK_LIVE) - po uspesnem LIVE zamceni umi poslat WAHA notifikaci do skupiny
(
AUTO_SHIFT_LOCK_NOTIFY_*+AUTO_SHIFT_LOCK_WAHA_*vconf/shift-planner-jobs.conf) - bezi v Docker kontejneru pres
supercronic - script pise pouze do
stdout entrypoint.shsmeruje stdout/stderr hlavniho procesu kontejneru doLOG_FILE- healthcheck je heartbeat-based, ne HTTP endpoint
- runtime conf mount:
/home/agent/shift-planner/conf -> /app/conf - produkcni
shift-planner-jobs.confv/home/agent/shift-planner/confje server-managed runtime konfigurace; deploy ji neprepisuje planned_hoursAPI pouzivaPLANNED_HOURS_METHOD=POSTa bere Basic auth zPLANNED_HOURS_AUTHvconf/shift-planner-jobs.confexpected_hoursashift locksz CME DB vyzaduji/app/data/cme-db.ini
Scheduler
AUTO_SHIFT_LOCK_CRONvconf/shift-planner-jobs.conf- vychozi hodnota
* * * * *-> beh kazdou minutu
Log file
- default:
/app/logs/shift-planner-jobs.log - v produkci pres mount:
/home/agent/shift-planner/logs/shift-planner-jobs.log - v DEV:
../target/logs/shift-planner-jobs.log - rotace po
100 MBnashift-planner-jobs.0001.log,shift-planner-jobs.0002.log, ... - dulezite log radky:
AUTO_SHIFT_LOCK_ROUND_SKIPPED ...-> kolo vyhodnoceni bylo preskoceno kvuli chybe nacitani datAUTO_SHIFT_LOCK_SKIP reason=expected_hours_non_positive ...-> den ma nulovy/neplatny expected a nebude zamknutAUTO_SHIFT_LOCK_DRY_RUN ...-> smeny, ktere by se zamklyAUTO_SHIFT_LOCK_NOTIFY_DRY_RUN ...-> text WAHA notifikace, ktery by se v live poslalAUTO_SHIFT_LOCK_LIVE ...-> smeny, ktere byly realne zamcenyAUTO_SHIFT_LOCK_LIVE_FAILED ...-> pokus o zamceni selhalAUTO_SHIFT_LOCK_NOTIFY_SENT ...-> WAHA notifikace byla odeslanaAUTO_SHIFT_LOCK_NOTIFY_FAILED ...-> WAHA notifikaci se nepodarilo odeslatAUTO_SHIFT_LOCK_RESULT ...-> souhrn behu
Monitoring
- kontejner ma
restart: unless-stopped - compose healthcheck cte heartbeat stav ze souboru
HEALTH_STATUS_FILE - scheduler zapise bootstrap health stav hned pri startu kontejneru, aby sluzba nezustavala dlouho ve stavu
starting - nove kolo scheduleru zapise heartbeat hned na zacatku behu (
status=running) - healthy healthcheck znamena, ze scheduler stale zije a heartbeat neni zastaraly
- interní status
okznamena, ze posledni beh probehl bez provozni chyby - interní status
degradedznamena, ze scheduler bezi, ale posledni kolo bylo preskoceno kvuli zavislosti nebo konfiguraci - interní status
runningznamena, ze kolo prave bezi - unhealthy healthcheck znamena typicky:
- fatalni pád jobu (
fatal_error) - nevalidni chybejici heartbeat soubor
- zastaraly heartbeat
- vychozi
HEALTH_MAX_AGE_SECONDSje3600; pokud pouzijete jeste ridsi cron, upravte ho vys
WAHA notifikace po zamceni
Konfigurace je v conf/shift-planner-jobs.conf:
AUTO_SHIFT_LOCK_WAHA_BASE_URL- WAHA base URL (napr.https://waha.mathbox.90.cz)AUTO_SHIFT_LOCK_WAHA_API_KEY- API key pro WAHA (X-Api-Key)AUTO_SHIFT_LOCK_WAHA_SESSION- WAHA session (default)AUTO_SHIFT_LOCK_NOTIFY_GROUP_CHAT_ID- cilova WhatsApp skupina (...@g.us)AUTO_SHIFT_LOCK_NOTIFY_TEMPLATE- text zpravyAUTO_SHIFT_LOCK_NOTIFY_TIMEOUT_SECONDS- HTTP timeout
Poznamky:
- v LIVE rezimu bez
AUTO_SHIFT_LOCK_NOTIFY_GROUP_CHAT_IDse zamykani provede, ale notifikace se neposle (AUTO_SHIFT_LOCK_NOTIFY_DISABLED reason=missing_config). - v pouzite WAHA edici nelze API key vytvaret v dashboardu; klic se nastavuje mimo dashboard.
Vychozi sablona:
Směny na den {} ve skladu {} byly zamčeny, protože počet hodin registrovaných brigádníků {} přesáhl o 100 počet hodin, které na směnu odhadujeme {}.
Placeholdery pro AUTO_SHIFT_LOCK_NOTIFY_TEMPLATE:
{} #1= business date (YYYY-MM-DD){} #2= warehouse name{} #3= planned (registered) hours{} #4= expected hours- named placeholders:
{shift},{business_date},{warehouse_name},{warehouse_id},{cme_id},{planovac_den_id},{planned_hours},{expected_hours},{threshold_hours},{buffer_hours}
Lokalni spusteni
./scripts/start-shift-planner-jobs.sh
Explicitne dry-run:
./scripts/start-shift-planner-jobs.sh --dry-run
Live rezim (ostry beh):
./scripts/start-shift-planner-jobs.sh --live
Okamzite testovaci spusteni:
./scripts/run-shift-planner-jobs-now.sh
Okamzite ostre spusteni:
./scripts/run-shift-planner-jobs-now.sh --live
Stop:
./scripts/stop-shift-planner-jobs.sh
Po spusteni scheduleru muzete log sledovat napr.:
tail -f target/logs/shift-planner-jobs.log
WAHA test (group id + send)
Test utility script:
python shift-planner-jobs/jobs/nudge/waha_group_test.py --help
List all WhatsApp groups for session default:
python shift-planner-jobs/jobs/nudge/waha_group_test.py groups
List groups filtered by name:
python shift-planner-jobs/jobs/nudge/waha_group_test.py groups --name "Sklad"
Send test message by exact chatId:
python shift-planner-jobs/jobs/nudge/waha_group_test.py send \
--chat-id "1203630XXXXXXXXX@g.us" \
--text "Test zprava ze shift-planner-jobs"
Send test message by group name (script first resolves group id):
python shift-planner-jobs/jobs/nudge/waha_group_test.py send \
--group-name "Sklad" \
--text "Test zprava ze shift-planner-jobs"
Send test message with user mention:
python shift-planner-jobs/jobs/nudge/waha_group_test.py send \
--group-name "Testovaci" \
--text "Ahoj @420123456789" \
--mention "+420123456789"
If WAHA requires auth, set API key:
export WAHA_API_KEY="..."
Script defaultne pouziva serverovou WAHA URL:
python shift-planner-jobs/jobs/nudge/waha_group_test.py \
--base-url "https://waha.mathbox.90.cz" \
groups
Troubleshooting
AUTO_SHIFT_LOCK_NOTIFY_DISABLED reason=missing_config missing_fields=group_chat_idznamena chybejiciAUTO_SHIFT_LOCK_NOTIFY_GROUP_CHAT_IDvconf/shift-planner-jobs.conf.- Pokud je
AUTO_SHIFT_LOCK_LIVE action=locka neniAUTO_SHIFT_LOCK_NOTIFY_SENT, hledejAUTO_SHIFT_LOCK_NOTIFY_FAILED(WAHA auth, session, URL, timeout). - Pokud je
candidate_count=0, smerodatny je souhrn vAUTO_SHIFT_LOCK_SCAN_FINISHED(over_capacity_slots,already_locked_slots,lock_candidates,expected_hours_non_positive_slots). - Pokud je
AUTO_SHIFT_LOCK_ROUND_SKIPPED, v tom behu se nic nezamyka (ochrana proti lockum s nekompletnimi daty).
Shift lock API test
Lock/unlock shift via API (uses X-API-KEY; Basic auth optional):
./shift-planner-jobs/jobs/nudge/lock_shift.py 8878 true --x-api-key "xxx"
./shift-planner-jobs/jobs/nudge/lock_shift.py 8878 false --x-api-key "xxx"
Print outgoing HTTP request (headers + body):
./shift-planner-jobs/jobs/nudge/lock_shift.py 8878 true --x-api-key "xxx" --debug-request