Sphery App Datenbank

Miro Visualisierung

Datenbanktabellen

Sessions

KeyTypBeschreibung
sessionIdintID der Session (DB index)
loginAtstringDer Zeitstempel des Logins
logoutAtstringDer Zeitstempel des Logouts
exercubestringDie ID des ExerCubes
netPromoterScoreintBewertung der Session

Challenges

KeyTypBeschreibung
challengeIdintID der Challenge (DB index)
userIdInitiatorintID des Herausforderers
userIdOpponentintID des Kontrahenten
isChallengeCompleteboolZeigt an ob die Challenge beendet wurde.
challengeWinnerIdintDie User ID des Gewinners
challengeBestOfintMaximale Anzahl der Spielrunden
challengeWorkouts[...{<workout>,<user>,int}]Ein Array, welches das Workout, die ID des Gewinners und die aktuelle Spielrunde abbildet.

HR Values

KeyTypBeschreibung
hrValuesIdintID der hrValues (DB index)
timefloatSekunden seit beginn des Workouts
valueintHR Value

WorkoutPresets

KeyTypBeschreibung
workoutPresetIdintID des WorkoutPresets (DB index)
workoutPresetNamestringName des WorkoutPresets (“DualFlow”, “UpperBody”, “LegDay”)
isCustomizableboolKann der Spieler im ExerCube Optionen (Dauer, Schwierigkeit, etc.) anpassen?
fixedRaceConfigIdintID des RaceConfig, nicht bearbeitbar im ExerCube. (z.B. bei Turnier-Formaten)

TimelineMarkers

KeyTypBeschreibung
timelineMarkerIdintDie ID des timelineMarkers (DB index)
namestringDie String-ID (unique) des Markers
readableNamestringDer (human readable) Name des Markers
timefloatDie Zeit nach Start des Workouts nachdem die Übung passiert wurde
tierintDer Combo-Tier mit welchem die Übung passiert wurde
physicalPrecisionfloat?Der Präzisionswert einer eher körperlich anstrengenden Übung (normalisiert, 0 falls verpasst/falsch)
physicalRatingintDer Evaluierungswert der Übung (Anzahl Sterne; 0 falls fehlerhaft)
cognitivePrecisionfloat?Der Präzisionswert einer eher kognitiv anstrengenden Übung (normalisiert, 0 falls verpasst/falsch)
cognitiveRatingintDer Evaluierungswert der Übung (Anzahl Sterne; 0 falls fehlerhaft)
scoreintDie erhaltene Punktzahl für diese Übung

Prefixes

Name PrefixesBeispieleBeschreibung
exercise_exercise_midPunchLeftDie String-ID (unique) des Exercises
pitStop_pitStop_enter, pitStop_exitBei Einfahrt und Ausfahrt in den Boxenstopp
pause_pause_on, pause_offBeim manuellen pausieren/unpausieren
workout_workout_abortBeim manuellen Abbruch eines Workouts.

Workouts

KeyTypBeschreibung
workoutIdintID des Workouts (DB index)
userIdintID des Users, der das Workout erstellt hat
absolvedWorkoutboolZeigt, ob das Workout schon im Exercube absolviert wurde.
sessionsIdintID der Session, wird nach Absolvierung im ExerCube hinzugefügt.
hrTrackingboolWurde 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
hrAverageintDie Durchschnittliche Herzrate über das ganze Workout gemessen
hrMaxintDie tatsächlich erreichte maximale Herzrate
timelineMarkers[]Array, welches geordnet alle Events auf der Rennstrecke fasst (siehe TimelineMarkers)
scoreintDie erreichte Punktzahl in diesem Workout
maxCombointMaximum Combo, welcher erreicht wurde
bodyScorefloatWorkout BodyScore (prozentualer Wert [0.0-1.0])
brainScorefloatWorkout BrainScore (prozentualer Wert [0.0-1.0])
dualflowScorefloatWorkout DualflowScore (prozentualer Wert [0.0-1.0])
timelineMarkers[]Array, welches geordnet alle Events auf der Rennstrecke fasst (siehe TimelineMarkers)

RaceConfig

KeyTypBeschreibung
raceConficIdintID der RaceConfig (DB index)
seedintDer generierte Seed für die Erzeugung der Übungsreihenfolge auf dem Track
typestringUnterscheidet zwischen Konfigurationen im Racer, die Sphery kuratiert. Z.B. “workout”, “competition”, “studie_bern”
difficultyintSchwierigkeit des Rennens [0-2]
durationintDauer des Rennens (in Sekunden)
tutorialboolBoxenstopp Tutorials verwendet?
startSpeedfloatStartgeschwindigkeit des Rennens [0.0-1.0]
hrTargetfloatDie Ziel-HR für HR-adaptives Spiel

Beispiele

Vorschlag Datenstruktur Sphery Racer <!-- omit in toc -->

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" } }
Vorschlag Datenstruktur Sphery Racer <!-- omit in toc -->

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>] } }
Vorschlag Datenstruktur Sphery Racer <!-- omit in toc -->

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" } }
Vorschlag Datenstruktur Sphery Racer <!-- omit in toc -->

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!" }
Vorschlag Datenstruktur Sphery Racer <!-- omit in toc -->

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 }
KeyTypBeschreibung
hrRestingPulseintRuhepuls der HR; null falls undefiniert
hrReserveintReservepuls der HR; null falls undefiniert
hrMaxintHR Max; null falls undefiniert
weightintGewicht (in kg); null falls undefiniert
ageintAlter; 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 }, ... ] }
KeyTypBeschreibung
namestringDer Name (und String-ID; unique) des Workouts
race{}Renn-spezifische Daten
→ seedintDer generierte Seed für die Erzeugung der Übungsreihenfolge auf dem Track
→ typestringUnterscheidet zwischen Konfigurationen im Racer, die Sphery kuratiert. Z.B. "workout", "competition", "studie_bern"
→ difficultyintSchwierigkeit des Rennens [0-2]
→ durationintDauer des Rennens (in Sekunden)
→ tutorialboolBoxenstopp Tutorials verwendet?
→ startSpeedfloatStartgeschwindigkeit des Rennens [0.0-1.0]
→ hrTargetfloatDie 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
→ cognitiveMinfloat?Minimale kognitive Adaptivität [0.0-1.0]
→ cognitiveMaxfloat?Maximale kognitive Adaptivität [0.0-1.0]
→ physicalMinfloat?Minimale physische Adaptivität [0.0-1.0]
→ physicalMaxfloat?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 }, ... ] }