Compare commits

..

7 commits

Author SHA1 Message Date
aldemirm 86dcc68825 refactoring 2026-09-04 12:37:13 +02:00
aldemirm c2c1e334c7 gitignore 2026-09-04 12:31:02 +02:00
aldemirm e0995dafbc chore: ignore build and gradle temporary directories 2026-09-04 12:28:06 +02:00
aldemirm dee5d95e7a added gitignore 2026-09-04 12:27:29 +02:00
aldemirm 8458d6a3f1 changed username, add UserTable to SchemaUtils 2026-09-04 12:23:20 +02:00
aldemirm b1448884c6 changed username, add UserTable to SchemaUtils 2026-09-04 12:21:51 +02:00
aldemirm cb03279c6d feat: add user authentication and protect endpoints with JWT
Added UsersTable to Exposed database schema

Updated KidioRepository interface and implementations for auth methods

Updated Ktor routing, application setup, and integration tests for JWT auth
2026-09-04 11:35:46 +02:00
275 changed files with 193 additions and 2248 deletions

2
.gitignore vendored
View file

@ -10,4 +10,4 @@ build/
*.iml
*.iws
*.ipr
out/
out/

Binary file not shown.

View file

@ -1,2 +0,0 @@
#Wed Sep 02 15:03:29 CEST 2026
gradle.version=9.5.1

Binary file not shown.

1
.idea/.name Normal file
View file

@ -0,0 +1 @@
Kidio_backend

View file

@ -0,0 +1,10 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<JetCodeStyleSettings>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</codeStyleSettings>
</code_scheme>
</component>

View file

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

8
.idea/modules.xml Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/modules/Kidio_backend.iml" filepath="$PROJECT_DIR$/.idea/modules/Kidio_backend.iml" />
</modules>
</component>
</project>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="AdditionalModuleElements">
<content url="file://$MODULE_DIR$/../.." dumb="true">
<excludeFolder url="file://$MODULE_DIR$/../dataSources" />
</content>
</component>
</module>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="" vcs="Git" />
</component>
</project>

176
README.md
View file

