List of relations
Schema | Name | Type | Owner
--------+-----------------+-------+----------------
public | HealthData | table | bydblzeeogvrzo
public | HrValues | table | bydblzeeogvrzo
public | RaceConfigs | table | bydblzeeogvrzo
public | SequelizeMeta | table | bydblzeeogvrzo
public | Sessions | table | bydblzeeogvrzo
public | TimelineMarkers | table | bydblzeeogvrzo
public | Users | table | bydblzeeogvrzo
public | WorkoutPresets | table | bydblzeeogvrzo
public | Workouts | table | bydblzeeogvrzo
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 |
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. |
Key | Typ | Beschreibung |
---|---|---|
hrValuesId | int |
ID der hrValues (DB index) |
time | float |
Sekunden seit beginn des Workouts |
value | int |
HR Value |
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) |
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 |
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. |
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) |
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 |
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"
}
}
Direkt nach dem Login und dem Erhalt des Authentifizierungs-Tokens und der Benutzer ID wird eine neue Spiel-Session gestartet.
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"
}
Als Antwort werden vom Server Benutzerspezifische Daten erwartet, welche für das Spiel erforderlich sind.
{
"session": {
"sessionId": 1,
"healthData": <health-data>,
"workouts": [...<workout>]
}
}
Zum Beenden der Session sendet das Spiel folgenden Request:
Type: PATCH
URI: https://sphery-1.herokuapp.com/api/v1/session
Header: Authorization: Bearer <token>
{
"sessionId": 1,
"logoutAt": "2021-01-25T12:57:38.184Z",
"sessionTime": 1547.23,
"netPromoterScore": 8
}
{
"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"
}
}
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.
Type: POST
URI: https://sphery-1.herokuapp.com/api/v1/workout
Header: Authorization: Bearer <token>
{
"completedWorkout":"true", // BOOLEAN
"hrTracking":"true", // BOOLEAN
"hrAverage":120, // INTEGER
"hrMax":200, // INTEGER
"score":600'000, // INTEGER
"maxCombo":81, // INTEGER
"bodyScore":0.89, // FLOAT
"brainScore":0.67, // FLOAT
"dualflowScore":0.78, // FLOAT
"measuredDuration":900.1, // FLOAT
"raceConfig": { // OBJECT
"seed": 45667567, // INTEGER
"adaptivityType": "hrTracking", // STRING
"difficulty": 2, // INTEGER
"duration": 900.00, // FLOAT
"tutorial": false, // BOOLEAN
"startSpeed": 5, // INTEGER
"hrTarget": 0.9 // FLOAT
},
"hrValues": [ // ARRAY (OPTIONAL)
{
"time": 3.02, // FLOAT
"value": 82 // INTEGER
},
{
"time": 6.13, // FLOAT
"value": 83 // INTEGER
},
...
],
"timelineMarkers": [ // ARRAY
{
"name": "exercise_midPunchLeft", // STRING
"readableName": "Punch Left", // STRING
"time": 2.14, // FLOAT
"tier": 2, // INTEGER
"physicalPrecision": 0.8, // FLOAT
"physicalRating": 3, // INTEGER
"cognitivePrecision": 0.6, // FLOAT
"cognitiveRating": 0, // INTEGER
"score": 230 // INTEGER
}
],
"workoutId": null, // NULL OR INTEGER (OPTIONAL) -> API CREATES NEW WORKOUT WHEN NO INTEGER (VALID ID OF EXISTING, NOT-COMPLETED WORKOUT) IS PROVIDED
"sessionId": 1, // INTEGER
"workoutPresetId": 4, // STRING
"challengeId": null // NULL OR INTEGER (OPTIONAL)
}
{
"Workout transfer successful! En schöne!"
}
{
"Öppis isch voll falsch gloffe!"
}
Hier werden alle Datensätze aufgeschlüsselt welche oft Inhalt der einzelnen Requests sein können und als eigene "Objekte" oder "Typen" gehandhabt werden.
{
"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 |
{
"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] |
{
"name": "exercise_midPunchLeft",
"readableName": "Punch Left",
"time": 2.14,
"tier": 2,
"physicalPrecision": 0.8,
"physicalRating": 3,
"cognitivePrecision": -1,
"cognitiveRating": 0,
"score": 230
}
Diese Beispiele zeigen wie jeweils ein voller Request für die oben beschriebenen Sync-Points am Ende strukturiert ist und aussehen könnte.
{
"loginAt": "2021-01-25T12:26:40.244Z",
"exercube": "SpheryCube1"
}
{
"sessionId": 1,
"logoutAt": "2021-01-25T12:57:38.184Z",
"sessionTime": 1800,
"netPromoterScore": 8
}
{
"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
},
...
]
}
Table "public.Workouts"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
------------------+--------------------------+-----------+----------+----------------------------------------+---------+--------------+-------------
id | integer | | not null | nextval('"Workouts_id_seq"'::regclass) | plain | |
completedWorkout | boolean | | not null | false | plain | |
hrTracking | boolean | | | | plain | |
hrAverage | integer | | | | plain | |
hrMax | integer | | | | plain | |
score | integer | | | | plain | |
maxCombo | integer | | | | plain | |
bodyScore | double precision | | | | plain | |
brainScore | double precision | | | | plain | |
dualflowScore | double precision | | | | plain | |
userId | integer | | | | plain | |
sessionId | integer | | | | plain | |
workoutPresetId | integer | | | | plain | |
createdAt | timestamp with time zone | | not null | | plain | |
updatedAt | timestamp with time zone | | not null | | plain | |
measuredDuration | double precision | | | | plain | |
Indexes:
"Workouts_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"Workouts_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "Sessions"(id) ON DELETE SET NULL
"Workouts_userId_fkey" FOREIGN KEY ("userId") REFERENCES "Users"(id) ON DELETE CASCADE
"Workouts_workoutPresetId_fkey" FOREIGN KEY ("workoutPresetId") REFERENCES "WorkoutPresets"(id) ON DELETE SET NULL
Referenced by:
TABLE ""HrValues"" CONSTRAINT "HrValues_workoutId_fkey" FOREIGN KEY ("workoutId") REFERENCES "Workouts"(id) ON DELETE CASCADE
TABLE ""RaceConfigs"" CONSTRAINT "RaceConfigs_workoutId_fkey" FOREIGN KEY ("workoutId") REFERENCES "Workouts"(id) ON DELETE CASCADE
TABLE ""TimelineMarkers"" CONSTRAINT "TimelineMarkers_workoutId_fkey" FOREIGN KEY ("workoutId") REFERENCES "Workouts"(id) ON DELETE CASCADE
Access method: heap
Table "public.HealthData"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
----------------+--------------------------+-----------+----------+------------------------------------------+---------+--------------+-------------
id | integer | | not null | nextval('"HealthData_id_seq"'::regclass) | plain | |
hrRestingPulse | integer | | | | plain | |
hrReserve | integer | | | | plain | |
hrMax | integer | | | | plain | |
weight | integer | | | | plain | |
age | integer | | | | plain | |
userId | integer | | | | plain | |
createdAt | timestamp with time zone | | not null | | plain | |
updatedAt | timestamp with time zone | | not null | | plain | |
Indexes:
"HealthData_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"HealthData_userId_fkey" FOREIGN KEY ("userId") REFERENCES "Users"(id) ON DELETE CASCADE
Access method: heap
Table "public.HrValues"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
-----------+--------------------------+-----------+----------+----------------------------------------+---------+--------------+-------------
id | integer | | not null | nextval('"HrValues_id_seq"'::regclass) | plain | |
time | double precision | | | | plain | |
value | integer | | | | plain | |
workoutId | integer | | | | plain | |
createdAt | timestamp with time zone | | not null | | plain | |
updatedAt | timestamp with time zone | | not null | | plain | |
Indexes:
"HrValues_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"HrValues_workoutId_fkey" FOREIGN KEY ("workoutId") REFERENCES "Workouts"(id) ON DELETE CASCADE
Access method: heap
Table "public.RaceConfigs"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
----------------+--------------------------+-----------+----------+-------------------------------------------+----------+--------------+-------------
id | integer | | not null | nextval('"RaceConfigs_id_seq"'::regclass) | plain | |
seed | integer | | | | plain | |
adaptivityType | character varying(255) | | | | extended | |
difficulty | integer | | | | plain | |
duration | double precision | | | | plain | |
tutorial | boolean | | | | plain | |
startSpeed | integer | | | | plain | |
hrTarget | double precision | | | | plain | |
workoutId | integer | | | | plain | |
createdAt | timestamp with time zone | | not null | | plain | |
updatedAt | timestamp with time zone | | not null | | plain | |
Indexes:
"RaceConfigs_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"RaceConfigs_workoutId_fkey" FOREIGN KEY ("workoutId") REFERENCES "Workouts"(id) ON DELETE CASCADE
Access method: heap
Table "public.Sessions"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
------------------+--------------------------+-----------+----------+----------------------------------------+----------+--------------+-------------
id | integer | | not null | nextval('"Sessions_id_seq"'::regclass) | plain | |
exercube | character varying(255) | | | | extended | |
loginAt | timestamp with time zone | | | | plain | |
logoutAt | timestamp with time zone | | | | plain | |
sessionTime | double precision | | | | plain | |
netPromoterScore | integer | | | | plain | |
userId | integer | | | | plain | |
createdAt | timestamp with time zone | | not null | | plain | |
updatedAt | timestamp with time zone | | not null | | plain | |
Indexes:
"Sessions_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"Sessions_userId_fkey" FOREIGN KEY ("userId") REFERENCES "Users"(id) ON DELETE CASCADE
Referenced by:
TABLE ""Workouts"" CONSTRAINT "Workouts_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "Sessions"(id) ON DELETE SET NULL
Access method: heap
Table "public.TimelineMarkers"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------------------+--------------------------+-----------+----------+-----------------------------------------------+----------+--------------+-------------
id | integer | | not null | nextval('"TimelineMarkers_id_seq"'::regclass) | plain | |
name | character varying(255) | | | | extended | |
readableName | character varying(255) | | | | extended | |
time | double precision | | | | plain | |
tier | integer | | | | plain | |
physicalPrecision | double precision | | | | plain | |
physicalRating | integer | | | | plain | |
cognitivePrecision | double precision | | | | plain | |
cognitiveRating | integer | | | | plain | |
score | integer | | | | plain | |
workoutId | integer | | | | plain | |
createdAt | timestamp with time zone | | not null | | plain | |
updatedAt | timestamp with time zone | | not null | | plain | |
Indexes:
"TimelineMarkers_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"TimelineMarkers_workoutId_fkey" FOREIGN KEY ("workoutId") REFERENCES "Workouts"(id) ON DELETE CASCADE
Access method: heap
Table "public.Users"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
------------------+--------------------------+-----------+----------+-------------------------------------+----------+--------------+-------------
id | integer | | not null | nextval('"Users_id_seq"'::regclass) | plain | |
email | character varying(255) | | | | extended | |
username | character varying(255) | | | | extended | |
password | character varying(255) | | | | extended | |
verified | boolean | | not null | false | plain | |
verificationCode | character varying(255) | | | | extended | |
createdAt | timestamp with time zone | | not null | | plain | |
updatedAt | timestamp with time zone | | not null | | plain | |
Indexes:
"Users_pkey" PRIMARY KEY, btree (id)
"Users_email_key" UNIQUE CONSTRAINT, btree (email)
Referenced by:
TABLE ""HealthData"" CONSTRAINT "HealthData_userId_fkey" FOREIGN KEY ("userId") REFERENCES "Users"(id) ON DELETE CASCADE
TABLE ""Sessions"" CONSTRAINT "Sessions_userId_fkey" FOREIGN KEY ("userId") REFERENCES "Users"(id) ON DELETE CASCADE
TABLE ""Workouts"" CONSTRAINT "Workouts_userId_fkey" FOREIGN KEY ("userId") REFERENCES "Users"(id) ON DELETE CASCADE
Access method: heap
Table "public.WorkoutPresets"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
-------------------+--------------------------+-----------+----------+----------------------------------------------+----------+--------------+-------------
id | integer | | not null | nextval('"WorkoutPresets_id_seq"'::regclass) | plain | |
name | character varying(255) | | | | extended | |
customizable | boolean | | | | plain | |
descriptionText | character varying(255) | | | | extended | |
fixedRaceConfigId | integer | | | | plain | |
exercisePool | character varying(255) | | | | extended | |
createdAt | timestamp with time zone | | not null | | plain | |
updatedAt | timestamp with time zone | | not null | | plain | |
Indexes:
"WorkoutPresets_pkey" PRIMARY KEY, btree (id)
Referenced by:
TABLE ""Workouts"" CONSTRAINT "Workouts_workoutPresetId_fkey" FOREIGN KEY ("workoutPresetId") REFERENCES "WorkoutPresets"(id) ON DELETE SET NULL
Access method: heap