Fehldende messages hinzugefügt
All checks were successful
Deploy to production / deploy (push) Successful in 2m14s

This commit is contained in:
Torsten Schulz (local)
2026-06-09 12:05:10 +02:00
parent 01c2f230a9
commit b22e1923cd
2 changed files with 59 additions and 26 deletions

View File

@@ -8961,9 +8961,45 @@ function serializeNotificationForClient(row) {
const j = typeof row.toJSON === 'function' ? row.toJSON() : { ...row }; const j = typeof row.toJSON === 'function' ? row.toJSON() : { ...row };
const dv = row.dataValues || {}; const dv = row.dataValues || {};
if (dv.region_name != null && j.region_name == null) j.region_name = dv.region_name; if (dv.region_name != null && j.region_name == null) j.region_name = dv.region_name;
j.tr = normalizeNotificationTrForClient(j.tr);
return j; return j;
} }
function parseNotificationTrPayload(tr) {
if (tr && typeof tr === 'object') return tr;
if (typeof tr !== 'string') return null;
const trimmed = tr.trim();
if (!trimmed) return null;
const jsonStart = trimmed.indexOf('{');
if (jsonStart < 0) return null;
try {
const parsed = JSON.parse(trimmed.slice(jsonStart));
return parsed && typeof parsed === 'object' ? parsed : null;
} catch {
return null;
}
}
function isMissingNotificationTrKey(value) {
if (value == null) return true;
const text = String(value).trim();
return !text || text === 'falukant.notifications.' || text === 'notifications.';
}
function normalizeNotificationTrForClient(tr) {
const parsed = parseNotificationTrPayload(tr);
if (!parsed) return tr;
const normalized = { ...parsed };
if (isMissingNotificationTrKey(normalized.tr) && normalized.event) {
normalized.tr = String(normalized.event);
}
return JSON.stringify(normalized);
}
// Helper: parse notifications for character references and attach characterName // Helper: parse notifications for character references and attach characterName
async function enrichNotificationsWithCharacterNames(notifications) { async function enrichNotificationsWithCharacterNames(notifications) {
if (!Array.isArray(notifications) || notifications.length === 0) return; if (!Array.isArray(notifications) || notifications.length === 0) return;
@@ -8999,18 +9035,8 @@ async function enrichNotificationsWithCharacterNames(notifications) {
// First pass: collect all referenced character ids and region ids from notifications // First pass: collect all referenced character ids and region ids from notifications
for (const n of notifications) { for (const n of notifications) {
let parsed = null; const parsed = parseNotificationTrPayload(n.tr);
try { if (parsed) collectIds(parsed);
if (typeof n.tr === 'string' && n.tr.trim().startsWith('{')) {
parsed = JSON.parse(n.tr);
collectIds(parsed);
} else if (n.tr && typeof n.tr === 'object') {
parsed = n.tr;
collectIds(parsed);
}
} catch (err) {
parsed = null;
}
if (parsed?.region_id != null) { if (parsed?.region_id != null) {
regionIds.add(Number(parsed.region_id)); regionIds.add(Number(parsed.region_id));
} }
@@ -9093,16 +9119,7 @@ async function enrichNotificationsWithCharacterNames(notifications) {
// Attach resolved name to notifications (set character_name; characterName is a getter that reads from it) // Attach resolved name to notifications (set character_name; characterName is a getter that reads from it)
for (const n of notifications) { for (const n of notifications) {
let parsed = null; const parsed = parseNotificationTrPayload(n.tr);
try {
if (typeof n.tr === 'string' && n.tr.trim().startsWith('{')) {
parsed = JSON.parse(n.tr);
} else if (n.tr && typeof n.tr === 'object') {
parsed = n.tr;
}
} catch (err) {
parsed = null;
}
let foundId = null; let foundId = null;
if (parsed?.director_character_id != null) { if (parsed?.director_character_id != null) {

View File

@@ -143,11 +143,15 @@ export default {
} }
if (typeof raw === 'string') { if (typeof raw === 'string') {
const trimmed = raw.trim(); const trimmed = raw.trim();
if (trimmed.startsWith('{') && trimmed.endsWith('}')) { const jsonStart = trimmed.indexOf('{');
if (jsonStart >= 0 && trimmed.endsWith('}')) {
try { try {
const parsed = JSON.parse(trimmed); const parsed = JSON.parse(trimmed.slice(jsonStart));
if (parsed && typeof parsed === 'object') { if (parsed && typeof parsed === 'object') {
merged = { ...merged, ...parsed }; merged = { ...merged, ...parsed };
if (!parsed.tr && parsed.event && /^falukant\.notifications\.\s*\{/.test(trimmed)) {
merged.tr = parsed.event;
}
} }
} catch { } catch {
/* Rohstring bleibt in merged.tr */ /* Rohstring bleibt in merged.tr */
@@ -175,17 +179,29 @@ export default {
let raw = payload.tr || ''; let raw = payload.tr || '';
let key = raw; let key = raw;
let params = {}; let params = {};
const isMissingNotificationKey = (value) => {
if (value == null) return true;
const text = String(value).trim();
return !text || text === 'falukant.notifications.' || text === 'notifications.';
};
// Fallback: Manche Daemon-Events liefern event_id/event_type, aber kein tr. // Fallback: Manche Daemon-Events liefern event_id/event_type, aber kein tr.
if ((!raw || !String(raw).trim()) && payload?.event_id) { if (isMissingNotificationKey(raw) && payload?.event_id) {
raw = payload.event_type === 'random_event' raw = payload.event_type === 'random_event'
? `random_event.${payload.event_id}` ? `random_event.${payload.event_id}`
: String(payload.event_id); : String(payload.event_id);
key = raw; key = raw;
} }
// Fallback: direkte Daemon-Events wie director_death liefern den Typ
// im Feld event, waehrend tr historisch leer oder nur der Namespace sein kann.
if (isMissingNotificationKey(raw) && payload?.event) {
raw = String(payload.event);
key = raw;
}
// Fallback: use payload.type if present (e.g. storage_damage) // Fallback: use payload.type if present (e.g. storage_damage)
if ((!raw || !String(raw).trim()) && payload?.type) { if (isMissingNotificationKey(raw) && payload?.type) {
raw = String(payload.type); raw = String(payload.type);
key = raw; key = raw;
} }