Vissza a Journal-hoz
adminhu

Multi-tenant brand-eszkozok kezelese az Adminon

Logo, szinek, OG-kep, font - tenant per brand-kit S3-ban, live previewvel, plusz a CDN cache-busting bug amit egyszer eszunkbe kell vesnunk.

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 light es opcionalis dark valtozat.
  • Szin-tokenek - 8 darab: primary, primaryHover, accent, surface, surfaceMuted, text, textMuted, danger. Mindegyik hex-formatumban, validalva (a UI nem engedi, hogy a primary es surface kontrasztja 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:

  1. 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.
  2. 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.