@ -1,171 +1,33 @@
# Kidio Backend
# Kidio_backend
Das Kidio-Backend ist eine gamifizierte Lösung zur Verwaltung von Bildschirmzeit für Kinder. Die Anwendung basiert auf dem **Ktor**-Framework in Kotlin und kombiniert **PostgreSQL** für die Persistenz mit **Redis** als Caching-Layer für schnelle Zugriffszeiten.
This project was created using the [Ktor Project Generator](https://start.ktor.io).
Kinder können durch das Lösen von Lernaufgaben (z. B. Mathe-Aufgaben) zusätzliche Bildschirmzeit erwerben, während das System ihre verbrauchte Bildschirmzeit synchronisiert und bei Ablauf sperrt.
Here are some useful links to get you started:
---
* [Ktor Documentation](https://ktor.io/docs/home.html)
* [Ktor GitHub page](https://github.com/ktorio/ktor)
* [Ktor Slack chat](https://app.slack.com/client/T09229ZC6/C0A974TJ9). [Request an invite](https://surveys.jetbrains.com/s3/kotlin-slack-sign-up).
## Features
Hier ist eine Übersicht der implementierten Kernfunktionen des Kidio-Backends:
Here's a list of features included in this project:
| Name | Beschreibung |
| Name | Description |
|------|-------------|
| **JWT Authentifizierung** | Sichere API-Endpunkte für authentifizierte Benutzer über JSON Web Tokens (JWT). |
| **Lernaufgaben (Tasks)** | Abrufen von interaktiven Lernaufgaben mit vordefinierten Antwortmöglichkeiten und Belohnungen (z. B. Minuten). |
| **Antwort-Verifizierung** | Überprüfung der vom Kind ausgewählten Antworten. Bei korrekter Antwort wird die Belohnung direkt auf die verbleibende Bildschirmzeit aufgerechnet. |
| **Bildschirmzeit-Synchronisation** | Laufender Datenabgleich der genutzten Bildschirmzeit. Sinkt die Zeit auf oder unter Null, wird der Status automatisch auf `isBlocked = true` gesetzt. |
| **Zwei-Ebenen-Speicher** | Datenhaltung in **PostgreSQL** (via JetBrains Exposed ORM) kombiniert mit **Redis-Caching** (via Jedis) für optimale Performance bei der Screentime-Abfrage. |
| **Fallback-Mechanismus** | Ist die Redis-Instanz nicht erreichbar, fällt das System automatisch und transparent auf PostgreSQL zurück. |
---
## Building & Running
## Technologiestack
To build or run the project, use one of the following tasks:
- **Framework**: [Ktor](https://ktor.io/) (Kotlin-basiertes asynchrones Web-Framework)
- **Datenbank-ORM**: [JetBrains Exposed](https://github.com/JetBrains/Exposed)
- **Persistenz**: PostgreSQL
- **Caching**: Redis (via Jedis Client)
- **Sicherheit & Auth**: JWT (Java JWT von auth0)
- **Serialization**: Kotlinx Serialization (JSON)
- **Testing**: Ktor Server Testing, JUnit
| Task | Description |
|-------------------|-------------------|
| `./gradlew test` | Run the tests |
| `./gradlew build` | Build the project |
| `./gradlew run` | Run the server |
---
If the server starts successfully, you'll see the following output:
## API-Endpunkte
Alle Endpunkte befinden sich unter dem Präfix `/api/v1`.
### Öffentliche Endpunkte
#### 1. Health-Check
- **Methode**: `GET`
- **Pfad**: `/api/v1/health`
- **Beschreibung**: Prüft, ob der Backend-Server ordnungsgemäß läuft.
- **Antwort**:
```json
{
"status": "OK",
"message": "Kidio Backend läuft!"
}
```
#### 2. Benutzer-Login (Auth-Token abholen)
- **Methode**: `POST`
- **Pfad**: `/api/v1/auth/login`
- **Request-Body**:
```json
{
"userId": "default_user"
}
```
- **Antwort**:
```json
{
"token": "eyJhbGciOiJIUzI1NiIsIn..."
}
```
### Geschützte Endpunkte (Erfordern JWT im `Authorization: Bearer <Token>` Header)
#### 3. Alle verfügbaren Aufgaben abrufen
- **Methode**: `GET`
- **Pfad**: `/api/v1/tasks`
- **Beschreibung**: Liefert eine Liste aller verfügbaren Lernaufgaben.
- **Antwort**:
```json
[
{
"id": "t1",
"question": "Was ist 12 + 15?",
"options": ["25", "27", "30", "22"],
"rewardMinutes": 10
}
]
```
#### 4. Antwort überprüfen & Belohnung verbuchen
- **Methode**: `POST`
- **Pfad**: `/api/v1/tasks/verify`
- **Request-Body**:
```json
{
"taskId": "t1",
"selectedAnswer": "27"
}
```
- **Antwort (Erfolg)**:
```json
{
"isCorrect": true,
"earnedMinutes": 10,
"message": "Super gemacht! Du hast 10 Minuten gewonnen."
}
```
- **Antwort (Fehler)**:
```json
{
"isCorrect": false,
"earnedMinutes": 0,
"message": "Schade, das war leider falsch. Versuche es nochmal!"
}
```
#### 5. Bildschirmzeit synchronisieren
- **Methode**: `POST`
- **Pfad**: `/api/v1/screentime/sync`
- **Beschreibung**: Zieht die seit dem letzten Abgleich verbrauchten Sekunden von der verfügbaren Bildschirmzeit ab.
- **Request-Body**:
```json
{
"userId": "default_user",
"usedSecondsSinceLastSync": 200
}
```
- **Antwort**:
```json
{
"remainingSeconds": 1600,
"isBlocked": false
}
```
---
## Projektkonfiguration und Umgebungsvariablen
Das Projekt wird über die Datei `src/main/resources/application.yaml` konfiguriert. Folgende Umgebungsvariablen können zur flexiblen Docker- oder Deployment-Konfiguration übergeben werden:
| Variable | Beschreibung | Standardwert |
|----------|--------------|--------------|
| `DB_HOST` | Hostname der PostgreSQL-Datenbank | `localhost` / aus `application.yaml` |
| `DB_PORT` | Port der PostgreSQL-Datenbank | `5432` / aus `application.yaml` |
| `DB_NAME` | Name der PostgreSQL-Datenbank | `kidio_db` |
| `DB_USER` | PostgreSQL-Benutzername | `kidio_admin` |
| `DB_PASSWORD` | PostgreSQL-Passwort | `learning` |
| `REDIS_HOST` | Hostname der Redis-Instanz | `localhost` |
| `REDIS_PORT` | Port der Redis-Instanz | `6379` |
| `JWT_SECRET` | Geheimer Schlüssel zur Signierung der JWTs | `super-geheimes-secret-fuer-dev` |
---
## Lokale Entwicklung, Bauen & Testen
Zur Ausführung des Projekts werden die folgenden Gradle-Tasks bereitgestellt:
| Task | Beschreibung |
|------|-------------|
| `./gradlew test` | Führt alle automatisierten Unit- und Integrationstests aus (nutzt die InMemory-Repository-Implementierung). |
| `./gradlew build` | Kompiliert das Projekt und baut das Artefakt. |
| `./gradlew run` | Startet den Ktor-Entwicklungsserver lokal auf Port `8080`. |
```bash
# Tests ausführen
./gradlew test
# Server starten
./gradlew run
```
Sobald der Server erfolgreich gestartet ist, ist er unter `http://localhost:8080` erreichbar.
2024-12-04 14:32:45.584 [main] INFO Application - Application started in 0.303 seconds.
2024-12-04 14:32:45.682 [main] INFO Application - Responding at http://0.0.0.0:8080
```

View file

@ -20,15 +20,12 @@ dependencies {
implementation(ktorLibs.server.core)
implementation(ktorLibs.server.netty)
// JWT Authentication
// JWT Authentication (NEU)
implementation("io.ktor:ktor-server-auth")
implementation("io.ktor:ktor-server-auth-jwt")
implementation(libs.logback.classic)
// Bcrypt
implementation("org.mindrot:jbcrypt:0.4")
// JSON-Unterstützung und Serialization
implementation("io.ktor:ktor-server-content-negotiation-jvm")
implementation("io.ktor:ktor-serialization-kotlinx-json-jvm")
@ -38,10 +35,11 @@ dependencies {
implementation("org.jetbrains.exposed:exposed-core:0.50.0")
implementation("org.jetbrains.exposed:exposed-dao:0.50.0")
implementation("org.jetbrains.exposed:exposed-jdbc:0.50.0")
testImplementation(kotlin("test"))
testImplementation(ktorLibs.server.testHost)
// redis
implementation("redis.clients:jedis:5.1.2")
implementation("org.jetbrains.exposed:exposed-java-time:0.50.0")
}

Some files were not shown because too many files have changed in this diff Show more