Ugrás a tartalomra

Stúdiókezelési esettanulmány

Tattoos by Sandor

Foglalási és stúdiókezelési rendszer éles használatra, online előlegekkel, Tap to Pay terminálokkal, automatizált Xero-integrációval és teljes admin irányítópulttal. Több mérnöki munka van benne, mint amit a legtöbben egy tetoválóstúdió weboldalától várnának.

Áttekintés

Nem csak weboldal. Teljes stúdióműködtető rendszer.

Kívülről a Tattoos by Sandor letisztult stúdióweboldalnak tűnik. Belül teljes foglaláskezelő platform: online időpontfoglalás előleggel, rugalmas időzítésű walk-in alkalmak, érintéses fizetés beszedése és automatikus számlagenerálás Xero-ban.

Az admin irányítópult teljes kontrollt ad a művésznek minden foglalás fölött az első érdeklődéstől a végső fizetésig, beépített Xero-szinkronnal és magas szintű biztonsággal, TOTP kétfaktoros hitelesítéssel együtt.

3

Foglalástípusok

32+

API-végpontok

2

Stripe-integrációk

6

Biztonsági rétegek

A Tattoos by Sandor weboldal

Foglalási folyamatok

Három foglalási mód. Egy rendszer.

Minden foglalástípus más valós helyzetet kezel, automatikus ütközésmegelőzéssel az adatbázisrétegben.

💳

Online foglalás + előleg

  1. 1Az ügyfél kiválasztja a dátumot és az idősávot
  2. 2Referenciaképeket tölt fel (Cloudinary)
  3. 3Kifizeti a foglalási előleget Stripe Checkouton keresztül
  4. 4A webhook visszaigazol → a foglalás automatikusan megerősítést kap
  5. 5E-mailes visszaigazolás megy az ügyfélnek és az adminnak
🚶

Walk-in (rugalmas időzítés)

  1. 1Az admin megnyitja a walk-in űrlapot az irányítópulton
  2. 2Beállítja a pontos időpontot 5 perces lépésekben
  3. 3Megadja az alkalom egyedi árát
  4. 4Kiválasztja a készpénzes vagy érintéses fizetést
  5. 5A foglalás azonnal megerősített, előleg nem kell
📱

Adminfoglalás + Tap to Pay

  1. 1Az admin kézi foglalást hoz létre az ügyfélnek
  2. 2A rendszer átirányít a Tap to Pay oldalra
  3. 3Az ügyfél odatartja a kártyát / Apple Payt / Google Payt
  4. 4A kártyaterminál valós időben rögzíti a fizetést
  5. 5Sikeres fizetés után a foglalás automatikusan megerősítést kap

Admin irányítópult

Teljes kontroll egy képernyőről

📅

Foglaláskezelés

Szűrés státusz alapján (függő / megerősített / lemondott). Bármelyik foglalás kinyitható, hogy látszódjanak az ügyféladatok, a referenciaképek, az előleg státusza és a végső fizetés adatai. A foglalások szerkeszthetők, megerősíthetők, lemondhatók vagy egész napos alkalommá bővíthetők.

💰

Végső fizetés rögzítése

Minden alkalom után a művész megadja a végső árat. A rendszer kiszámolja a fennmaradó összeget (végösszeg mínusz előleg), rögzíti a fizetési módot (készpénz vagy érintéses fizetés), és időbélyeget tesz a lezárásra.

📊

Pénzügyi irányítópult

A Xero-integrációra épített pénzügyi nézet szinkronizált számlákkal és jelentésekkel, valamint alkalmazáson belüli összegzéssel az adott időszak foglalásairól és fizetéseiről.

🗓️

Blokkolt dátumok

Teljes napok vagy konkrét 3 órás idősávok blokkolhatók szabadság, rendezvények vagy személyes idő miatt. A blokkolt dátumok valós időben eltűnnek az ügyfél foglalási naptárából.

🔗

Xero-szinkron

