Runtime Overview

This page summarizes current behavior. Canonical ownership of module layout and runtime contracts is in Project Layout and Container Runtime Contract.

Co je implementovano

  • Python worker bezici v Docker kontejneru modulu ab-ticket-bot-jobs.
  • Samostatny docs packaging modul ab-ticket-bot-docs, ktery servuje root MkDocs dokumentaci.
  • Scheduler spousteny podle AUTO_SHIFT_LOCK_CRON (5-field cron).
  • Polling WhatsApp Adapter z konkretni WhatsApp skupiny.
  • Parsovani prefixu:
  • ab<cislo> na zacatku zpravy = zalozeni/aktualizace Jira ticketu
  • x<cislo> na zacatku zpravy = uzavre navazovani jen pro autora teto zpravy a dane ab<cislo>
  • x (bez cisla) na zacatku zpravy = uzavre aktualne aktivni ab<cislo> kontext autora
  • ? na zacatku zpravy = bot posle do skupiny kratkou napovedu k pouziti
  • nova explicitni zprava ab<cislo> od stejneho autora navazovani znovu otevre
  • Pokud od stejneho autora po ab<cislo> prijde zprava bez prefixu, bot ji bere jako pokracovani posledniho aktivniho ab<cislo> a ulozi do stejneho ticketu.
  • Zpravy se zpracovavaji od vsech clenu sledovane skupiny (krome fromMe odeslani bota).
  • Pokud je zprava uspesne zpracovana (ab create/update, x close nebo ? help), bot prida reakci 🤖 na puvodni zpravu ve WhatsApp.
  • Zakladani ticketu do Jira projektu (JIRA_PROJECT_KEY) + doplnovani description. Zapis do description ma format [YYYY-MM-DD HH:mm] <text-zpravy>.
  • Pri chybejicim lokalnim mapovani bot nejdriv vyhleda existujici Jira issue (project + issue type AB Test + exact summary) a napoji mapovani na nalezeny issue key.
  • Deduplikace je 2-vrstvova:
  • podle message_id
  • podle fingerprintu zpravy (author + text + casovy bucket)
  • Stav deduplikace se uklada prubezne po kazde zpracovane zprave, aby restart nezpusobil opakovane zpracovani.
  • Zpetna kontrola historie za poslednich AUTO_SHIFT_LOCK_HISTORY_DAYS pri startu.
  • Ukladani mapovani ab<cislo> -> Jira issue key do CSV.
  • Ukladani runtime stavu (zpracovane message ID + posledni poll timestamp) do CSV souboru.
  • Rotace logu po 100 MB.

Konfigurace Jobs Modulu

Standard je:

  • ab-ticket-bot-jobs/.env.example je commitovany priklad konfigurace
  • secrets/local/ab-ticket-bot-jobs.env a secrets/prod/ab-ticket-bot-jobs.env jsou zdroj pravdy
  • ab-ticket-bot-jobs/.env.local a ab-ticket-bot-jobs/.env.server jsou materializovane runtime artefakty

Povinne promenne:

  • AUTO_SHIFT_LOCK_WHATSAPP_ADAPTER_BASE_URL
  • AUTO_SHIFT_LOCK_WHATSAPP_ADAPTER_API_TOKEN
  • AUTO_SHIFT_LOCK_WHATSAPP_ADAPTER_SESSION
  • AUTO_SHIFT_LOCK_NOTIFY_CONVERSATION_ID
  • JIRA_EMAIL
  • JIRA_API_TOKEN

Aktualni cilove conversation ID:

  • local secret secrets/local/ab-ticket-bot-jobs.env: AUTO_SHIFT_LOCK_NOTIFY_CONVERSATION_ID=grp_01ebfab2a215
  • prod secret secrets/prod/ab-ticket-bot-jobs.env: AUTO_SHIFT_LOCK_NOTIFY_CONVERSATION_ID=grp_b6f05648107a

