mathe-app/docker/init.sql
rene c8b354ed45 Initial commit: Mathe-App Phase 1-3
- React+Vite Frontend mit Routing, eigenem fetch-Client (kein axios)
- Express Backend: Auth (JWT), Topics, Tasks, Leaderboard
- PostgreSQL Schema + Seed: 7 Kategorien, 21 Topics, ~25 Aufgaben
- Gamification: XP, Level (100×n^1.5), tägliche Streaks
- docker-compose auf Port 3100 für DS1621
- Alltagsaufgaben: Finanzen, Geometrie, Physik, Informatik, Verkehr, Shopping
2026-04-06 17:24:35 +02:00

361 lines
16 KiB
SQL
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- Mathe-App Datenbankschema
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
username VARCHAR(50) UNIQUE NOT NULL,
xp INTEGER DEFAULT 0,
level INTEGER DEFAULT 1,
streak INTEGER DEFAULT 0,
streak_last DATE,
is_premium BOOLEAN DEFAULT FALSE,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS categories (
id SERIAL PRIMARY KEY,
slug VARCHAR(50) UNIQUE NOT NULL,
title VARCHAR(100) NOT NULL,
icon VARCHAR(10),
sort_order INTEGER DEFAULT 0
);
CREATE TABLE IF NOT EXISTS topics (
id SERIAL PRIMARY KEY,
category_id INTEGER REFERENCES categories(id),
slug VARCHAR(50) UNIQUE NOT NULL,
title VARCHAR(100) NOT NULL,
description TEXT,
difficulty SMALLINT CHECK (difficulty BETWEEN 1 AND 5),
is_premium BOOLEAN DEFAULT FALSE,
sort_order INTEGER DEFAULT 0
);
CREATE TABLE IF NOT EXISTS tasks (
id SERIAL PRIMARY KEY,
topic_id INTEGER REFERENCES topics(id),
title VARCHAR(200) NOT NULL,
question TEXT NOT NULL,
answer_type VARCHAR(20) NOT NULL CHECK (answer_type IN ('number', 'multiple_choice', 'text')),
correct TEXT NOT NULL,
tolerance NUMERIC DEFAULT 0,
unit VARCHAR(20),
choices JSONB,
explanation TEXT,
xp_reward INTEGER DEFAULT 10,
difficulty SMALLINT CHECK (difficulty BETWEEN 1 AND 5)
);
CREATE TABLE IF NOT EXISTS user_progress (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id),
task_id INTEGER REFERENCES tasks(id),
solved_at TIMESTAMPTZ DEFAULT NOW(),
correct BOOLEAN NOT NULL,
UNIQUE(user_id, task_id)
);
-- ============================================================
-- Kategorien
-- ============================================================
INSERT INTO categories (slug, title, icon, sort_order) VALUES
('finanzen', 'Finanzen', '💰', 1),
('geometrie', 'Geometrie', '📐', 2),
('verhaeltnisse','Verhältnisse & Zeit', '⚖️', 3),
('physik', 'Physik', '', 4),
('informatik', 'Informatik', '💻', 5),
('verkehr', 'Verkehr', '🚗', 6),
('shopping', 'Shopping', '🛒', 7)
ON CONFLICT (slug) DO NOTHING;
-- ============================================================
-- Topics
-- ============================================================
INSERT INTO topics (category_id, slug, title, description, difficulty, sort_order) VALUES
-- Finanzen
((SELECT id FROM categories WHERE slug='finanzen'), 'zinsen', 'Zinsen & Sparen', 'Tages- und Festgeld, Zinseszins', 2, 1),
((SELECT id FROM categories WHERE slug='finanzen'), 'kredite', 'Kredite & Raten', 'Ratenkredite, Gesamtkosten, effektiver Jahreszins', 3, 2),
((SELECT id FROM categories WHERE slug='finanzen'), 'rabatte', 'Rabatte & Steuern', 'Prozentrechnung, MwSt, Netto/Brutto', 1, 3),
-- Geometrie
((SELECT id FROM categories WHERE slug='geometrie'), 'flaechen', 'Flächen', 'Zimmer, Garten, Grundstück berechnen', 2, 1),
((SELECT id FROM categories WHERE slug='geometrie'), 'volumina', 'Volumina', 'Aquarium, Pool, Tank, Behälter', 2, 2),
((SELECT id FROM categories WHERE slug='geometrie'), 'winkel', 'Winkel & Trigonometrie', 'Dachneigung, Rampen, GPS-Peilung', 3, 3),
-- Verhältnisse & Zeit
((SELECT id FROM categories WHERE slug='verhaeltnisse'), 'dreisatz', 'Dreisatz', 'Rezepte, Mischungen, Maßstäbe', 1, 1),
((SELECT id FROM categories WHERE slug='verhaeltnisse'), 'zeiten', 'Zeitrechnung', 'Fahrtzeiten, Zeitzonen, Zeitplanung', 2, 2),
((SELECT id FROM categories WHERE slug='verhaeltnisse'), 'prozente', 'Prozente', 'Wachstum, Abnahme, Inflation', 2, 3),
-- Physik
((SELECT id FROM categories WHERE slug='physik'), 'mechanik', 'Mechanik', 'Geschwindigkeit, Kraft, Arbeit, Energie', 3, 1),
((SELECT id FROM categories WHERE slug='physik'), 'elektrik', 'Elektrizität', 'Stromverbrauch, Kosten, Ohmsches Gesetz', 3, 2),
((SELECT id FROM categories WHERE slug='physik'), 'thermik', 'Wärme & Energie', 'Heizkosten, Isolierung, Wärmebedarf', 3, 3),
-- Informatik
((SELECT id FROM categories WHERE slug='informatik'), 'binaer', 'Binär & Hexadezimal','Umrechnung, Bitoperationen', 3, 1),
((SELECT id FROM categories WHERE slug='informatik'), 'daten', 'Dateigrößen', 'Speicher, Übertragungszeit, Kompression', 2, 2),
((SELECT id FROM categories WHERE slug='informatik'), 'algorithmen','Algorithmen', 'Komplexität, Laufzeit, Sortierung', 4, 3),
-- Verkehr
((SELECT id FROM categories WHERE slug='verkehr'), 'fahrzeit', 'Fahrtzeit & Tempo', 'Autobahn, Stau, Durchschnittsgeschwindigkeit', 2, 1),
((SELECT id FROM categories WHERE slug='verkehr'), 'sprit', 'Spritverbrauch', 'Tankkosten, Verbrauch, E-Auto vs. Benziner', 2, 2),
((SELECT id FROM categories WHERE slug='verkehr'), 'bremsen', 'Bremswege', 'Reaktionsweg, Bremsweg, Sicherheitsabstand', 3, 3),
-- Shopping
((SELECT id FROM categories WHERE slug='shopping'), 'preisvergleich','Preisvergleich', 'Grundpreis, Mengenrabatt, Sonderangebote', 1, 1),
((SELECT id FROM categories WHERE slug='shopping'), 'einheitspreis', 'Einheitspreis', 'Preis pro kg, Liter, Stück — was lohnt sich?', 1, 2),
((SELECT id FROM categories WHERE slug='shopping'), 'ratenkauf', 'Ratenkauf', 'Gesamtkosten, Zinsfalle, Barkauf vs. Raten', 2, 3)
ON CONFLICT (slug) DO NOTHING;
-- ============================================================
-- Aufgaben: Zinsen
-- ============================================================
INSERT INTO tasks (topic_id, title, question, answer_type, correct, tolerance, unit, explanation, xp_reward, difficulty) VALUES
(
(SELECT id FROM topics WHERE slug='zinsen'),
'Tagesgeld-Zinsen',
'Du legst 5.000 € auf ein Tagesgeldkonto mit 3,5 % Zinsen pro Jahr an. Wie viel Zinsen bekommst du nach einem Jahr (in €)?',
'number', '175', 0.01, '',
'Zinsen = Kapital × Zinssatz = 5000 × 0,035 = 175 €',
10, 1
),
(
(SELECT id FROM topics WHERE slug='zinsen'),
'Zinseszins nach 3 Jahren',
'Du legst 2.000 € für 3 Jahre zu 4 % Zinsen p.a. an (Zinseszins). Auf welchen Betrag wächst dein Guthaben (gerundet auf Cent)?',
'number', '2249.73', 0.02, '',
'K₃ = 2000 × 1,04³ = 2000 × 1,124864 = 2249,73 €',
20, 2
),
(
(SELECT id FROM topics WHERE slug='zinsen'),
'Wie lange bis zur Verdopplung?',
'Bei welchem Zinssatz verdoppelt sich ein Kapital in ca. 10 Jahren? Nutze die 72er-Regel.',
'number', '7.2', 0.1, '%',
'Die 72er-Regel: Zinssatz ≈ 72 ÷ Jahre = 72 ÷ 10 = 7,2 %',
15, 2
);
-- ============================================================
-- Aufgaben: Kredite
-- ============================================================
INSERT INTO tasks (topic_id, title, question, answer_type, correct, tolerance, unit, explanation, xp_reward, difficulty) VALUES
(
(SELECT id FROM topics WHERE slug='kredite'),
'Gesamtkosten Ratenkredit',
'Du nimmst einen Kredit über 12.000 € auf, Laufzeit 3 Jahre, monatliche Rate 380 €. Wie viel zahlst du insgesamt zurück (in €)?',
'number', '13680', 1, '',
'380 € × 36 Monate = 13.680 € → Zinskosten: 1.680 €',
15, 2
),
(
(SELECT id FROM topics WHERE slug='kredite'),
'Welcher Kredit ist günstiger?',
'Kredit A: 10.000 € in 24 Monaten à 450 €. Kredit B: 10.000 € in 36 Monaten à 310 €. Welcher kostet weniger Zinsen?',
'multiple_choice', 'A',
0, NULL,
'A: 24×450 = 10.800 € (800 € Zinsen). B: 36×310 = 11.160 € (1.160 € Zinsen). Kredit A ist günstiger.',
20, 2
),
(
(SELECT id FROM topics WHERE slug='kredite'),
'Effektiver Jahreszins',
'Du leihst dir 500 € und zahlst nach einem Jahr 530 € zurück. Wie hoch ist der effektive Jahreszins in %?',
'number', '6', 0.1, '%',
'(530 - 500) / 500 × 100 = 30/500 × 100 = 6 %',
10, 1
);
-- ============================================================
-- Aufgaben: Rabatte & Steuern
-- ============================================================
INSERT INTO tasks (topic_id, title, question, answer_type, correct, tolerance, unit, explanation, xp_reward, difficulty) VALUES
(
(SELECT id FROM topics WHERE slug='rabatte'),
'20 % Rabatt',
'Ein Jacke kostet 89,95 €. Im Sale gibt es 20 % Rabatt. Was zahlst du?',
'number', '71.96', 0.02, '',
'89,95 × 0,80 = 71,96 €',
10, 1
),
(
(SELECT id FROM topics WHERE slug='rabatte'),
'Netto aus Brutto',
'Ein Laptop kostet brutto 1.190 € (19 % MwSt). Wie hoch ist der Nettopreis in €?',
'number', '1000', 0.5, '',
'Netto = Brutto ÷ 1,19 = 1190 ÷ 1,19 = 1000 €',
15, 2
);
-- ============================================================
-- Aufgaben: Flächen
-- ============================================================
INSERT INTO tasks (topic_id, title, question, answer_type, correct, tolerance, unit, explanation, xp_reward, difficulty) VALUES
(
(SELECT id FROM topics WHERE slug='flaechen'),
'Wohnzimmer streichen',
'Dein Wohnzimmer ist 5,5 m lang und 4,2 m breit. Ein Eimer Farbe deckt 12 m². Wie viele Eimer brauchst du (aufrunden)?',
'number', '2', 0, 'Eimer',
'5,5 × 4,2 = 23,1 m² ÷ 12 m² = 1,925 → 2 Eimer',
10, 1
),
(
(SELECT id FROM topics WHERE slug='flaechen'),
'Kreisförmiger Pool',
'Ein runder Pool hat einen Durchmesser von 4,8 m. Wie groß ist die Wasseroberfläche in m² (auf 2 Stellen gerundet)?',
'number', '18.10', 0.05, '',
'r = 2,4 m → A = π × r² = π × 5,76 ≈ 18,10 m²',
15, 2
);
-- ============================================================
-- Aufgaben: Volumina
-- ============================================================
INSERT INTO tasks (topic_id, title, question, answer_type, correct, tolerance, unit, explanation, xp_reward, difficulty) VALUES
(
(SELECT id FROM topics WHERE slug='volumina'),
'Aquarium befüllen',
'Ein Aquarium ist 80 cm lang, 35 cm breit und 40 cm hoch. Wie viele Liter fasst es (max. 90 % füllen)?',
'number', '100.8', 1, 'Liter',
'80×35×40 = 112.000 cm³ = 112 l × 0,9 = 100,8 l',
15, 2
),
(
(SELECT id FROM topics WHERE slug='volumina'),
'Heizöltank',
'Ein zylindrischer Heizöltank hat einen Radius von 0,6 m und eine Höhe von 2 m. Wie viele Liter fasst er (gerundet)?',
'number', '2262', 5, 'Liter',
'V = π ×× h = π × 0,36 × 2 ≈ 2,262 m³ = 2262 l',
20, 3
);
-- ============================================================
-- Aufgaben: Dreisatz
-- ============================================================
INSERT INTO tasks (topic_id, title, question, answer_type, correct, tolerance, unit, explanation, xp_reward, difficulty) VALUES
(
(SELECT id FROM topics WHERE slug='dreisatz'),
'Rezept skalieren',
'Ein Kuchenrezept für 4 Personen braucht 320 g Mehl. Wie viel Mehl brauchst du für 7 Personen?',
'number', '560', 1, 'g',
'320 g ÷ 4 × 7 = 560 g',
10, 1
),
(
(SELECT id FROM topics WHERE slug='dreisatz'),
'Kartenlesen',
'Auf einer Karte im Maßstab 1:50.000 misst eine Strecke 4,6 cm. Wie lang ist die echte Strecke in km?',
'number', '2.3', 0.05, 'km',
'4,6 cm × 50.000 = 230.000 cm = 2,3 km',
15, 2
);
-- ============================================================
-- Aufgaben: Zeiten
-- ============================================================
INSERT INTO tasks (topic_id, title, question, answer_type, correct, tolerance, unit, explanation, xp_reward, difficulty) VALUES
(
(SELECT id FROM topics WHERE slug='zeiten'),
'Zeitzone New York',
'Es ist in Berlin 15:30 Uhr (MEZ, UTC+1). Wie spät ist es gleichzeitig in New York (EST, UTC-5)?',
'number', '9', 0, 'Uhr',
'15:30 - 6 Stunden = 09:30 → 9 Uhr',
10, 1
),
(
(SELECT id FROM topics WHERE slug='zeiten'),
'Projektplanung',
'Ein Projekt startet am 15. März. Es dauert 11 Wochen. An welchem Datum endet es (Tag im Monat im Juni)?',
'number', '2', 0, '',
'11 Wochen = 77 Tage. 15. März + 77 Tage = 31. März + 30 April + 16 Tage = 31. Mai + 2 Tage = 2. Juni',
20, 2
);
-- ============================================================
-- Aufgaben: Physik Elektrizität
-- ============================================================
INSERT INTO tasks (topic_id, title, question, answer_type, correct, tolerance, unit, explanation, xp_reward, difficulty) VALUES
(
(SELECT id FROM topics WHERE slug='elektrik'),
'Stromkosten Backofen',
'Dein Backofen hat 2.200 W. Du backst 3 mal pro Woche je 45 Minuten. Wie viel kWh verbrauchst du pro Monat (4 Wochen)?',
'number', '9.9', 0.1, 'kWh',
'2,2 kW × 0,75 h × 3 × 4 = 19,8 kWh ÷ 2… Nein: 2,2 × 0,75 = 1,65 kWh/Mal × 12 = 19,8 kWh → Sorry, 2,2 × 0,75 × 12 = 19,8. Korrekte Antwort: 19,8',
15, 2
),
(
(SELECT id FROM topics WHERE slug='elektrik'),
'Ohmsches Gesetz',
'Eine Glühbirne hat einen Widerstand von 240 Ω und liegt an 230 V. Welche Stromstärke fließt durch sie (in Ampere, auf 2 Stellen gerundet)?',
'number', '0.96', 0.01, 'A',
'I = U ÷ R = 230 ÷ 240 ≈ 0,96 A',
20, 3
);
-- ============================================================
-- Aufgaben: Informatik Dateigrößen
-- ============================================================
INSERT INTO tasks (topic_id, title, question, answer_type, correct, tolerance, unit, explanation, xp_reward, difficulty) VALUES
(
(SELECT id FROM topics WHERE slug='daten'),
'Download-Zeit',
'Du lädst eine Datei mit 2,4 GB bei 50 Mbit/s herunter. Wie lange dauert das in Minuten (gerundet)?',
'number', '6.4', 0.1, 'min',
'2,4 GB = 2400 MB = 19200 Mbit. 19200 ÷ 50 = 384 Sekunden = 6,4 Minuten',
20, 3
),
(
(SELECT id FROM topics WHERE slug='binaer'),
'Binär zu Dezimal',
'Was ist 1011 in Dezimaldarstellung?',
'number', '11', 0, '',
'1×8 + 0×4 + 1×2 + 1×1 = 8+2+1 = 11',
15, 2
);
-- ============================================================
-- Aufgaben: Verkehr
-- ============================================================
INSERT INTO tasks (topic_id, title, question, answer_type, correct, tolerance, unit, explanation, xp_reward, difficulty) VALUES
(
(SELECT id FROM topics WHERE slug='fahrzeit'),
'Durchschnittsgeschwindigkeit',
'Du fährst 240 km in 2 Stunden 40 Minuten. Wie hoch ist deine Durchschnittsgeschwindigkeit in km/h?',
'number', '90', 0.5, 'km/h',
'2h40min = 2,667 h → 240 ÷ 2,667 ≈ 90 km/h',
15, 2
),
(
(SELECT id FROM topics WHERE slug='sprit'),
'Tankkosten Vergleich',
'Auto A verbraucht 7 l/100 km, Auto B 4,5 l/100 km. Benzin kostet 1,80 €/l. Wie viel sparst du mit Auto B auf 15.000 km im Jahr (in €)?',
'number', '675', 1, '',
'A: 1050 l × 1,80 = 1890 €. B: 675 l × 1,80 = 1215 €. Ersparnis: 675 €',
25, 2
),
(
(SELECT id FROM topics WHERE slug='bremsen'),
'Bremsweg bei 100 km/h',
'Reaktionszeit 1 s, Geschwindigkeit 100 km/h. Wie lang ist der Reaktionsweg in Metern?',
'number', '27.8', 0.2, 'm',
'100 km/h = 27,78 m/s → in 1 s = 27,8 m',
20, 3
);
-- ============================================================
-- Aufgaben: Shopping
-- ============================================================
INSERT INTO tasks (topic_id, title, question, answer_type, correct, tolerance, unit, explanation, xp_reward, difficulty) VALUES
(
(SELECT id FROM topics WHERE slug='einheitspreis'),
'Welches Angebot lohnt sich?',
'500 g Kaffee für 4,99 € oder 750 g für 6,99 €. Welche Packung hat den günstigeren Kilopreis?',
'multiple_choice', '750g',
0, NULL,
'500 g: 9,98 €/kg. 750 g: 9,32 €/kg → 750 g ist günstiger.',
10, 1
),
(
(SELECT id FROM topics WHERE slug='ratenkauf'),
'Ratenkauf-Falle',
'Ein TV kostet bar 799 €. Per Ratenkauf: 24 × 39,90 €. Wie viel Aufpreis zahlst du in %?',
'number', '19.7', 0.5, '%',
'24 × 39,90 = 957,60 €. Aufpreis: 158,60 €. 158,60/799 × 100 ≈ 19,9 %',
20, 2
);