15 KiB
🌐 Admin i18n Audit & Újrastrukturálási Javaslat
Dátum: 2026-06-30 Készítette: Rendszer-Architect Verzió: 1.0 Cél: Admin felület nyelvi moduljainak teljes körű felmérése, központi nyelvi állomány kialakítása, oldalakra bontási terv, többnyelvű (dropdown) nyelvválasztó bevezetése
1. Jelenlegi Helyzet (As-Is)
1.1 Három teljesen elkülönülő i18n rendszer
| Rendszer | Hely | Formátum | Fájlok | Össz. kulcs | Nyelvek |
|---|---|---|---|---|---|
| Backend | backend/static/locales/ |
Nested JSON (UPPER_SNAKE) | 2 db | ~130 sor/fájl | hu, en |
| Frontend Admin | frontend_admin/i18n/locales/ |
Nested JSON (camelCase) | 2 db | ~800-900 sor/fájl | hu, en |
| Frontend Old (src) | frontend/src/i18n/ (korábbi) |
TS objektum | 6 db | ~1600 sor/fájl | hu, en, de, ro, cz, sk |
⚠️ A backend és a frontend rendszerek teljesen függetlenek. Más kulcs-sémát használnak (dot-notation vs UPPER_SNAKE_CASE), így közöttük NINCS kulcs-megosztás.
1.2 Frontend Admin jelenlegi struktúrája
frontend_admin/i18n/locales/
├── en.json (902 sor / ~700 kulcs)
└── hu.json (804 sor / ~650 kulcs)
Gyökér-szekciók a JSON-ben:
permissions(~29 kulcs)packages(~67 kulcs)garages→garages.details,garages.analytics,garages.employees,garages.fleet(~180 kulcs)gamification→gamification.badges,.competitions,.config,.dashboard,.leaderboard,.ledger,.levels,.params,.point_rules,.seasons,.users,.user_detail(~410 kulcs)providers(~85 kulcs)users→users.details(~98 kulcs)
1.3 Admin oldalak leképezése (Pages ↔ i18n szekciók)
| Oldal (Vue fájl) | i18n Szekció | Kulcsszám |
|---|---|---|
/ (index.vue) |
— | — (dashboard nincs lefordítva) |
/permissions/ |
permissions.* |
~29 |
/packages/ |
packages.* |
~67 |
/garages/ + garages/[id]/ |
garages.*, garages.details.*, garages.analytics.*, garages.employees.*, garages.fleet.* |
~180 |
/gamification/ (index) |
gamification.dashboard.* |
~25 |
/gamification/badges |
gamification.badges.* |
~35 |
/gamification/competitions |
gamification.competitions.* |
~40 |
/gamification/config |
gamification.config.* |
~25 |
/gamification/leaderboard |
gamification.leaderboard.* |
~40 |
/gamification/ledger |
gamification.ledger.* |
~30 |
/gamification/levels |
gamification.levels.* |
~35 |
/gamification/params |
gamification.params.* |
~25 |
/gamification/point-rules |
gamification.point_rules.* |
~40 |
/gamification/seasons |
gamification.seasons.* |
~30 |
/gamification/users/ + [id] |
gamification.users.*, gamification.user_detail.* |
~40+50 |
/providers/ + [id] |
providers.* |
~85 |
/users/ + [id] |
users.*, users.details.* |
~98 |
2. Feltárt Problémák
2.1 Hiányzó központi (common/global) nyelvi szekció
Jelenleg NINCS common vagy global szekció az admin i18n-ben. Minden általános UI művelet (Mentés, Mégse, Törlés, Szerkesztés, Betöltés, Hiba) szekciónként DUPLIKÁLVA van.
2.2 Masszív kulcs-duplikáció
A docs/i18n_duplicate_key_analysis.md által feltárt frontend duplikációk az adminban is jelen vannak. Példák a frontend_admin fájlokból:
| Kulcs (EN) | Előfordulások száma | HU fordítás |
|---|---|---|
cancel |
9+ (permissions, packages, garages.employees, gamification.badges, competitions, levels, params, point_rules, seasons, providers) | "Mégse" |
save |
10+ (permissions, packages.details, garages., gamification., providers, users.details) | "Mentés" |
loading |
15+ (minden CRUD szekció) | "Betöltés..." |
error |
10+ (minden CRUD szekció) | "Nem sikerült..." |
retry |
10+ | "Újra" / "Újrapróbálkozás" (két változat!) |
edit |
8+ | "Szerkesztés" |
delete |
6+ | "Törlés" |
actions |
6+ | "Műveletek" |
no_items / no_results |
8+ | "Nincs..." |
status |
6+ | "Státusz" |
save_error |
8+ | "Hiba történt..." |
2.3 HU oldalon inkonzisztens fordítások
retry: hol "Újra" (permissions.retry,packages.retry), hol "Újrapróbálkozás" (gamification.badges.retry)cancel: hol "Mégse" (többnyire), de van ahol nincs következetesensave_successvsupdatedvscreated: eltérő sablonok
2.4 Csak 2 nyelv támogatott az adminban
A nuxt.config.ts i18n beállításaiban csak hu és en szerepel:
locales: [
{ code: 'hu', iso: 'hu-HU', file: 'hu.json', name: 'Magyar' },
{ code: 'en', iso: 'en-GB', file: 'en.json', name: 'English' },
]
A frontend_old LanguageSwitcher már 4 nyelvet támogat (hu, en, de, fr).
Előző audit szerint a korábbi frontend/src/i18n/ is tartalmazott részleges de, ro, cz, sk fordításokat.
2.5 Nyelvválasztó jelenleg kétállású kapcsoló
A frontend_admin/layouts/default.vue topbar-jában a nyelvválasztó két gomb (HU / EN), nem pedig egy legördülő menü. Ez nem skálázható 3+ nyelv esetén.
2.6 Backend i18n aszimmetria
- A
backend/static/locales/hu.json(83 sor) ésen.json(76 sor) között eltérés van a kulcsok számában (pl.SENTINEL.APPROVAL.REQUIREDEN: "Approval required", HU-ban hosszabb) - Backend hiányzik: német és más nyelvű backend fordítások
3. Javasolt Megoldás (To-Be)
3.1 Központi/globális nyelvi állomány (common)
Létrehozandó: új common gyökér-szekció mindkét fájlban
Tartalma (javasolt kulcsok):
{
"common": {
"save": "Mentés",
"saving": "Mentés...",
"cancel": "Mégse",
"confirm": "Megerősítés",
"discard": "Elvetés",
"delete": "Törlés",
"deleting": "Törlés...",
"edit": "Szerkesztés",
"create": "Létrehozás",
"close": "Bezárás",
"back": "Vissza",
"next": "Következő",
"previous": "Előző",
"search": "Keresés",
"filter": "Szűrés",
"reset": "Visszaállítás",
"clear": "Törlés",
"retry": "Újra",
"loading": "Betöltés...",
"error": "Hiba",
"success": "Siker",
"no_results": "Nincs találat",
"no_data": "Nincs adat",
"yes": "Igen",
"no": "Nem",
"continue": "Tovább",
"exit": "Kilépés",
"save_changes": "Változtatások Mentése",
"confirm_delete": "Biztosan törölni szeretnéd?",
"unknown_error": "Ismeretlen hiba",
"all": "Mind",
"none": "Nincs",
"optional": "opcionális",
"required": "kötelező"
}
}
Használati elv: A Vue komponensek elsődlegesen a common.* kulcsokat használják. Csak ha egy gombnak szekció-specifikus szövege van (pl. "Csomag törlése" ≠ általános "Törlés"), akkor kell szekció-specifikus kulcs.
3.2 Oldalakra bontás javaslata (lazy loading támogatás)
Jelenleg a nuxt.config.ts-ben lazy: false van beállítva, ami azt jelenti, hogy minden nyelvi fájl betöltődik induláskor. A javasolt struktúra lehetővé teszi a lazy: true váltást.
Új fájl struktúra:
frontend_admin/i18n/
├── locales/
│ ├── common.en.json ← központi alapértékek (EN)
│ ├── common.hu.json ← központi alapértékek (HU)
│ ├── permissions.en.json
│ ├── permissions.hu.json
│ ├── packages.en.json
│ ├── packages.hu.json
│ ├── garages.en.json
│ ├── garages.hu.json
│ ├── providers.en.json
│ ├── providers.hu.json
│ ├── users.en.json
│ ├── users.hu.json
│ ├── gamification-dashboard.{en,hu}.json
│ ├── gamification-badges.{en,hu}.json
│ ├── gamification-competitions.{en,hu}.json
│ ├── gamification-config.{en,hu}.json
│ ├── gamification-leaderboard.{en,hu}.json
│ ├── gamification-ledger.{en,hu}.json
│ ├── gamification-levels.{en,hu}.json
│ ├── gamification-params.{en,hu}.json
│ ├── gamification-point-rules.{en,hu}.json
│ ├── gamification-seasons.{en,hu}.json
│ ├── gamification-users.{en,hu}.json
│ └── gamification-user-detail.{en,hu}.json
nuxt.config.ts módosítása:
i18n: {
locales: [
{ code: 'hu', iso: 'hu-HU', file: 'common.hu.json', name: 'Magyar' },
{ code: 'en', iso: 'en-GB', file: 'common.en.json', name: 'English' },
{ code: 'de', iso: 'de-DE', file: 'common.de.json', name: 'Deutsch' },
],
defaultLocale: 'hu',
lazy: true,
langDir: 'locales/',
strategy: 'no_prefix',
detectBrowserLanguage: {
useCookie: true,
cookieKey: 'i18n_redirected',
redirectOn: 'root',
},
}
3.3 Többnyelvűség (3+ nyelv) bevezetése
Új nyelv hozzáadásának lépései:
- Új fájl létrehozása: pl.
common.de.json,permissions.de.json, stb. - A nyelv felvétele a
nuxt.config.tslocalestömbjébe - Fordítások elkészítése (kezdetben csak
common+ a leggyakoribb admin oldalak) - Backend oldalon: új
de.jsonfájl abackend/static/locales/mappába - A backend
i18n.pyautomatikusan betölti, ha a fájl létezik
Előkészített nyelvek (részleges fordítások megléte alapján):
- Deutsch (de) — volt már részleges fordítás a régi frontend-ben
- Français (fr) — volt a LanguageSwitcher-ben
- Română (ro) — volt részleges fordítás a régi frontend-ben
- Čeština (cz) — volt részleges fordítás a régi frontend-ben
- Slovenčina (sk) — volt részleges fordítás a régi frontend-ben
3.4 Nyelvválasztó legördülő menüvé alakítása
Jelenlegi kód (frontend_admin/layouts/default.vue, 158-170. sor):
<!-- JELENLEG: kétállású kapcsoló -->
<div class="flex items-center bg-slate-700/50 rounded-lg p-0.5">
<button v-for="locale in availableLocales" :key="locale.code"
@click="switchLocale(locale.code)"
class="px-2.5 py-1 text-xs font-medium rounded-md transition"
:class="currentLocale === locale.code
? 'bg-indigo-600 text-white shadow-sm'
: 'text-slate-400 hover:text-white'"
>
{{ locale.code === 'hu' ? 'HU' : 'EN' }}
</button>
</div>
Javasolt új kód:
<!-- ÚJ: legördülő nyelvválasztó -->
<div class="language-switcher relative">
<button @click="langDropdownOpen = !langDropdownOpen"
class="flex items-center gap-2 px-3 py-1.5 bg-slate-700/50 rounded-lg text-xs font-medium
hover:bg-slate-600/50 transition border border-slate-600/50"
>
<span>{{ getFlagEmoji(currentLocale) }}</span>
<span>{{ getCurrentLanguageLabel() }}</span>
<svg class="w-3.5 h-3.5 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
</button>
<!-- Dropdown -->
<div v-if="langDropdownOpen"
class="absolute right-0 mt-1 bg-slate-800 border border-slate-700 rounded-lg shadow-xl z-50 min-w-[140px]"
>
<button v-for="locale in availableLocales" :key="locale.code"
@click="switchLocale(locale.code); langDropdownOpen = false"
class="w-full text-left px-3 py-2 text-xs hover:bg-slate-700 flex items-center gap-2 transition"
:class="{ 'text-indigo-400': locale.code === currentLocale }"
>
<span>{{ getFlagEmoji(locale.code) }}</span>
<span>{{ locale.name }}</span>
<span v-if="locale.code === currentLocale" class="ml-auto text-indigo-400">✓</span>
</button>
</div>
</div>
script kiegészítés:
const langDropdownOpen = ref(false)
function getFlagEmoji(code: string): string {
const flags: Record<string, string> = {
hu: '🇭🇺', en: '🇬🇧', de: '🇩🇪', fr: '🇫🇷',
ro: '🇷🇴', cz: '🇨🇿', sk: '🇸🇰',
}
return flags[code] || '🌐'
}
function getCurrentLanguageLabel(): string {
const lang = availableLocales.value.find(l => l.code === currentLocale.value)
return lang?.name || currentLocale.value.toUpperCase()
}
3.5 Backend i18n kiegészítése
A backend i18n.py már támogatja az automatikus betöltést — bármely .json fájl a backend/static/locales/ mappában automatikusan felkerül a cache-be. Új nyelv esetén csak a JSON fájlt kell létrehozni.
A nuxt.config.ts-ben a PATCH /api/v1/auth/me/language végpont már támogatja a nyelv perzisztálását a backend felé — ez működni fog új nyelvekkel is, mivel a preferred_language mező egy szabad string.
4. Ütemezés (Mérföldkövek)
M1: Központi common szekció létrehozása
- Új
commonszekció felvétele azen.jsonéshu.jsonfájlokba - A duplikált kulcsok (cancel, save, loading, stb.) eltávolítása a szekció-specifikus részekből
- Vue komponensek átírása:
$t('common.cancel')használata a szekció-specifikus helyett - Érintett fájlok:
frontend_admin/i18n/locales/*.json,frontend_admin/pages/*.vue,frontend_admin/layouts/default.vue
M2: Fájlok oldalakra bontása (lazy loading)
- A monolit
en.jsonéshu.jsonszétbontása oldal-specifikus fájlokra nuxt.config.tsfrissítése (lazy: true)- Tesztelés: minden oldal megfelelően betölti a saját nyelvi fájlját
- Érintett fájlok:
frontend_admin/i18n/locales/*,frontend_admin/nuxt.config.ts
M3: Nyelvválasztó dropdown bevezetése
default.vuelayoutban a kétállású HU/EN kapcsoló cseréje legördülő menüre- Flag emoji támogatás
- Több nyelv (de, fr) felvétele a konfigurációba
- Érintett fájlok:
frontend_admin/layouts/default.vue,frontend_admin/nuxt.config.ts
M4: Új nyelvek backend támogatása
de.json,fr.jsonlétrehozása abackend/static/locales/mappában- Legalább a COMMON és AUTH szekciók lefordítása
- Érintett fájlok:
backend/static/locales/*.json
M5: Backend i18n aszimmetria javítása
hu.jsonésen.jsonkulcs-szinkronizációja- Hiányzó kulcsok pótlása
- Érintett fájlok:
backend/static/locales/*.json
5. Kockázatok és Függőségek
| Kockázat | Hatás | Valószínűség | Mérséklés |
|---|---|---|---|
Vue komponensekben elszórt $t('szekcio.kulcs') hívások eltörnek az átnevezés után |
Magas | Közepes | Codebase search ($t() minden hívásra, fokozatos átállás |
| Lazy loading miatt inicializálási késleltetés | Alacsony | Alacsony | common fájl előtöltése |
| Backend és frontend közötti nyelvi kód inkonzisztencia | Közepes | Alacsony | Mindkét oldalon azonos ISO kódok használata |
| Új nyelv hozzáadásánál a teljes admin felület nem lesz lefordítva | Közepes | Magas | Részleges fordítási státusz jelzése, angol fallback működik |
6. Összefoglaló
A jelenlegi admin i18n rendszer funkcionálisan működik, de strukturálisan optimalizálatlan:
- ~50%-os kulcs-duplikáció a
commonszekció hiánya miatt - Skálázhatatlan - a monolit JSON fájlok 800+ sorosak, nehezen karbantarthatók
- Csak 2 nyelv - a régi frontend már 6 nyelvet ismert, az admin le van maradva
- Kétállású kapcsoló - nem bővíthető 3+ nyelvre
A javasolt restructuring:
- Bevezeti a központi
commonszekciót (30+ általános kulcs) - Oldalakra bontja a monolit fájlokat (lazy loading)
- Dropdown nyelvválasztóra cseréli a kapcsolót
- Előkészíti a terepet 6+ nyelv támogatásához
- Backend szinkronban marad a frontenddel