feat(admin): add potential fathers retrieval for character management
All checks were successful
Deploy to production / deploy (push) Successful in 2m47s

- Implemented a new method in AdminService to fetch potential fathers for a given character based on existing relationships.
- Updated AdminController to expose this functionality via a new API endpoint.
- Enhanced adminRouter to include the route for retrieving potential fathers.
- Modified frontend components to allow selection of potential fathers during pregnancy and birth management.
- Updated internationalization files to include new translation keys related to father selection.
This commit is contained in:
Torsten Schulz (local)
2026-03-31 08:50:56 +02:00
parent ee11a989a0
commit 9a78bc7c4b
30 changed files with 3907 additions and 45 deletions

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env node
/**
* Script zum Erstellen eines vollständigen 4-Wochen Bisaya-Kurses
* Script zum Erstellen eines vollständigen 6-Wochen Bisaya-Kurses
*
* Verwendung:
* node backend/scripts/create-bisaya-course.js <languageId> <ownerHashedId>
@@ -11,6 +11,10 @@ import VocabCourse from '../models/community/vocab_course.js';
import VocabCourseLesson from '../models/community/vocab_course_lesson.js';
import User from '../models/community/user.js';
import crypto from 'crypto';
import { getBisayaLessonPedagogy } from './bisaya-course-phase2-pedagogy.js';
import { BISAYA_PHASE3_DIDACTICS, BISAYA_PHASE3_LESSONS } from './bisaya-course-phase3-extension.js';
import { BISAYA_PHASE4_DIDACTICS, BISAYA_PHASE4_LESSONS } from './bisaya-course-phase4-extension.js';
import { BISAYA_PHASE5_DIDACTICS, BISAYA_PHASE5_LESSONS } from './bisaya-course-phase5-extension.js';
const LESSON_DIDACTICS = {
'Begrüßungen & Höflichkeit': {
@@ -192,7 +196,10 @@ const LESSON_DIDACTICS = {
'Lami',
'Mingaw ko nimo'
]
}
},
...BISAYA_PHASE3_DIDACTICS,
...BISAYA_PHASE4_DIDACTICS,
...BISAYA_PHASE5_DIDACTICS
};
const LESSONS = [
@@ -398,7 +405,11 @@ const LESSONS = [
{ week: 4, day: 5, num: 40, type: 'culture', title: 'Kulturelle Tipps & Tricks',
desc: 'Wichtige kulturelle Hinweise für den Alltag',
targetMin: 15, targetScore: 0, review: false,
cultural: 'Kulturelles Verständnis ist genauso wichtig wie die Sprache selbst.' }
cultural: 'Kulturelles Verständnis ist genauso wichtig wie die Sprache selbst.' },
...BISAYA_PHASE3_LESSONS,
...BISAYA_PHASE4_LESSONS,
...BISAYA_PHASE5_LESSONS
];
async function createBisayaCourse(languageId, ownerHashedId) {
@@ -422,8 +433,8 @@ async function createBisayaCourse(languageId, ownerHashedId) {
const shareCode = crypto.randomBytes(8).toString('hex');
const course = await VocabCourse.create({
ownerUserId: user.id,
title: 'Bisaya für Familien - Schnellstart in 4 Wochen',
description: 'Lerne Bisaya (Cebuano) schnell und praktisch für den Familienalltag. Fokus auf Sprechen & Hören mit strukturiertem 4-Wochen-Plan.',
title: 'Bisaya für Familien - Alltag & Stabilisierung',
description: 'Lerne Bisaya (Cebuano) praxisnah für den Familienalltag. Der Pfad verbindet Schnellstart, Alltagsmodule und Stabilisierungsblöcke mit Spiralwiederholung, Fehlertraining und freier Produktion.',
languageId: Number(languageId),
difficultyLevel: 1,
isPublic: true,
@@ -435,6 +446,7 @@ async function createBisayaCourse(languageId, ownerHashedId) {
// Erstelle Lektionen
for (const lessonData of LESSONS) {
const pedagogy = getBisayaLessonPedagogy(lessonData.num) || {};
const lesson = await VocabCourseLesson.create({
courseId: course.id,
chapterId: null, // Wird später mit Vokabeln verknüpft
@@ -452,7 +464,14 @@ async function createBisayaCourse(languageId, ownerHashedId) {
practicalTasks: LESSON_DIDACTICS[lessonData.title]?.practicalTasks || [],
targetMinutes: lessonData.targetMin,
targetScorePercent: lessonData.targetScore,
requiresReview: lessonData.review
requiresReview: lessonData.review,
didacticMode: pedagogy.didacticMode || null,
phaseLabel: pedagogy.phaseLabel || null,
blockNumber: pedagogy.blockNumber ?? null,
difficultyWeight: pedagogy.difficultyWeight ?? null,
newUnitTarget: pedagogy.newUnitTarget ?? null,
reviewWeight: pedagogy.reviewWeight ?? null,
isIntensiveReview: Boolean(pedagogy.isIntensiveReview)
});
console.log(` ✅ Lektion ${lessonData.num}: ${lessonData.title} (Woche ${lessonData.week}, Tag ${lessonData.day})`);
}
@@ -464,7 +483,7 @@ async function createBisayaCourse(languageId, ownerHashedId) {
console.log(` - Konversations-Lektionen: ${LESSONS.filter(l => l.type === 'conversation').length}`);
console.log(` - Grammatik-Lektionen: ${LESSONS.filter(l => l.type === 'grammar').length}`);
console.log(` - Wiederholungs-Lektionen: ${LESSONS.filter(l => l.type === 'review').length}`);
console.log(` - Durchschnittliche Zeit pro Tag: ~${Math.round(LESSONS.reduce((sum, l) => sum + l.targetMin, 0) / (4 * 5))} Minuten`);
console.log(` - Durchschnittliche Zeit pro Tag: ~${Math.round(LESSONS.reduce((sum, l) => sum + l.targetMin, 0) / (15 * 5))} Minuten`);
console.log(`\n💡 Nächste Schritte:`);
console.log(` 1. Füge Vokabeln zu den Vokabel-Lektionen hinzu`);
console.log(` 2. Erstelle Grammatik-Übungen für die Grammatik-Lektionen`);