Compare commits
9 commits
feature/au
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ac198a695 | ||
|
|
49c472f748 | ||
|
|
b8bfb0b68f | ||
|
|
71f81a97dd | ||
|
|
de33790206 | ||
|
|
57e91c6742 | ||
|
|
a1c01b5112 | ||
|
|
ad90c4c7d7 | ||
|
|
d1b25af722 |
BIN
.gradle/9.5.1/checksums/checksums.lock
Normal file
BIN
.gradle/9.5.1/checksums/checksums.lock
Normal file
Binary file not shown.
BIN
.gradle/9.5.1/checksums/md5-checksums.bin
Normal file
BIN
.gradle/9.5.1/checksums/md5-checksums.bin
Normal file
Binary file not shown.
BIN
.gradle/9.5.1/checksums/sha1-checksums.bin
Normal file
BIN
.gradle/9.5.1/checksums/sha1-checksums.bin
Normal file
Binary file not shown.
BIN
.gradle/9.5.1/executionHistory/executionHistory.bin
Normal file
BIN
.gradle/9.5.1/executionHistory/executionHistory.bin
Normal file
Binary file not shown.
BIN
.gradle/9.5.1/executionHistory/executionHistory.lock
Normal file
BIN
.gradle/9.5.1/executionHistory/executionHistory.lock
Normal file
Binary file not shown.
BIN
.gradle/9.5.1/expanded/expanded.lock
Normal file
BIN
.gradle/9.5.1/expanded/expanded.lock
Normal file
Binary file not shown.
BIN
.gradle/9.5.1/fileChanges/last-build.bin
Normal file
BIN
.gradle/9.5.1/fileChanges/last-build.bin
Normal file
Binary file not shown.
BIN
.gradle/9.5.1/fileHashes/fileHashes.bin
Normal file
BIN
.gradle/9.5.1/fileHashes/fileHashes.bin
Normal file
Binary file not shown.
BIN
.gradle/9.5.1/fileHashes/fileHashes.lock
Normal file
BIN
.gradle/9.5.1/fileHashes/fileHashes.lock
Normal file
Binary file not shown.
BIN
.gradle/9.5.1/fileHashes/resourceHashesCache.bin
Normal file
BIN
.gradle/9.5.1/fileHashes/resourceHashesCache.bin
Normal file
Binary file not shown.
0
.gradle/9.5.1/gc.properties
Normal file
0
.gradle/9.5.1/gc.properties
Normal file
BIN
.gradle/9.5.1/kotlin-dsl-plugin-entries/jar-entries.bin
Normal file
BIN
.gradle/9.5.1/kotlin-dsl-plugin-entries/jar-entries.bin
Normal file
Binary file not shown.
Binary file not shown.
BIN
.gradle/buildOutputCleanup/buildOutputCleanup.lock
Normal file
BIN
.gradle/buildOutputCleanup/buildOutputCleanup.lock
Normal file
Binary file not shown.
2
.gradle/buildOutputCleanup/cache.properties
Normal file
2
.gradle/buildOutputCleanup/cache.properties
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#Wed Sep 02 15:03:29 CEST 2026
|
||||
gradle.version=9.5.1
|
||||
BIN
.gradle/buildOutputCleanup/outputFiles.bin
Normal file
BIN
.gradle/buildOutputCleanup/outputFiles.bin
Normal file
Binary file not shown.
BIN
.gradle/file-system.probe
Normal file
BIN
.gradle/file-system.probe
Normal file
Binary file not shown.
0
.gradle/vcs-1/gc.properties
Normal file
0
.gradle/vcs-1/gc.properties
Normal file
|
|
@ -1 +0,0 @@
|
|||
Kidio_backend
|
||||
|
|
@ -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>
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||
</state>
|
||||
</component>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
176
README.md
176
README.md
|
|
@ -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!"
|
||||
}
|
||||
```
|
||||
|
||||
#### 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
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
Sobald der Server erfolgreich gestartet ist, ist er unter `http://localhost:8080` erreichbar.
|
||||
|
|
|
|||
|
|
@ -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.
BIN
build/classes/kotlin/main/MainKt.class
Normal file
BIN
build/classes/kotlin/main/MainKt.class
Normal file
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.
BIN
build/classes/kotlin/main/com/oliver/kidio/backend/Task.class
Normal file
BIN
build/classes/kotlin/main/com/oliver/kidio/backend/Task.class
Normal file
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.
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.
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.
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.
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.
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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue