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

@@ -0,0 +1,23 @@
ALTER TABLE community.vocab_course_lesson
ADD COLUMN IF NOT EXISTS didactic_mode TEXT,
ADD COLUMN IF NOT EXISTS phase_label TEXT,
ADD COLUMN IF NOT EXISTS block_number INTEGER,
ADD COLUMN IF NOT EXISTS difficulty_weight INTEGER,
ADD COLUMN IF NOT EXISTS new_unit_target INTEGER,
ADD COLUMN IF NOT EXISTS review_weight INTEGER,
ADD COLUMN IF NOT EXISTS is_intensive_review BOOLEAN NOT NULL DEFAULT FALSE;
COMMENT ON COLUMN community.vocab_course_lesson.didactic_mode IS
'Didaktischer Modus der Lektion, z.B. core_input, guided_dialogue, intensive_review oder checkpoint.';
COMMENT ON COLUMN community.vocab_course_lesson.phase_label IS
'Übergeordnete Lernphase, z.B. quickstart, daily_life oder stabilization.';
COMMENT ON COLUMN community.vocab_course_lesson.block_number IS
'Inhaltlicher Block für Konsolidierungs- und Wiederholungswellen.';
COMMENT ON COLUMN community.vocab_course_lesson.difficulty_weight IS
'Grobe relative Schwierigkeit der Lektion von leicht bis schwer.';
COMMENT ON COLUMN community.vocab_course_lesson.new_unit_target IS
'Empfohlene Zahl neuer Spracheinheiten in dieser Lektion.';
COMMENT ON COLUMN community.vocab_course_lesson.review_weight IS
'Wie stark Wiederholung in dieser Lektion dominieren soll, typischerweise 0 bis 100.';
COMMENT ON COLUMN community.vocab_course_lesson.is_intensive_review IS
'Markiert Lektionen, die als intensive Wiederholungsphase gedacht sind.';

View File

