diff --git a/deploy-frontend.sh b/deploy-frontend.sh index 3ad9b70..940258c 100755 --- a/deploy-frontend.sh +++ b/deploy-frontend.sh @@ -57,9 +57,12 @@ echo "✅ Build erfolgreich!" echo "Erstelle Zielverzeichnis..." sudo mkdir -p /opt/yourpart/frontend/dist -# 7. Altes Frontend löschen -echo "Lösche altes Frontend..." -sudo rm -rf /opt/yourpart/frontend/dist +# 7. Sicheres Backup des alten Frontends (timestamped). Vermeidet Datenverlust bei Fehlern. +if [ -d "/opt/yourpart/frontend/dist" ]; then + TIMESTAMP=$(date +%Y%m%d-%H%M%S) + echo "Erstelle Backup von altem Frontend nach /opt/yourpart/frontend/dist.backup.$TIMESTAMP" + sudo mv /opt/yourpart/frontend/dist /opt/yourpart/frontend/dist.backup.$TIMESTAMP || true +fi # 8. Zielverzeichnis neu erstellen echo "Erstelle Zielverzeichnis neu..." diff --git a/frontend/src/dialogues/socialnetwork/VocabPracticeDialog.vue b/frontend/src/dialogues/socialnetwork/VocabPracticeDialog.vue index 8988a9e..0b816d1 100644 --- a/frontend/src/dialogues/socialnetwork/VocabPracticeDialog.vue +++ b/frontend/src/dialogues/socialnetwork/VocabPracticeDialog.vue @@ -697,24 +697,35 @@ export default { return [{ ...item, learning, reference }]; }, normalizePool(items = []) { - const seen = new Set(); - return (Array.isArray(items) ? items : []) - .flatMap((item, index) => this.expandPoolItemAlternatives(item).map((candidate, altIndex) => ({ candidate, index, altIndex }))) - .map(({ candidate, index, altIndex }) => { - const learning = String(candidate?.learning || '').trim(); - const reference = String(candidate?.reference || '').trim(); - if (!this.isTrainablePair(learning, reference)) return null; - const key = `${this.normalize(learning)}|${this.normalize(reference)}`; - if (seen.has(key)) return null; - seen.add(key); - return { - ...candidate, - id: candidate?.id || candidate?.itemKey || candidate?.key || `${key}|${index}|${altIndex}`, - learning, - reference - }; - }) - .filter(Boolean); + try { + const inputLen = Array.isArray(items) ? items.length : 0; + const seen = new Set(); + const expanded = (Array.isArray(items) ? items : []) + .flatMap((item, index) => this.expandPoolItemAlternatives(item).map((candidate, altIndex) => ({ candidate, index, altIndex }))); + + const mapped = expanded + .map(({ candidate, index, altIndex }) => { + const learning = String(candidate?.learning || '').trim(); + const reference = String(candidate?.reference || '').trim(); + if (!this.isTrainablePair(learning, reference)) return null; + const key = `${this.normalize(learning)}|${this.normalize(reference)}`; + if (seen.has(key)) return null; + seen.add(key); + return { + ...candidate, + id: candidate?.id || candidate?.itemKey || candidate?.key || `${key}|${index}|${altIndex}`, + learning, + reference + }; + }); + + const result = mapped.filter(Boolean); + try { console.debug('[VocabPracticeDialog] normalizePool', { inputLen, outLen: result.length, sample: result.slice(0,5) }); } catch (_) {} + return result; + } catch (e) { + console.warn('[VocabPracticeDialog] normalizePool failed', e); + return []; + } }, resetQuestion() { this.current = null;