Compare commits

..

9 commits

275 changed files with 2246 additions and 191 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

Binary file not shown.

View file

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

Binary file not shown.

BIN
.gradle/file-system.probe Normal file

Binary file not shown.

View file

View file

@ -1 +0,0 @@
Kidio_backend

View file

@ -1,10 +0,0 @@
<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

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

View file

@ -1,8 +0,0 @@
<?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

@ -1,8 +0,0 @@
<?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="" vcs="Git" />
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

174
README.md
View file

@ -1,33 +1,171 @@
# Kidio_backend
# Kidio Backend
This project was created using the [Ktor Project Generator](https://start.ktor.io).
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.
Here are some useful links to get you started:
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.
* [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
Here's a list of features included in this project:
Hier ist eine Übersicht der implementierten Kernfunktionen des Kidio-Backends:
| Name | Description |
| Name | Beschreibung |
|------|-------------|
| **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
---
To build or run the project, use one of the following tasks:
## Technologiestack
| Task | Description |
|-------------------|-------------------|
| `./gradlew test` | Run the tests |
| `./gradlew build` | Build the project |
| `./gradlew run` | Run the server |
- **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
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!"
}
```
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
#### 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.

View file

@ -20,12 +20,15 @@ dependencies {
implementation(ktorLibs.server.core)
implementation(ktorLibs.server.netty)
// JWT Authentication (NEU)
// JWT Authentication
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")
@ -35,11 +38,10 @@ 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")
}

Binary file not shown.

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