·
7 min čtení
·
Napsal Tomáš Mikeš
Provizní výpočty v MLM: jak je modelovat, aby byly auditovatelné
Pro JUST jsme nahrazovali legacy systém s komplexními provizemi. Historie přepočtů, versioned pravidla, rekonstrukce výpočtu po letech — tady je, jak se k tomu dá přistoupit, aby to přežilo prvního auditora.
Multi-level marketing provize jsou speciální disciplína. Prodejce A přivede prodejce B, B dělá obrat 50 000 Kč měsíčně. A dostane provizi z B obratu — kolik, záleží na tom, v jaké úrovni A je, jakou kvalifikaci měla v daném měsíci, jestli dosáhla bonusového objemu, jestli má odblokované override bonusy od prodejců C a D, kteří jsou pod B.
Pro JUST jsme nahrazovali systém, který tyhle výpočty dělal 15 let. Zákon č. 1 při replikaci: musí to dát stejné číslo, i když to vedle sebe spustíš oběma systémům na stejná data. Zákon č. 2: musíš umět za 3 roky vysvětlit, proč prodejce dostal 3 240 Kč místo 3 470 Kč.
Tady je, jak jsme to strukturovali.
1. Provizní pravidla jako data, ne jako kód
Prvotní impuls vývojáře: „napíšu funkci calculateCommission(seller, month) s if/else podle úrovní.“ To funguje 6 měsíců. Pak přijde byznys s novým bonusem, a upravíš funkci. Pak změna, a další. Za 3 roky máš 6 verzí funkce a žádnou nedokážeš oddělit podle měsíce, kdy platila.
Správně: pravidla jako řádky v DB tabulce s validFrom / validTo. Struktura:
CommissionRule {
id: UUID
name: 'Tier 2 Base Commission'
validFrom: Date
validTo: Date | null
condition: JSON // když platí
calculation: JSON // co se počítá
priority: Integer
}Při výpočtu pro měsíc 2023-05 se načtou pravidla, kde validFrom <= '2023-05-01' AND (validTo IS NULL OR validTo > '2023-05-31'). Změna business logiky = přidání nového řádku, ne edit kódu. Historická data se přepočítávají pravidly, která platila v daném období.
2. Outcomy výpočtu jsou immutable
Jakmile se provize jednou spočítá a prodejce ji dostane, už se nepřepisuje. I když se najde bug v pravidlech. Místo přepisu se zaznamená korekce.
Schéma:
CommissionOutcome {
id: UUID
sellerId
month: '2023-05'
amount: 3240
ruleSnapshot: JSON // všechna použitá pravidla, copy
inputSnapshot: JSON // obraty, strukturu sítě v okamžiku výpočtu
calculatedAt: DateTime
status: 'final' | 'corrected' | 'superseded'
}
CommissionCorrection {
id: UUID
originalOutcomeId
correctionAmount: 230 // +/-
reason: string
approvedBy: UserId
approvedAt: DateTime
}Výplata prodejci = original + všechny corrections. Finanční systém má immutable audit trail. Když v roce 2026 přijde auditor a ptá se, „proč tahle provize z 2023-05 byla 3 240 Kč“, dokážeš to replikovat — snapshot pravidel i inputů je tam navždy.
3. Test scenarios jako smlouva mezi business a vývojem
Byznys říká: „prodejce Jana má obrat 80 000, pod ní B s 60 000, pod B je C s 40 000, Jana dostává override 3 % z B a 1,5 % z C. Spočítej.“ My to spočítáme, dostaneme číslo, byznys potvrdí „správně“. Tohle se musí uložit jako test case.
My jsme pro JUST sbírali scenario file: ~50 reálných i vymyšlených případů. Každé pravidlo v systému má alespoň 2-3 scenarios, které ho testují. Když někdo změní logiku, CI pipeline spustí všechny scenarios a ukáže, které výsledky se změnily. Pokud se změnily neočekávaně → bug.
Legacy systém něco takového neměl. Po 15 letech nikdo přesně nevěděl, jak se co počítá — muselo se experimentovat. Jeden z prvních deliverables naší implementace bylo dostat testovací scenarios od business analytika a tím zafixovat skutečná pravidla.
4. Dual-run period před přepnutím
Před cutoverem legacy → nový systém jsme 3 měsíce běželi oba systémy paralelně na stejná data. Výsledky se každý měsíc porovnaly. Rozdíl > 0,01 % byl alert.
Najeli jsme 7 pravidel, kde náš nový systém počítal jinak než legacy. 5× byl legacy správně a my jsme měli bug. 2× byl legacy špatně a byznys to nikdy nevěděl (~15 000 Kč za 3 měsíce podplaceno). Nahlásilo se, prodejcům se dopočítaly korekce, byznys to ocenil.
Dual-run není luxus. Pro kritické finanční systémy je to minimum, aby byl launch bez překvapení.
5. Recalculation ability od dne jedna
Schopnost přepočítat libovolný historický měsíc znovu je load- bearing. Důvody:
- Audit zjistí chybu v pravidlech z roku 2022 — musíš přepočítat celou historii
- Legal sporu s prodejcem — musíš předložit detail výpočtu
- Byznys chce zpětně aplikovat nový bonus — recalculation s retroaktivním pravidlem
Pokud máš pravidla immutable v DB + snapshot inputů per výpočet, recalculation je deterministický. Pokud máš logiku v kódu a běžně ji měníš, za 3 roky je recalculation nemožná.
Generalizace
MLM není jediný use case tohoto vzoru. Totéž platí pro:
- Loyalty programy s měnícími se pravidly
- Payroll / odměňovací systémy
- Pricing engines, kde zákazníci mají různé historicky nasmlouvané podmínky
- Fintech fee calculations s regulatory změnami
Společný jmenovatel: pravidlo dnes ≠ pravidlo za rok, a musíš umět oboje obhájit. Nedělej to v kódu. Dělej to v datech, s immutable historií a testy jako smlouvou mezi business a engineering.
Řešíš něco podobného?
Domluvme si 30min technický call. Bez obchodních procesů — přímá architekturní zpětná vazba.
Naše služba:
Systémy, které škálují — bez bottlenecků →