Doporucene (maji default):

  • JIRA_BASE_URL (default https://internet-handel.atlassian.net)
  • JIRA_PROJECT_KEY (default ESH)
  • AUTO_SHIFT_LOCK_DRY_RUN (default 1)

Volitelne promenne:

  • AUTO_SHIFT_LOCK_CRON (default * * * * *)
  • AUTO_SHIFT_LOCK_TIMEZONE (default Europe/Prague)
  • AUTO_SHIFT_LOCK_MODULE_NAME (default ab-ticket-bot-jobs)
  • AUTO_SHIFT_LOCK_HISTORY_DAYS (default 10)
  • AUTO_SHIFT_LOCK_FETCH_LIMIT (default 200)
  • AUTO_SHIFT_LOCK_JIRA_LABEL (default AB_testy)
  • AUTO_SHIFT_LOCK_MAPPING_CSV (default /app/data/ticeket-mapping.csv)
  • AUTO_SHIFT_LOCK_STATE_FILE (default /app/data/ab_ticket_state.csv)
  • AUTO_SHIFT_LOCK_AUTHOR_CONTEXT_CSV (default /app/data/author-conversation.csv)
  • JIRA_CLOUD_ID (pro scoped tokeny)
  • JIRA_ISSUE_TYPE (default AB Test)

AUTO_SHIFT_LOCK_STATE_FILE funguje jako prefix; bot z nej odvozi vice CSV souboru (-meta.csv, -processed-message-ids.csv, -processed-fingerprints.csv, -last-ab-by-author.csv).

Migracni poznamka:

  • worker zatim akceptuje i legacy WAHA env nazvy (AUTO_SHIFT_LOCK_WAHA_*, AUTO_SHIFT_LOCK_NOTIFY_GROUP_CHAT_ID), ale canonical konfigurace je WhatsApp Adapter varianta uvedena vyse

AUTO_SHIFT_LOCK_DRY_RUN:

  • 1 = zablokuje pouze zalozeni noveho Jira ticketu (create). Ostatni behavior bezi: update existujicich ticketu, WhatsApp reakce 🤖, lokalni persistence.
  • 0 = create ticketu je povolen.

Skripty

  • Root orchestration: scripts/start.sh, scripts/stop.sh, scripts/deploy.sh
  • Jobs module: ab-ticket-bot-jobs/scripts/ab-ticket-bot-jobs-start.sh
  • Docs module: ab-ticket-bot-docs/scripts/ab-ticket-bot-docs-start.sh

Primy jobs compose prikaz:

docker compose --env-file ab-ticket-bot-jobs/.env.local \
  -f ab-ticket-bot-jobs/docker-compose.yml \
  --project-name ab-ticket-bot-jobs \
  up -d --build

Docs Modul

Docs modul servuje root docs/ a root mkdocs.yml pres zabaleny staticky site image.

  • lokalni bind default: 127.0.0.1:18081
  • produkcni URL: https://ab-ticket-bot-docs.mathbox.90.cz/
  • health endpoint: GET /healthz
  • produkcni TLS a public routing zajistuje HAProxy na serveru mathbox.90.cz
  • canonical docs source zustava v repo rootu; modul si pred buildem synchronizuje build-context/

Remote Deploy

Remote deploy pouziva modulove adresare pod:

  • /home/agent/docker_deployments/ab-ticket-bot/ab-ticket-bot-jobs
  • /home/agent/docker_deployments/ab-ticket-bot/ab-ticket-bot-docs

Na server se neprenasi root repository; kazdy modul se deployuje samostatne.

Perzistence

  • Jobs logy (host): ab-ticket-bot-jobs/logs
  • Jobs data (host): ab-ticket-bot-jobs/data

Soubory:

  • ab-ticket-bot-jobs/data/ticeket-mapping.csv
  • ab-ticket-bot-jobs/data/ab_ticket_state-meta.csv
  • ab-ticket-bot-jobs/data/ab_ticket_state-processed-message-ids.csv
  • ab-ticket-bot-jobs/data/ab_ticket_state-processed-fingerprints.csv
  • ab-ticket-bot-jobs/data/ab_ticket_state-last-ab-by-author.csv
  • ab-ticket-bot-jobs/data/author-conversation.csv

CSV schema:

  • ticeket-mapping.csv: ab_id,issue_key,closed
  • author-conversation.csv: author,active_ab_id,closed
  • active_ab_id = posledni explicitne aktivovane ab<cislo> pro autora
  • closed=1 = autor ma navazovani uzavrene a zpravy bez prefixu se ignoruji
  • ab_ticket_state-meta.csv: key,value (aktualne hlavne last_poll_timestamp)
  • ab_ticket_state-processed-message-ids.csv: message_id,timestamp
  • ab_ticket_state-processed-fingerprints.csv: fingerprint,timestamp
  • ab_ticket_state-last-ab-by-author.csv: author,ab_id

Datovy model (tabulka)

Soubor Sloupce Ucel
ticeket-mapping.csv ab_id,issue_key,closed Persistuje vazbu lokalniho ab<cislo> na Jira issue key.
author-conversation.csv author,active_ab_id,closed Udrzuje aktivni AB kontext na autora a stav navazovani po x.
ab_ticket_state-meta.csv key,value Systemovy checkpoint (last_poll_timestamp) pro dalsi polling.
ab_ticket_state-processed-message-ids.csv message_id,timestamp Deduplikace podle message_id napric restarty.
ab_ticket_state-processed-fingerprints.csv fingerprint,timestamp Deduplikace stejnych textu v kratkem casovem bucketu.
ab_ticket_state-last-ab-by-author.csv author,ab_id Interni fallback kontext autora.

Datovy model 1: Mapping + autor kontext

Datovy model mappingu a autor kontextu

Datovy model 2: Runtime checkpoint + deduplikace

Datovy model runtime stavu a deduplikace

Tok a vztahy dat:

  1. Na startu runu bot nacte last_poll_timestamp z ab_ticket_state-meta.csv a z toho urci casove okno, odkud ma cist zpravy.
  2. Pro kazdou zpravu nejdriv kontroluje ab_ticket_state-processed-message-ids.csv (presna deduplikace podle message_id).
  3. Pokud message_id jeste neexistuje, kontroluje ab_ticket_state-processed-fingerprints.csv (deduplikace stejnych textu od stejneho autora v kratkem casovem bucketu).
  4. Po uspesnem zpracovani zpravy zapise oba zaznamy (message_id i fingerprint) a stav ulozi hned na disk, aby restart neopakoval zpracovani.
  5. Na konci runu aktualizuje last_poll_timestamp v ab_ticket_state-meta.csv a zaroven proreze stare deduplikacni zaznamy podle AUTO_SHIFT_LOCK_HISTORY_DAYS.
  6. ab_ticket_state-last-ab-by-author.csv je interni pomocny stav; hlavni navazovani konverzace autoru je vedeno v author-conversation.csv.

Prakticky efekt:

  1. meta urcuje od kdy cist.
  2. processed-message-ids brani presnym duplicitam.
  3. processed-fingerprints brani duplicitam se zmenenym message_id.

Mapovani host/container:

  • host ab-ticket-bot-jobs/data je namountovano do containeru jako /app/data
  • bot uvnitr zapisuje do:
  • /app/data/ticeket-mapping.csv
  • /app/data/ab_ticket_state-meta.csv
  • /app/data/ab_ticket_state-processed-message-ids.csv
  • /app/data/ab_ticket_state-processed-fingerprints.csv
  • /app/data/ab_ticket_state-last-ab-by-author.csv
  • /app/data/author-conversation.csv

Logy

  • V kontejneru: /app/logs
  • Lokalni jobs mount: ab-ticket-bot-jobs/logs
  • Aktivni jobs log: ab-ticket-bot-jobs/logs/ab-ticket-bot-jobs.log
  • Rotace: ab-ticket-bot-jobs.0001.log, ab-ticket-bot-jobs.0002.log, ...