Egyedi foglalások vagy az összes megerősített kártyás fizetésű alkalom egy kattintással szinkronizálható Xero-ba. Minden számla automatikusan típus szerint kategorizálódik.

🔐

Biztonság és 2FA

JWT-vel védett admin opcionális TOTP kétfaktoros hitelesítéssel (Google Authenticator). A token-visszavonási tábla megakadályozza a kijelentkezett JWT-k újrafelhasználását. 6 rétegű CSV-importbiztonság tömeges adatokhoz.

Fizetések

Két fizetési mód, nem egy

A legtöbb foglalási rendszer kínál egy fizetési módot, és ezzel lezártnak tekinti a kérdést. Ez a projekt két külön integrációt használ, hogy lefedjen minden helyzetet, amivel a stúdió találkozik.

🖥️

Online fizetés, előlegek

Az ügyfelek online fizetik ki a foglalási előleget. Sikeres fizetéskor a Stripe webhookot küld, amely automatikusan megerősíti a foglalást és elindítja a visszaigazoló e-mailt.

📱

Tap to Pay terminál

A stúdióban történő fizetéseknél az admin egy előre kitöltött Tap to Pay oldalra irányít, amely tartalmazza a foglalást és az összeget. Az ügyfél közvetlenül a művész telefonján érinti oda a kártyáját, az Apple Payt vagy a Google Payt. Külön kártyaolvasó hardver nem kell.

Könyvelés

Xero-integráció

A kártyával fizetett foglalások OAuth 2.0-n keresztül számlaként szinkronizálódnak Xero-ba, automatikusan alkalmazott megfelelő adókezeléssel.

Normál előleg

Xero-ba szinkronizál

A fizetés megerősítésekor előlegszámla készül Xero-ban.

Walk-in (kártyás fizetés)

Xero-ba szinkronizál

A teljes alkalomról számla készül Xero-ban, a megfelelő adókezeléssel.

Értékesítés a széken túl

Utalványok, kedvezmények és hűségkártya

Három mód, ahogy pénz érkezik a stúdióba úgy, hogy nem egyszerűen egy alkalmat fizetnek ki. Mindegyik pénzügyi szabály, ezért egyik sem lehet egy handler mélyére eldugott egysoros megoldás.

🎁

Ajándékutalványok

A kódok Crockford Base32 ábécéből készülnek, amelyből kivettem az I, L, O és U karaktereket: az első hármat azért, mert a legtöbb betűtípusban nem különböztethetők meg az 1-től és a 0-tól, az U-t pedig azért, mert ezeket a kódokat telefonon is bediktálják. A pontosan 32 karakter azt is jelenti, hogy a húzás rejection sampling nélkül torzítatlan, amit pénzt képviselő kódnál érdemes már felépítésből jól megoldani.

🏷️

Kedvezménykódok

Százalékos vagy fix összegű kedvezmény, fél napra, egész napra vagy bármilyen alkalomra korlátozva, opcionális időablakkal, amely nem a foglalás dátumára, hanem az ALKALOM dátumára vonatkozik. Így egy januári kód továbbra is érvényes egy januári idősávra akkor is, ha októberben foglalták. Az összes beváltási limit és az ügyfelenkénti limit kódonként állítható az irányítópulton.

🎟️

A hűségkártya

Maga a kártya szándékosan fizikai; itt semmi nem követi a pecséteket, és ennek hozzáadását nem feltételeztem, hanem nyitva hagytam döntésként. Amit a rendszer kezel, az a pultnál töltött tíz másodperc: kiszámolja a csökkentést, és rögzíti, MIÉRT lett alacsonyabb ár megadva. A magyarázat nélküli ár ugyanaz a probléma a könyvelésben, mint a kódban; hat hónappal később senki nem tudja megmondani, hogy hűségkedvezményről vagy hibáról volt-e szó.

Technológiai stack

Az első naptól éles használatra építve

Felhasználói felület

  • Next.js 14
  • TypeScript
  • Tailwind CSS
  • React 18
  • react-icons