@@ -0,0 +1,147 @@
UPDATE community.vocab_course_lesson AS lesson
SET
phase_label = CASE lesson.lesson_number
WHEN 1 THEN 'quickstart'
WHEN 2 THEN 'quickstart'
WHEN 3 THEN 'quickstart'
WHEN 4 THEN 'quickstart'
WHEN 5 THEN 'quickstart'
WHEN 6 THEN 'quickstart'
WHEN 7 THEN 'quickstart'
WHEN 8 THEN 'quickstart'
WHEN 9 THEN 'quickstart'
WHEN 10 THEN 'quickstart'
WHEN 11 THEN 'quickstart'
WHEN 12 THEN 'quickstart'
WHEN 13 THEN 'quickstart'
WHEN 14 THEN 'quickstart'
WHEN 15 THEN 'quickstart'
WHEN 16 THEN 'quickstart'
WHEN 17 THEN 'quickstart'
WHEN 18 THEN 'quickstart'
WHEN 19 THEN 'quickstart'
WHEN 20 THEN 'quickstart'
WHEN 21 THEN 'daily_life'
WHEN 22 THEN 'daily_life'
WHEN 23 THEN 'daily_life'
WHEN 24 THEN 'daily_life'
WHEN 25 THEN 'daily_life'
WHEN 26 THEN 'daily_life'
WHEN 27 THEN 'daily_life'
WHEN 28 THEN 'daily_life'
WHEN 29 THEN 'daily_life'
WHEN 30 THEN 'daily_life'
WHEN 31 THEN 'stabilization'
WHEN 32 THEN 'stabilization'
WHEN 33 THEN 'stabilization'
WHEN 34 THEN 'stabilization'
WHEN 35 THEN 'stabilization'
WHEN 36 THEN 'stabilization'
WHEN 37 THEN 'stabilization'
WHEN 38 THEN 'stabilization'
WHEN 39 THEN 'stabilization'
WHEN 40 THEN 'stabilization'
ELSE lesson.phase_label
END,
block_number = CASE lesson.lesson_number
WHEN 1 THEN 1 WHEN 2 THEN 1 WHEN 3 THEN 1 WHEN 4 THEN 1 WHEN 5 THEN 1
WHEN 6 THEN 1 WHEN 7 THEN 1 WHEN 8 THEN 1 WHEN 9 THEN 1 WHEN 10 THEN 1
WHEN 11 THEN 2 WHEN 12 THEN 2 WHEN 13 THEN 2 WHEN 14 THEN 2 WHEN 15 THEN 2
WHEN 16 THEN 2 WHEN 17 THEN 2 WHEN 18 THEN 2 WHEN 19 THEN 2 WHEN 20 THEN 2
WHEN 21 THEN 3 WHEN 22 THEN 3 WHEN 23 THEN 3 WHEN 24 THEN 3 WHEN 25 THEN 3
WHEN 26 THEN 3 WHEN 27 THEN 3 WHEN 28 THEN 3 WHEN 29 THEN 3 WHEN 30 THEN 3
WHEN 31 THEN 4 WHEN 32 THEN 4 WHEN 33 THEN 4 WHEN 34 THEN 4 WHEN 35 THEN 4
WHEN 36 THEN 4 WHEN 37 THEN 4 WHEN 38 THEN 4 WHEN 39 THEN 4 WHEN 40 THEN 4
ELSE lesson.block_number
END,
didactic_mode = CASE lesson.lesson_number
WHEN 1 THEN 'guided_dialogue'
WHEN 2 THEN 'core_input'
WHEN 3 THEN 'core_input'
WHEN 4 THEN 'guided_dialogue'
WHEN 5 THEN 'guided_dialogue'
WHEN 6 THEN 'core_input'
WHEN 7 THEN 'guided_dialogue'
WHEN 8 THEN 'core_input'
WHEN 9 THEN 'intensive_review'
WHEN 10 THEN 'checkpoint'
WHEN 11 THEN 'guided_dialogue'
WHEN 12 THEN 'core_input'
WHEN 13 THEN 'guided_dialogue'
WHEN 14 THEN 'core_input'
WHEN 15 THEN 'pattern_drill'
WHEN 16 THEN 'core_input'
WHEN 17 THEN 'guided_dialogue'
WHEN 18 THEN 'core_input'
WHEN 19 THEN 'intensive_review'
WHEN 20 THEN 'checkpoint'
WHEN 21 THEN 'guided_dialogue'
WHEN 22 THEN 'core_input'
WHEN 23 THEN 'guided_dialogue'
WHEN 24 THEN 'core_input'
WHEN 25 THEN 'pattern_drill'
WHEN 26 THEN 'guided_dialogue'
WHEN 27 THEN 'guided_dialogue'
WHEN 28 THEN 'core_input'
WHEN 29 THEN 'intensive_review'
WHEN 30 THEN 'checkpoint'
WHEN 31 THEN 'real_life_scenario'
WHEN 32 THEN 'intensive_review'
WHEN 33 THEN 'real_life_scenario'
WHEN 34 THEN 'intensive_review'
WHEN 35 THEN 'real_life_scenario'
WHEN 36 THEN 'intensive_review'
WHEN 37 THEN 'real_life_scenario'
WHEN 38 THEN 'checkpoint'
WHEN 39 THEN 'checkpoint'
WHEN 40 THEN 'real_life_scenario'
ELSE lesson.didactic_mode
END,
difficulty_weight = CASE lesson.lesson_number
WHEN 1 THEN 2 WHEN 2 THEN 3 WHEN 3 THEN 2 WHEN 4 THEN 3 WHEN 5 THEN 3
WHEN 6 THEN 3 WHEN 7 THEN 3 WHEN 8 THEN 2 WHEN 9 THEN 3 WHEN 10 THEN 3
WHEN 11 THEN 3 WHEN 12 THEN 2 WHEN 13 THEN 3 WHEN 14 THEN 3 WHEN 15 THEN 4
WHEN 16 THEN 3 WHEN 17 THEN 4 WHEN 18 THEN 4 WHEN 19 THEN 4 WHEN 20 THEN 4
WHEN 21 THEN 3 WHEN 22 THEN 3 WHEN 23 THEN 4 WHEN 24 THEN 4 WHEN 25 THEN 4
WHEN 26 THEN 4 WHEN 27 THEN 3 WHEN 28 THEN 3 WHEN 29 THEN 4 WHEN 30 THEN 4
WHEN 31 THEN 4 WHEN 32 THEN 4 WHEN 33 THEN 4 WHEN 34 THEN 4 WHEN 35 THEN 5
WHEN 36 THEN 5 WHEN 37 THEN 5 WHEN 38 THEN 5 WHEN 39 THEN 5 WHEN 40 THEN 2
ELSE lesson.difficulty_weight
END,
new_unit_target = CASE lesson.lesson_number
WHEN 1 THEN 5 WHEN 2 THEN 8 WHEN 3 THEN 7 WHEN 4 THEN 5 WHEN 5 THEN 4
WHEN 6 THEN 7 WHEN 7 THEN 5 WHEN 8 THEN 6 WHEN 9 THEN 0 WHEN 10 THEN 0
WHEN 11 THEN 5 WHEN 12 THEN 7 WHEN 13 THEN 5 WHEN 14 THEN 6 WHEN 15 THEN 4
WHEN 16 THEN 6 WHEN 17 THEN 5 WHEN 18 THEN 7 WHEN 19 THEN 0 WHEN 20 THEN 0
WHEN 21 THEN 5 WHEN 22 THEN 7 WHEN 23 THEN 5 WHEN 24 THEN 6 WHEN 25 THEN 4
WHEN 26 THEN 5 WHEN 27 THEN 5 WHEN 28 THEN 6 WHEN 29 THEN 0 WHEN 30 THEN 0
WHEN 31 THEN 4 WHEN 32 THEN 0 WHEN 33 THEN 4 WHEN 34 THEN 0 WHEN 35 THEN 3
WHEN 36 THEN 0 WHEN 37 THEN 3 WHEN 38 THEN 0 WHEN 39 THEN 0 WHEN 40 THEN 2
ELSE lesson.new_unit_target
END,
review_weight = CASE lesson.lesson_number
WHEN 1 THEN 15 WHEN 2 THEN 20 WHEN 3 THEN 20 WHEN 4 THEN 25 WHEN 5 THEN 25
WHEN 6 THEN 25 WHEN 7 THEN 30 WHEN 8 THEN 30 WHEN 9 THEN 90 WHEN 10 THEN 95
WHEN 11 THEN 25 WHEN 12 THEN 25 WHEN 13 THEN 30 WHEN 14 THEN 30 WHEN 15 THEN 40
WHEN 16 THEN 35 WHEN 17 THEN 35 WHEN 18 THEN 35 WHEN 19 THEN 92 WHEN 20 THEN 96
WHEN 21 THEN 35 WHEN 22 THEN 35 WHEN 23 THEN 40 WHEN 24 THEN 40 WHEN 25 THEN 45
WHEN 26 THEN 45 WHEN 27 THEN 40 WHEN 28 THEN 40 WHEN 29 THEN 94 WHEN 30 THEN 97
WHEN 31 THEN 55 WHEN 32 THEN 95 WHEN 33 THEN 60 WHEN 34 THEN 95 WHEN 35 THEN 65
WHEN 36 THEN 98 WHEN 37 THEN 70 WHEN 38 THEN 99 WHEN 39 THEN 100 WHEN 40 THEN 50
ELSE lesson.review_weight
END,
is_intensive_review = CASE lesson.lesson_number
WHEN 9 THEN TRUE
WHEN 19 THEN TRUE
WHEN 29 THEN TRUE
WHEN 32 THEN TRUE
WHEN 34 THEN TRUE
WHEN 36 THEN TRUE
ELSE FALSE
END
FROM community.vocab_course AS course
JOIN community.vocab_language AS language
ON language.id = course.language_id
WHERE lesson.course_id = course.id
AND language.name = 'Bisaya'
AND lesson.lesson_number BETWEEN 1 AND 40;

