Sphery App Datenbank
Miro Visualisierung
Datenbanktabellen
Sessions
Key | Typ | Beschreibung |
---|---|---|
sessionId | int | ID der Session (DB index) |
loginAt | string | Der Zeitstempel des Logins |
logoutAt | string | Der Zeitstempel des Logouts |
exercube | string | Die ID des ExerCubes |
netPromoterScore | int | Bewertung der Session |
Challenges
Key | Typ | Beschreibung |
---|---|---|
challengeId | int | ID der Challenge (DB index) |
userIdInitiator | int | ID des Herausforderers |
userIdOpponent | int | ID des Kontrahenten |
isChallengeComplete | bool | Zeigt an ob die Challenge beendet wurde. |
challengeWinnerId | int | Die User ID des Gewinners |
challengeBestOf | int | Maximale Anzahl der Spielrunden |
challengeWorkouts | [...{<workout>,<user>,int}] | Ein Array, welches das Workout, die ID des Gewinners und die aktuelle Spielrunde abbildet. |
HR Values
Key | Typ | Beschreibung |
---|---|---|
hrValuesId | int | ID der hrValues (DB index) |
time | float | Sekunden seit beginn des Workouts |
value | int | HR Value |
WorkoutPresets
Key | Typ | Beschreibung |
---|---|---|
workoutPresetId | int | ID des WorkoutPresets (DB index) |
workoutPresetName | string | Name des WorkoutPresets (“DualFlow”, “UpperBody”, “LegDay”) |
isCustomizable | bool | Kann der Spieler im ExerCube Optionen (Dauer, Schwierigkeit, etc.) anpassen? |
fixedRaceConfigId | int | ID des RaceConfig, nicht bearbeitbar im ExerCube. (z.B. bei Turnier-Formaten) |
TimelineMarkers
Key | Typ | Beschreibung |
---|---|---|
timelineMarkerId | int | Die ID des timelineMarkers (DB index) |
name | string | Die String-ID (unique) des Markers |
readableName | string | Der (human readable) Name des Markers |
time | float | Die Zeit nach Start des Workouts nachdem die Übung passiert wurde |
tier | int | Der Combo-Tier mit welchem die Übung passiert wurde |
physicalPrecision | float? | Der Präzisionswert einer eher körperlich anstrengenden Übung (normalisiert, 0 falls verpasst/falsch) |
physicalRating | int | Der Evaluierungswert der Übung (Anzahl Sterne; 0 falls fehlerhaft) |
cognitivePrecision | float? | Der Präzisionswert einer eher kognitiv anstrengenden Übung (normalisiert, 0 falls verpasst/falsch) |
cognitiveRating | int | Der Evaluierungswert der Übung (Anzahl Sterne; 0 falls fehlerhaft) |
score | int | Die erhaltene Punktzahl für diese Übung |
Prefixes
Name Prefixes | Beispiele | Beschreibung |
---|---|---|
exercise_ | exercise_midPunchLeft | Die String-ID (unique) des Exercises |
pitStop_ | pitStop_enter, pitStop_exit | Bei Einfahrt und Ausfahrt in den Boxenstopp |
pause_ | pause_on, pause_off | Beim manuellen pausieren/unpausieren |
workout_ | workout_abort | Beim manuellen Abbruch eines Workouts. |
Workouts
Key | Typ | Beschreibung |
---|---|---|
workoutId | int | ID des Workouts (DB index) |
userId | int | ID des Users, der das Workout erstellt hat |
absolvedWorkout | bool | Zeigt, ob das Workout schon im Exercube absolviert wurde. |
sessionsId | int | ID der Session, wird nach Absolvierung im ExerCube hinzugefügt. |
hrTracking | bool | Wurde die Herzrate getracked? |
hrValues | [float,int] | Array von allen gemessenen HR-Werten; in der angegebenen Struktur
– time = Zeit nach start des Workouts (in Sekunden)
– value = HR-Wert |
hrAverage | int | Die Durchschnittliche Herzrate über das ganze Workout gemessen |
hrMax | int | Die tatsächlich erreichte maximale Herzrate |
timelineMarkers | [] | Array, welches geordnet alle Events auf der Rennstrecke fasst (siehe TimelineMarkers) |
score | int | Die erreichte Punktzahl in diesem Workout |
maxCombo | int | Maximum Combo, welcher erreicht wurde |
bodyScore | float | Workout BodyScore (prozentualer Wert [0.0-1.0]) |
brainScore | float | Workout BrainScore (prozentualer Wert [0.0-1.0]) |
dualflowScore | float | Workout DualflowScore (prozentualer Wert [0.0-1.0]) |
timelineMarkers | [] | Array, welches geordnet alle Events auf der Rennstrecke fasst (siehe TimelineMarkers) |
RaceConfig
Key | Typ | Beschreibung |
---|---|---|
raceConficId | int | ID der RaceConfig (DB index) |
seed | int | Der generierte Seed für die Erzeugung der Übungsreihenfolge auf dem Track |
type | string | Unterscheidet zwischen Konfigurationen im Racer, die Sphery kuratiert. Z.B. “workout”, “competition”, “studie_bern” |
difficulty | int | Schwierigkeit des Rennens [0-2] |
duration | int | Dauer des Rennens (in Sekunden) |
tutorial | bool | Boxenstopp Tutorials verwendet? |
startSpeed | float | Startgeschwindigkeit des Rennens [0.0-1.0] |
hrTarget | float | Die Ziel-HR für HR-adaptives Spiel |
Beispiele
Login
Das Spiel wird ein Loginformular beinhalten. Die Registrierung wird direkt über die WebApp vorgenommen. Die gesendeten Requests der Formulare beinhalten folgende Daten:
Login
{
"email": "stophel@blocher.ch",
"password": "schlumpfgate"
}
Response
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjMsImVtYWlsIjoibWljaGVsLmtpbnplbEBtb3J0eS5jb20iLCJpYXQiOjE2MTE1NzYxMzksImV4cCI6MTYxMTY2MjUzOX0.ZjvJxYY0FhUSveOoGlLQic2syf-_eBGZnVahicQFj4k",
"user": {
"userId": 1,
"email": "stophel@blocher.ch",
"username": "Christoph"
}
}
Start der Session
Direkt nach dem Login und dem Erhalt des Authentifizierungs-Tokens und der Benutzer ID wird eine neue Spiel-Session gestartet.
Request
Das Spiel sendet folgenden Request:
Type: POST
URI: https://sphery-1.herokuapp.com/api/v1/session
Header: Authorization: Bearer <token>
{
"loginAt": "2021-01-25T12:26:40.244Z",
"exercube": "SpheryCube1"
}
Response
Als Antwort werden vom Server Benutzerspezifische Daten erwartet, welche für das Spiel erforderlich sind.
{
"session": {
"sessionId": 1,
"healthData": <health-data>,
"workouts": [...<workout>]
}
}
Ende der Session
Zum Beenden der Session sendet das Spiel folgenden Request:
Type: PATCH
URI: https://sphery-1.herokuapp.com/api/v1/session
Header: Authorization: Bearer <token>
Request
{
"sessionId": 1,
"logoutAt": "2021-01-25T12:57:38.184Z",
"sessionTime": 1547.23,
"netPromoterScore": 8
}
Response
{
"session": {
"sessionId": 1,
"loginAt": "2021-01-25T12:26:40.244Z",
"logoutAt": "2021-01-25T12:57:38.184Z",
"sessionTime": 1547.23,
"netPromoterScore": 8,
"userId": 1,
"createdAt": "2021-01-25T12:26:40.244Z",
"updatedAt": "2021-01-25T12:57:38.184Z"
}
}
Abgeschlossenes Workout
Ein Workout beschreibt eigentlich immer ein einzelnes Rennen im Spiel. Nachdem der Spieler das Rennen beendet hat (sprich das Ziel erreicht hat), wird ein Request mit den gesamten Workout-Daten erstellt.
Request
Type: POST
URI: https://sphery-1.herokuapp.com/api/v1/workout
Header: Authorization: Bearer <token>
{
"workoutPreset": {
"name": "DualFlow",
},
"raceConfig": {
"raceConfigId": 1,
"seed": 45667567,
"adaptivityType": "hrTracking",
"difficulty": 2,
"duration": 900.00,
"tutorial": false,
"startSpeed": 5,
"hrTarget": 0.9
},
"sessionId": 1,
"userId": 1,
"challenge": -1,
"hrTracking": true,
"hrAverage": 163,
"hrMax": 199,
"score": 756388,
"maxCombo": 123,
"bodyScore": 0.9,
"brainScore": 0.8,
"dualflowScore": 0.85,
"hrValues": [
{
"time": 3.02,
"value": 82
},
{
"time": 6.13,
"value": 83
},
...
],
"timelineMarkers": [
{
"name": "exercise_midPunchLeft",
"readableName": "Punch Left",
"time": 2.14,
"tier": 2,
"physicalPrecision": 0.8,
"physicalRating": 3,
"cognitivePrecision": -1,
"cognitiveRating": 0,
"score": 230
},
...
]
}
Response
{
"Workout transfer successful! En schöne!"
}
Allgemeine Datensätze
Hier werden alle Datensätze aufgeschlüsselt welche oft Inhalt der einzelnen Requests sein können und als eigene "Objekte" oder "Typen" gehandhabt werden.
HealthData
{
"hrRestingPulse": 80,
"hrReserve": 116,
"hrMax": 196,
"weight": 75,
"age": 30
}
Key | Typ | Beschreibung |
---|---|---|
hrRestingPulse | int | Ruhepuls der HR; null falls undefiniert |
hrReserve | int | Reservepuls der HR; null falls undefiniert |
hrMax | int | HR Max; null falls undefiniert |
weight | int | Gewicht (in kg); null falls undefiniert |
age | int | Alter; null falls undefiniert |
WorkoutPresets
{
"name": "MyCustomWorkout",
"race": {
"seed": 6545684,
"type": "workout",
"difficulty": 2,
"duration": 900.00,
"tutorial": false,
"startSpeed": 5,
"hrTarget": 0.9
},
"exercises": [
"touches",
"punches"
],
"tiers": [
{
"cognitiveChallenges": [
"mirror",
"lights"
],
"cognitiveMin": 0.0,
"cognitiveMax": 1.0,
"physicalMin": 0.0,
"physicalMax": 1.0
},
...
]
}
Key | Typ | Beschreibung |
---|---|---|
name | string | Der Name (und String-ID; unique) des Workouts |
race | {} | Renn-spezifische Daten |
→ seed | int | Der generierte Seed für die Erzeugung der Übungsreihenfolge auf dem Track |
→ type | string | Unterscheidet zwischen Konfigurationen im Racer, die Sphery kuratiert. Z.B. "workout", "competition", "studie_bern" |
→ difficulty | int | Schwierigkeit des Rennens [0-2] |
→ duration | int | Dauer des Rennens (in Sekunden) |
→ tutorial | bool | Boxenstopp Tutorials verwendet? |
→ startSpeed | float | Startgeschwindigkeit des Rennens [0.0-1.0] |
→ hrTarget | float | Die Ziel-HR für HR-adaptives Spiel |
exercises | [...string] | Array an Übungs-Typen welche für das Spiel ausgewählt wurden |
tiers | [...{}] | Alle Combo-Tier informationen als Array; Länge des Arrays ist die Anzahl der Tiers |
→ cognitiveChallenges | [...string] | Array an kognitiven Challenge-Typen welche für das Spiel ausgewählt wurden |
→ cognitiveMin | float? | Minimale kognitive Adaptivität [0.0-1.0] |
→ cognitiveMax | float? | Maximale kognitive Adaptivität [0.0-1.0] |
→ physicalMin | float? | Minimale physische Adaptivität [0.0-1.0] |
→ physicalMax | float? | Maximale physische Adaptivität [0.0-1.0] |
TimelineMarkers
{
"name": "exercise_midPunchLeft",
"readableName": "Punch Left",
"time": 2.14,
"tier": 2,
"physicalPrecision": 0.8,
"physicalRating": 3,
"cognitivePrecision": -1,
"cognitiveRating": 0,
"score": 230
}
Beispiele
Diese Beispiele zeigen wie jeweils ein voller Request für die oben beschriebenen Sync-Points am Ende strukturiert ist und aussehen könnte.
Start der Session
{
"loginAt": "2021-01-25T12:26:40.244Z",
"exercube": "SpheryCube1"
}
Ende der Session
{
"sessionId": 1,
"logoutAt": "2021-01-25T12:57:38.184Z",
"sessionTime": 1800,
"netPromoterScore": 8
}
Abgeschlossenes Workout
{
"workoutPreset": {
"name": "MyCustomWorkout",
"race": {
"seed": 45667567,
"type": "workout",
"difficulty": 2,
"duration": 900,
"tutorial": false,
"startSpeed": 5,
"hrTarget": 0.9
},
"exercises": [
"touches",
"punches"
],
"tiers": [
{
"cognitiveChallenges": [
"mirror",
"lights"
],
"cognitiveMin": 0.0,
"cognitiveMax": 1.0,
"physicalMin": 0.0,
"physicalMax": 1.0
},
...
]
},
"sessionId": 1,
"challenge": -1,
"duration": 600,
"hrTracking": true,
"hrAdaptivity": true,
"hrValues": [
{
"time": 3.02,
"value": 82
},
{
"time": 6.13,
"value": 83
},
...
],
"hrAverage": 163,
"hrMax": 199,
"score": 756388,
"maxCombo": 123,
"bodyScore": 0.9,
"brainScore": 0.8,
"dualflowScore": 0.85,
"timelineMarkers": [
{
"name": "exercise_midPunchLeft",
"readableName": "Punch Left",
"time": 2.14,
"tier": 2,
"physicalPrecision": 0.8,
"physicalRating": 3,
"cognitivePrecision": -1,
"cognitiveRating": 0,
"score": 230
},
...
]
}