Szerveroldal

  • Next.js API Routes
  • Raw SQL (mysql2)
  • JWT auth (jsonwebtoken)
  • bcryptjs
  • TOTP 2FA (otplib)

Adatbázis

  • MySQL 8.0
  • Pesszimista zárolás
  • Egyedi idősáv-korlátok
  • Atomi tranzakciók

Fizetések

  • Stripe Checkout (deposits)
  • Stripe Terminal (Tap to Pay)
  • Stripe Webhooks
  • Éles kulcsok éles környezetben

Integrációk

  • Xero OAuth 2.0
  • Cloudinary CDN (képek)
  • Nodemailer SMTP (e-mail)
  • Redis (kérésszám-korlátozás)
  • Sentry (hibakövetés)

Mérnöki részletek

A részletek, amelyek számítanak

A pesszimista zárolás megelőzi a dupla foglalást

Az adatbázisban UNIQUE korlát van a (booking_date, slot_start) mezőkön. Ezen felül az idősáv elérhetősége SELECT ... FOR UPDATE tranzakción belül ellenőrződik, így ugyanarra az idősávra két egyszerre érkező foglalás versenyhelyzetben sem lehet egyszerre sikeres.

Egész napos foglalások két atomi sorként

Egy 6 órás alkalom két összekapcsolt 3 órás idősávrekordként tárolódik, egyetlen tranzakcióban létrehozva. Ha bármelyik beszúrás hibázik, mindkettő visszagördül. A kliens FULL: előtaggal azonosítja őket; az adatbázis az egyező ügyféladatok alapján kapcsolja össze a sorokat.

A walk-in idősávok megkerülik a 3 órás korlátot

A walk-in foglalások rugalmas, 5 perces időzítést használnak (például 14:35), ami ütközne a szabványos idősáv egyedi kulcsával. A walk-in foglalásoknál a booking_type oszlop is része az egyedi korlátnak, így ugyanazon a napon ütközés nélkül megférnek a normál foglalások mellett.

JWT-visszavonás session store nélkül

A serverless függvények állapotmentesek, de kijelentkezéskor akkor is érvényteleníteni kell a tokent. Minden JWT egyedi azonosítót hordoz. Kijelentkezéskor ez az azonosító szerveroldalon tárolódik, és minden védett útvonal hozzáférés előtt ellenőrzi.

OAuth tokenfrissítés állapotmentes környezetben

A Xero OAuth tokenjei gyakran lejárnak. Mivel a Vercel-függvényeknek nincs tartós memóriájuk, a tokenek biztonságosan, szerveroldalon vannak tartósítva. Minden API-hívás betölti és használja a tokent, szükség esetén frissíti, majd visszamenti a frissített hitelesítő adatokat.

A pénzügyi szabályok tiszta függvények

Azt, hogy egy utalvány fizethet-e egy foglalásért, és hogy egy kedvezménykód mennyit von le, olyan függvények döntik el, amelyek hatókörében nincs adatbázis, fizetési SDK vagy e-mail-küldés. Ez nem rendrakás. A foglalási végpont mindhármat importálja, és egyik sem töltődik be a tesztfuttató alatt, ezért egy oda beírt pénzügyi szabály egyáltalán nem lenne tesztelhető. Így maradhatott élesben egy korábbi előlegszámítási hiba, amelyet nem teszt, hanem valódi fizetés fogott meg.

Content Security Policy SHA-256 scripthashekkel

A szigorú CSP minden inline scriptet blokkol, kivéve az előre kiszámított SHA-256 hashsel rendelkezőket. Ez akkor is megelőzi az XSS-t, ha egy támadó tartalmat juttat az oldalba. A Google Analytics és a Stripe domain alapján engedélyezett; minden más forrás blokkolva van.

Olyan foglalási rendszer kell, amely tényleg működik?

Foglalási platformokat építek valódi fizetéskezeléssel, könyvelési integrációval és admineszközökkel, nem sablonra rácsavarozott kész plugint. Ha ilyen a problémád, írd le.