View File

@@ -0,0 +1,12 @@
UPDATE community.vocab_course AS course
SET
title = 'Bisaya für Familien - Schnellstart in 6 Wochen',
description = 'Lerne Bisaya (Cebuano) schnell und praktisch für den Familienalltag. Fokus auf Sprechen, Hören, Spiralwiederholung und einem strukturierten 6-Wochen-Plan.'
FROM community.vocab_language AS language
WHERE course.language_id = language.id
AND language.name = 'Bisaya';
-- Für die eigentlichen neuen Lektionen 41-60 wird das Skript
-- backend/scripts/extend-bisaya-course-phase3.js empfohlen, weil dort
-- auch JSON-Felder wie learning_goals, core_patterns, grammar_focus,
-- speaking_prompts und practical_tasks konsistent gepflegt werden.

View File

@@ -0,0 +1,11 @@
UPDATE community.vocab_course AS course
SET
title = 'Bisaya für Familien - Alltag in 3 Monaten',
description = 'Lerne Bisaya (Cebuano) praxisnah für den Familienalltag. Fokus auf Sprechen, Hören, Spiralwiederholung und einem strukturierten 3-Monats-Pfad vom Schnellstart bis zur stabilen Alltagskommunikation.'
FROM community.vocab_language AS language
WHERE course.language_id = language.id
AND language.name = 'Bisaya';
-- Für die neuen Lektionen 61-120 wird das Skript
-- backend/scripts/extend-bisaya-course-phase4.js empfohlen, weil dort
-- auch die JSON-Felder der Lektionen konsistent gepflegt werden.

View File

@@ -0,0 +1,11 @@
UPDATE community.vocab_course AS course
SET
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.'
FROM community.vocab_language AS language
WHERE course.language_id = language.id
AND language.name = 'Bisaya';
-- Für die neuen Lektionen 121-150 wird das Skript
-- backend/scripts/extend-bisaya-course-phase5.js empfohlen, weil dort
-- auch die JSON-Felder der Lektionen konsistent gepflegt werden.