Magazín
Technika2 min čtení

Jak nasazujeme funkce, které se dotýkají peněz, aniž bychom někomu omylem změnili cenu

Chyba v cenách je ta, kterou už nevezmete zpět, jakmile se strhne platba z karty. Tady je kázeň, se kterou přidáváme do rezervačního procesu slevy, ceny podle personálu a akce, aniž by se jediná cena pohnula dřív, než chceme.

TTTechnický tým Bookatu

Většina chyb vás stojí omluvu. Chyba v cenách vás stojí vratku, chargeback a klienta, který už nevěří číslu na obrazovce. Sázky jsou nevyrovnané, takže postup okolo všeho, co se dotýká peněz, je záměrně pomalejší než zbytek naší práce. Takhle vypadá, a jako příklad použijeme nedávnou funkci: slevu na celou kategorii, kdy salon může dát do slevy všechna ošetření pleti naráz.

REBUILT ON THE SERVER, EVERY BOOKINGBase priceStaff priceCategory saleBest couponCharged
Cena každé rezervace se skládá vždy ve stejném pevném pořadí a celý součet se znovu udělá na serveru.

Vypnuto, v produkci, nedělá nic

První řádek funkce je přepínač. Čte proměnnou prostředí a výchozí stav je vypnuto. To znamená, že můžeme kód sloučit a nasadit dlouho předtím, než začne cokoli dělat, a každá cena zůstane bajt po bajtu stejná jako den předtím. Není tu žádné velké spuštění, ze kterého by šel strach, protože spuštění je samostatný nudný krok, který uděláme, až si budeme jistí.

ts
export const FEATURE_LIVE =  process.env.FEATURE_LIVE === "true"; // Read at the one place it matters. When the flag is off, the branch// is skipped entirely: no extra query, no price change, nothing.if (FEATURE_LIVE) {  const pct = await activeCategorySalePercent(orgId, "service", service.category);  if (pct > 0) fullPriceCents = applyCategorySaleCents(fullPriceCents, pct);}
1Behind a flagoff by default2Merge & deploystill off3Audit passes0 money bugs4Flip the flagthe go-liveLive
Spuštění je samostatný nudný krok. Kód se nasadí dlouho předtím, než začne cokoli dělat.

Jedna funkce, jeden úkol

Aritmetika slevy žije v jediné čisté funkci. Bere haléře a procenta a vrací haléře. Nemá databázi, nemá požadavek a nemá hodiny, což znamená, že je triviální otestovat každý její okraj izolovaně: nulová sleva, běžná sleva, omezení nahoře, záporná hodnota, která by nikdy neměla nastat. Když je výpočet jedna malá funkce, kterou udržíte v hlavě, přestanete o ní hádat.

ts
export function applyCategorySaleCents(  baseCents: number,  salePercent: number | null | undefined,): number {  const base = cents(baseCents);  const pct = Math.max(0, Math.min(100, Math.round(salePercent ?? 0)));  if (pct === 0) return base;  return cents((base * (100 - pct)) / 100);}

Přepočítat na serveru, vždycky

Prohlížeč ukazuje cenu, aby klient věděl, kolik zaplatí, ale to číslo je vždy jen zobrazení. Když přijde rezervace, server načte skutečnou službu, vyhodnotí cenu podle personálu, uplatní případnou aktivní slevu na kategorii a pak spočítá slevu, a to všechno z dat, která si sám stáhl. Když někdo požadavek cestou upravil, nezmění to nic, protože cena stržená z karty nikdy nebyla cenou, kterou poslal prohlížeč. Tohle je nejdůležitější návyk v kódu okolo peněz: hranice důvěry je server a součet dělá server.

BROWSERShows a price so the clientknows what they will pay.A display only. Never trusted.requestSERVER · SOURCE OF TRUTH1 · Load the real service2 · Resolve staff + sale price3 · Apply the best coupon4 · Charge exactly that
Číslo, které ukazuje prohlížeč, je jen zobrazení. Server si natáhne vlastní data a součet udělá znovu.

Zkuste to rozbít dřív než zákazník

Procházející testy vám řeknou, že případy, na které jste mysleli, fungují. Neřeknou vám nic o případu, který vám unikl. Než tedy cenový přepínač zapneme, projedeme nepřátelské kolo, jehož jediným úkolem je najít způsob, jak peníze pokazit. Jednotlivé kontroly berou věc z různých stran: jedna hledá jakoukoli cestu, která klientovi naúčtuje příliš, druhá cestu, kterou podnik přichází o peníze, třetí ověřuje, že je funkce s vypnutým přepínačem opravdu netečná, a čtvrtá jde po zaokrouhlování a driftu na hranicích. Sleva navršená na kupon a na zálohu je přesně to místo, kde se schová zlomek haléře, takže právě tam se díváme nejpozorněji.

New pricing featureOvercharges?Loses money?Leaks when off?Rounding drift?Clean sweep → GO
Čtyři skeptici, každý jiná cesta k chybě. Zelenou dává jen čistý průchod.

Nic z toho není chytré. Je to přepínač, malá funkce, server, který si počítá sám, a zvyk zkoušet si rozbít vlastní práci dřív, než se nasadí. Dohromady je to rozdíl mezi tím přidat funkci, která se dotýká peněz, a nespat kvůli ní.

feature flagsbezpečná práce s penězi v kódunávrh cenového enginuvalidace na serveruhranice důvěry
Chcete to uvést do praxe?

Bookatu vám dá rezervační stránku ve vašem stylu, zálohy, členství, dárkové poukazy a připomínky, s 0% provizí z vašich rezervací.

Začít zdarma