f22c5ebbfe
- PHP/MySQL Backend (XAMPP + Produktionsserver) - Front-Controller, API-Endpunkte, Session-Management - Flussmanagement-Simulation (Echtzeit, Punkt-basierter Fluss) - Stadt & Raumplanung (Prototyp, Top-Down Kachelsystem) - Klimawaechter 3D: Deiche kleiner, Baeume kippen, Budget angepasst - persistence.ts: Dualer Speicher (localStorage + Server-API) - 6 Unit-Test-Dateien fuer bestehende Simulationen Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
187 lines
9.6 KiB
TypeScript
187 lines
9.6 KiB
TypeScript
/**
|
||
* Bildungsstufen-Konfiguration
|
||
*
|
||
* Abstrahiert von länderspezifischen Bezeichnungen.
|
||
* Pro App-Instanz wird ein Land/Region konfiguriert,
|
||
* das die Zuordnung von internen Leveln zu lokalen Bezeichnungen steuert.
|
||
*
|
||
* Intern arbeiten wir mit:
|
||
* - `educationLevel`: 1–13 (= Schulstufe/Schuljahr, international vergleichbar)
|
||
* - `ageRange`: Alter der Zielgruppe
|
||
* - `readingLevel`: Lesekompetenz (none, basic, fluent)
|
||
*
|
||
* In der Entwicklung entscheiden wir pro Simulation:
|
||
* - Welche educationLevels werden unterstützt?
|
||
* - Braucht es eine Variante ohne Lesen (Grundstufe 1)?
|
||
* - Welche Sprachkomplexität ist angemessen?
|
||
*/
|
||
|
||
export type ReadingLevel = 'none' | 'basic' | 'fluent'
|
||
|
||
export interface EducationLevel {
|
||
/** Internationale Schulstufe (1 = 1. Schuljahr, 5 = 5. Schuljahr etc.) */
|
||
level: number
|
||
/** Typisches Alter */
|
||
ageMin: number
|
||
ageMax: number
|
||
/** Erwartete Lesekompetenz */
|
||
reading: ReadingLevel
|
||
/** Kann komplexe Texte verarbeiten? */
|
||
canProcessComplexText: boolean
|
||
}
|
||
|
||
export interface CountryConfig {
|
||
id: string
|
||
name: string
|
||
/** Zuordnung: lokale Bezeichnung → internationale Schulstufe */
|
||
stages: CountryStage[]
|
||
/** Welche Schulstufen deckt unser Produkt primär ab? */
|
||
primaryRange: { from: number; to: number }
|
||
/** Optionale Erweiterung (z.B. Volksschule) */
|
||
extendedRange?: { from: number; to: number }
|
||
}
|
||
|
||
export interface CountryStage {
|
||
/** Internationale Schulstufe */
|
||
level: number
|
||
/** Lokale Bezeichnung (z.B. "1. Klasse Mittelschule") */
|
||
localName: string
|
||
/** Kurzform (z.B. "1. Kl. MS") */
|
||
shortName: string
|
||
/** Schultyp-Bezeichnung */
|
||
schoolType: string
|
||
/** Fachbezeichnung für Geografie in dieser Stufe */
|
||
subjectName: string
|
||
/** Wochenstunden GW (falls bekannt) */
|
||
hoursPerWeek?: number
|
||
}
|
||
|
||
// ============================================================
|
||
// Länderkonfigurationen
|
||
// ============================================================
|
||
|
||
export const AUSTRIA: CountryConfig = {
|
||
id: 'at',
|
||
name: 'Österreich',
|
||
primaryRange: { from: 5, to: 8 }, // Mittelschule / AHS-Unterstufe
|
||
extendedRange: { from: 1, to: 4 }, // Volksschule (Sachunterricht)
|
||
stages: [
|
||
// Volksschule (optional, für spätere Erweiterung)
|
||
{ level: 1, localName: '1. Klasse Volksschule', shortName: '1. VS', schoolType: 'Volksschule', subjectName: 'Sachunterricht', hoursPerWeek: undefined },
|
||
{ level: 2, localName: '2. Klasse Volksschule', shortName: '2. VS', schoolType: 'Volksschule', subjectName: 'Sachunterricht', hoursPerWeek: undefined },
|
||
{ level: 3, localName: '3. Klasse Volksschule', shortName: '3. VS', schoolType: 'Volksschule', subjectName: 'Sachunterricht', hoursPerWeek: undefined },
|
||
{ level: 4, localName: '4. Klasse Volksschule', shortName: '4. VS', schoolType: 'Volksschule', subjectName: 'Sachunterricht', hoursPerWeek: undefined },
|
||
// Mittelschule / AHS-Unterstufe (= unser Hauptfokus)
|
||
{ level: 5, localName: '1. Klasse', shortName: '1. Kl.', schoolType: 'Mittelschule / AHS-Unterstufe', subjectName: 'Geografie und wirtschaftliche Bildung', hoursPerWeek: 2 },
|
||
{ level: 6, localName: '2. Klasse', shortName: '2. Kl.', schoolType: 'Mittelschule / AHS-Unterstufe', subjectName: 'Geografie und wirtschaftliche Bildung', hoursPerWeek: 1 },
|
||
{ level: 7, localName: '3. Klasse', shortName: '3. Kl.', schoolType: 'Mittelschule / AHS-Unterstufe', subjectName: 'Geografie und wirtschaftliche Bildung', hoursPerWeek: 2 },
|
||
{ level: 8, localName: '4. Klasse', shortName: '4. Kl.', schoolType: 'Mittelschule / AHS-Unterstufe', subjectName: 'Geografie und wirtschaftliche Bildung', hoursPerWeek: 2 },
|
||
],
|
||
}
|
||
|
||
export const GERMANY_BAYERN: CountryConfig = {
|
||
id: 'de-by',
|
||
name: 'Deutschland (Bayern)',
|
||
primaryRange: { from: 5, to: 10 },
|
||
stages: [
|
||
{ level: 5, localName: '5. Jahrgangsstufe', shortName: '5. Jgst.', schoolType: 'Gymnasium / Realschule', subjectName: 'Geographie', hoursPerWeek: 2 },
|
||
{ level: 6, localName: '6. Jahrgangsstufe', shortName: '6. Jgst.', schoolType: 'Gymnasium / Realschule', subjectName: 'Geographie', hoursPerWeek: 0 },
|
||
{ level: 7, localName: '7. Jahrgangsstufe', shortName: '7. Jgst.', schoolType: 'Gymnasium / Realschule', subjectName: 'Geographie', hoursPerWeek: 2 },
|
||
{ level: 8, localName: '8. Jahrgangsstufe', shortName: '8. Jgst.', schoolType: 'Gymnasium / Realschule', subjectName: 'Geographie', hoursPerWeek: 2 },
|
||
{ level: 9, localName: '9. Jahrgangsstufe', shortName: '9. Jgst.', schoolType: 'Gymnasium / Realschule', subjectName: 'Geographie', hoursPerWeek: 0 },
|
||
{ level: 10, localName: '10. Jahrgangsstufe', shortName: '10. Jgst.', schoolType: 'Gymnasium / Realschule', subjectName: 'Geographie', hoursPerWeek: 2 },
|
||
],
|
||
}
|
||
|
||
export const GERMANY_NRW: CountryConfig = {
|
||
id: 'de-nrw',
|
||
name: 'Deutschland (NRW)',
|
||
primaryRange: { from: 5, to: 10 },
|
||
stages: [
|
||
{ level: 5, localName: 'Klasse 5', shortName: 'Kl. 5', schoolType: 'Gymnasium / Gesamtschule', subjectName: 'Erdkunde', hoursPerWeek: 2 },
|
||
{ level: 6, localName: 'Klasse 6', shortName: 'Kl. 6', schoolType: 'Gymnasium / Gesamtschule', subjectName: 'Erdkunde', hoursPerWeek: 2 },
|
||
{ level: 7, localName: 'Klasse 7', shortName: 'Kl. 7', schoolType: 'Gymnasium / Gesamtschule', subjectName: 'Erdkunde', hoursPerWeek: 2 },
|
||
{ level: 8, localName: 'Klasse 8', shortName: 'Kl. 8', schoolType: 'Gymnasium / Gesamtschule', subjectName: 'Erdkunde', hoursPerWeek: 1 },
|
||
{ level: 9, localName: 'Klasse 9', shortName: 'Kl. 9', schoolType: 'Gymnasium / Gesamtschule', subjectName: 'Erdkunde', hoursPerWeek: 2 },
|
||
{ level: 10, localName: 'Klasse 10', shortName: 'Kl. 10', schoolType: 'Gymnasium / Gesamtschule', subjectName: 'Erdkunde', hoursPerWeek: 1 },
|
||
],
|
||
}
|
||
|
||
export const SWITZERLAND: CountryConfig = {
|
||
id: 'ch',
|
||
name: 'Schweiz',
|
||
primaryRange: { from: 7, to: 9 }, // Zyklus 3
|
||
extendedRange: { from: 3, to: 6 }, // Zyklus 2 (NMG)
|
||
stages: [
|
||
// Zyklus 2 (optional)
|
||
{ level: 3, localName: '3. Klasse', shortName: '3. Kl.', schoolType: 'Primarstufe', subjectName: 'Natur, Mensch, Gesellschaft', hoursPerWeek: undefined },
|
||
{ level: 4, localName: '4. Klasse', shortName: '4. Kl.', schoolType: 'Primarstufe', subjectName: 'Natur, Mensch, Gesellschaft', hoursPerWeek: undefined },
|
||
{ level: 5, localName: '5. Klasse', shortName: '5. Kl.', schoolType: 'Primarstufe', subjectName: 'Natur, Mensch, Gesellschaft', hoursPerWeek: undefined },
|
||
{ level: 6, localName: '6. Klasse', shortName: '6. Kl.', schoolType: 'Primarstufe', subjectName: 'Natur, Mensch, Gesellschaft', hoursPerWeek: undefined },
|
||
// Zyklus 3 (= unser Hauptfokus)
|
||
{ level: 7, localName: '1. Oberstufe', shortName: '1. OS', schoolType: 'Sekundarschule', subjectName: 'Räume, Zeiten, Gesellschaften', hoursPerWeek: 2 },
|
||
{ level: 8, localName: '2. Oberstufe', shortName: '2. OS', schoolType: 'Sekundarschule', subjectName: 'Räume, Zeiten, Gesellschaften', hoursPerWeek: 2 },
|
||
{ level: 9, localName: '3. Oberstufe', shortName: '3. OS', schoolType: 'Sekundarschule', subjectName: 'Räume, Zeiten, Gesellschaften', hoursPerWeek: 2 },
|
||
],
|
||
}
|
||
|
||
// ============================================================
|
||
// Education-Level-Definitionen (länderunabhängig)
|
||
// ============================================================
|
||
|
||
export const EDUCATION_LEVELS: EducationLevel[] = [
|
||
{ level: 1, ageMin: 6, ageMax: 7, reading: 'none', canProcessComplexText: false },
|
||
{ level: 2, ageMin: 7, ageMax: 8, reading: 'basic', canProcessComplexText: false },
|
||
{ level: 3, ageMin: 8, ageMax: 9, reading: 'basic', canProcessComplexText: false },
|
||
{ level: 4, ageMin: 9, ageMax: 10, reading: 'fluent', canProcessComplexText: false },
|
||
{ level: 5, ageMin: 10, ageMax: 11, reading: 'fluent', canProcessComplexText: false },
|
||
{ level: 6, ageMin: 11, ageMax: 12, reading: 'fluent', canProcessComplexText: true },
|
||
{ level: 7, ageMin: 12, ageMax: 13, reading: 'fluent', canProcessComplexText: true },
|
||
{ level: 8, ageMin: 13, ageMax: 14, reading: 'fluent', canProcessComplexText: true },
|
||
{ level: 9, ageMin: 14, ageMax: 15, reading: 'fluent', canProcessComplexText: true },
|
||
{ level: 10, ageMin: 15, ageMax: 16, reading: 'fluent', canProcessComplexText: true },
|
||
]
|
||
|
||
// ============================================================
|
||
// Alle verfügbaren Länder
|
||
// ============================================================
|
||
|
||
export const ALL_COUNTRIES: CountryConfig[] = [
|
||
AUSTRIA,
|
||
GERMANY_BAYERN,
|
||
GERMANY_NRW,
|
||
SWITZERLAND,
|
||
]
|
||
|
||
// ============================================================
|
||
// Helper-Funktionen
|
||
// ============================================================
|
||
|
||
/** Gibt die lokale Bezeichnung für eine Schulstufe zurück */
|
||
export function getLocalName(country: CountryConfig, level: number): string | undefined {
|
||
return country.stages.find(s => s.level === level)?.localName
|
||
}
|
||
|
||
/** Gibt alle Stufen zurück, die im Hauptfokus des Landes liegen */
|
||
export function getPrimaryStages(country: CountryConfig): CountryStage[] {
|
||
return country.stages.filter(
|
||
s => s.level >= country.primaryRange.from && s.level <= country.primaryRange.to
|
||
)
|
||
}
|
||
|
||
/** Prüft, ob eine Schulstufe Lesekompetenz erfordert */
|
||
export function requiresReading(level: number): boolean {
|
||
const ed = EDUCATION_LEVELS.find(e => e.level === level)
|
||
return ed ? ed.reading !== 'none' : true
|
||
}
|
||
|
||
/** Gibt die Lesekompetenz für eine Stufe zurück */
|
||
export function getReadingLevel(level: number): ReadingLevel {
|
||
return EDUCATION_LEVELS.find(e => e.level === level)?.reading ?? 'fluent'
|
||
}
|
||
|
||
/** Gibt die Fachbezeichnung für eine Stufe in einem Land zurück */
|
||
export function getSubjectName(country: CountryConfig, level: number): string | undefined {
|
||
return country.stages.find(s => s.level === level)?.subjectName
|
||
}
|