Egy multi-tenant ERP-rendszer egyik nehez kerdese: hogyan tartsuk fenn, hogy minden tenant a sajat brandjet lassa - de ne kelljen 200 fa storefront-temat fenntartani. A Netorigo Admin brand-modulja egy kompromisszum: egy tenant = egy brand-kit, es minden frontend-felulet ebbol szarmaztatja a megjelenest.
Mi van a brand-kitben
A tenant_brand tabla tartalmazza:
- Logo - SVG vagy PNG, max 2 MB, S3-ban szignalt URL-lel, kotelezo
lightes opcionalisdarkvaltozat. - Szin-tokenek - 8 darab: primary, primaryHover, accent, surface, surfaceMuted, text, textMuted, danger. Mindegyik hex-formatumban, validalva (a UI nem engedi, hogy a
primaryessurfacekontrasztja 4.5 ala essen, mert akkor a WCAG AA bukik). - OG kep - Open Graph megosztashoz, 1200x630 px, kotelezo.
- Favicon - .ico vagy .svg, multi-size (16, 32, 180, 512).
- Email-fejlec banner - 600 px szeles PNG, tranzakcios emailekhez (rendelesvisszaigazolas, jelszovisszaallitas).
- Brand-font - a 14 elotaltott Google Font kozul egy, vagy custom WOFF2 (max 200 KB, kotelezo subset: latin-ext).
Hogyan jut el a frontendig
Az /api/v1/tenant/:slug/brand egy publikus, cache-elheto endpoint (Vercel edge-cache, 5 perc TTL). Minden frontend-app (admin, storefront, finance, logistics) ezt hivja a layoutban, majd a szin-tokeneket egy <style> blokkba toltik a CSS variable-okkel:
:root {
--brand-primary: #1e40af;
--brand-primary-hover: #1d4ed8;
/* ... */
}
A Tailwind v4 oldalan ezt mar trivialisan hasznaljuk: bg-[var(--brand-primary)], vagy a sajat bg-brand-primary utility-vel, ami a @theme blokkban van regisztralva.
Live preview
A brand-szerkeszto kepernyon egy ket-oszlopos layout: bal oldalon a form, jobb oldalon egy <iframe>, ami a tenant landingpage-et toltik be ?preview=<draft-id> query-vel. Minden valtoztatas (onChange, debounce 300 ms) egy postMessage-et kuld az iframe-be, ami a CSS-variable-eket on-the-fly frissiti. Igy az operator latja a logo-cseret, szinevaltast valos idoben, anelkul, hogy mentenie kellene.
A mentes egy tenant_brand_draft rekordot hoz letre, amit a Publish gomb tesz tenant_brand-re. A draft 30 nap utan automatice torlodik.
A bug ami csipett: CDN cache-busting logo-cserekor
2026 marciusban egy ugyfel jelentette, hogy a logot lecserelte, de a publikus storefronton meg a regi latszik. A nyomozas: a CDN-en a logo.png URL 24 ora-ra cache-elve volt (Cache-Control: max-age=86400). A fix ket reszbol all:
- Verzio-query string - minden brand-asset URL-ben
?v=<sha256_8>query, ahol a hash a fajl tartalmaval valtozik. Igy a CDN egy uj file-nak latja a friss verziot. - Aktiv CDN purge - a Publish gomb egy webhookot kuld a Cloudflare API-nak, ami a
logo.*mintat torli a tenant cache-ebol. Ez kb. 30 masodperc alatt vegigfut globalisan.
A ket reszbol bekartyazott megoldas: a verziozott URL azonnal hat, a CDN purge biztositja, hogy a 24 oras cache se okoz problemat, ha valamiert a verzio-query nem futna at az osszes konzumeren.
A dontes: egy tenant = egy brand
A roadmapen szerepelt egy multi-storefront brand-override (egy tenant kezelhetne 3-4 kulonbozo brand alatt, mondjuk egy szuloceg + ket lanymarka). Ezt elhalasztottuk, mert a komplexitas (per-storefront layout-injection, per-storefront cache-key, per-storefront preview) megduplazta volna a modul kodjat, es a 2026 Q1-ben kerdezett 47 ugyfel kozul csak 4-nek volt erre valos igenye. A 4-et manualis tenant-szeparalassal oldottuk meg: minden brandnek sajat tenant-rekord, sajat user-ek, kozos termek-katalogus egy tenant-share modulon keresztul.
A jovoben (varhatoan 2026 H2): per-channel branding (web vs. email vs. PDF eltero szinekkel), de meg az egy tenant = egy brand korlatozasban.