Merge pull request #34 from sarisen/add-json-schema
Add JSON Schema for exercises dataset
This commit is contained in:
@@ -105,7 +105,8 @@ A step-by-step guide for integrating the dataset into your own application:
|
||||
```
|
||||
exercises-dataset/
|
||||
├── data/
|
||||
│ └── exercises.json # Full dataset — 1,324 exercise records (JSON array)
|
||||
│ ├── exercises.json # Full dataset — 1,324 exercise records (JSON array)
|
||||
│ └── exercises.schema.json # JSON Schema (2020-12) describing every record
|
||||
├── images/ # 1,324 × 180×180 thumbnails (© Gym visual)
|
||||
├── videos/ # 1,324 × 180×180 animation GIFs (© Gym visual)
|
||||
├── index.html # Interactive exercise browser (client-side, no server needed)
|
||||
@@ -117,6 +118,7 @@ exercises-dataset/
|
||||
### Key Files
|
||||
|
||||
- **`data/exercises.json`** — The primary data file. A JSON array of 1,324 exercise objects with all metadata. `image` / `gif_url` point to the local 180×180 assets, and each record carries an `attribution` field; `media_id` holds the original media reference id.
|
||||
- **`data/exercises.schema.json`** — A [JSON Schema](https://json-schema.org/) (Draft 2020-12) that formally describes every field, its type and constraints. Use it to validate the dataset or your own additions with any standard JSON Schema validator.
|
||||
- **`images/`, `videos/`** — 180×180 thumbnails and animation GIFs (© [Gym visual](https://gymvisual.com/), used with permission).
|
||||
- **`index.html`** — Standalone exercise browser. Open directly in any modern browser.
|
||||
- **`setup.html`** — Developer guide for DB setup, API integration, and LLM-assisted backend generation.
|
||||
@@ -169,7 +171,7 @@ exercises-dataset/
|
||||
|
||||
## 🗂️ Data Schema
|
||||
|
||||
Each record in `data/exercises.json` follows this structure:
|
||||
Each record in `data/exercises.json` follows this structure. A machine-readable [JSON Schema](data/exercises.schema.json) is also provided for validation.
|
||||
|
||||
| Field | Type | Description |
|
||||
|---|---|---|
|
||||
@@ -184,6 +186,7 @@ Each record in `data/exercises.json` follows this structure:
|
||||
| `instructions.tr` | `string` | Full step-by-step instructions in Turkish |
|
||||
| `instructions.ru` | `string` | Full step-by-step instructions in Russian |
|
||||
| `instructions.zh` | `string` | Full step-by-step instructions in Chinese |
|
||||
| `instruction_steps.<lang>` | `array[string]` | Same instructions split into an ordered array of steps, per language (`en`, `es`, `it`, `tr`, `ru`, `zh`) |
|
||||
| `muscle_group` | `string` | Primary synergist muscle group |
|
||||
| `secondary_muscles` | `array[string]` | Additional muscles involved |
|
||||
| `target` | `string` | Primary target muscle (e.g. `"biceps"`, `"pectoralis major"`) |
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.schema.json",
|
||||
"title": "Exercises Dataset",
|
||||
"description": "Schema for data/exercises.json — an array of fitness exercise records with multilingual instructions and media references.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/$defs/exercise"
|
||||
},
|
||||
"$defs": {
|
||||
"languageMap": {
|
||||
"type": "object",
|
||||
"description": "Instruction text keyed by ISO 639-1 language code.",
|
||||
"properties": {
|
||||
"en": { "type": "string" },
|
||||
"es": { "type": "string" },
|
||||
"it": { "type": "string" },
|
||||
"tr": { "type": "string" },
|
||||
"ru": { "type": "string" },
|
||||
"zh": { "type": "string" }
|
||||
},
|
||||
"required": ["en", "es", "it", "tr", "ru", "zh"],
|
||||
"additionalProperties": { "type": "string" }
|
||||
},
|
||||
"languageStepsMap": {
|
||||
"type": "object",
|
||||
"description": "Step-by-step instructions as an array of strings, keyed by ISO 639-1 language code.",
|
||||
"properties": {
|
||||
"en": { "$ref": "#/$defs/steps" },
|
||||
"es": { "$ref": "#/$defs/steps" },
|
||||
"it": { "$ref": "#/$defs/steps" },
|
||||
"tr": { "$ref": "#/$defs/steps" },
|
||||
"ru": { "$ref": "#/$defs/steps" },
|
||||
"zh": { "$ref": "#/$defs/steps" }
|
||||
},
|
||||
"required": ["en", "es", "it", "tr", "ru", "zh"],
|
||||
"additionalProperties": { "$ref": "#/$defs/steps" }
|
||||
},
|
||||
"steps": {
|
||||
"type": "array",
|
||||
"items": { "type": "string", "minLength": 1 }
|
||||
},
|
||||
"exercise": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Unique numeric identifier, zero-padded to 4 digits (e.g. \"0001\").",
|
||||
"pattern": "^[0-9]{4}$"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Full exercise name (e.g. \"3/4 sit-up\").",
|
||||
"minLength": 1
|
||||
},
|
||||
"category": {
|
||||
"type": "string",
|
||||
"description": "Body part category. Mirrors body_part.",
|
||||
"minLength": 1
|
||||
},
|
||||
"body_part": {
|
||||
"type": "string",
|
||||
"description": "Body part targeted.",
|
||||
"enum": [
|
||||
"back",
|
||||
"cardio",
|
||||
"chest",
|
||||
"lower arms",
|
||||
"lower legs",
|
||||
"neck",
|
||||
"shoulders",
|
||||
"upper arms",
|
||||
"upper legs",
|
||||
"waist"
|
||||
]
|
||||
},
|
||||
"equipment": {
|
||||
"type": "string",
|
||||
"description": "Required equipment (e.g. \"dumbbell\", \"body weight\").",
|
||||
"minLength": 1
|
||||
},
|
||||
"instructions": {
|
||||
"$ref": "#/$defs/languageMap",
|
||||
"description": "Full step-by-step instructions as a single string per language."
|
||||
},
|
||||
"instruction_steps": {
|
||||
"$ref": "#/$defs/languageStepsMap",
|
||||
"description": "Same instructions split into an ordered array of steps per language."
|
||||
},
|
||||
"muscle_group": {
|
||||
"type": "string",
|
||||
"description": "Primary synergist muscle group.",
|
||||
"minLength": 1
|
||||
},
|
||||
"secondary_muscles": {
|
||||
"type": "array",
|
||||
"description": "Additional muscles involved.",
|
||||
"items": { "type": "string", "minLength": 1 }
|
||||
},
|
||||
"target": {
|
||||
"type": "string",
|
||||
"description": "Primary target muscle (e.g. \"biceps\", \"abs\").",
|
||||
"minLength": 1
|
||||
},
|
||||
"media_id": {
|
||||
"type": "string",
|
||||
"description": "Original media reference id (e.g. \"2gPfomN\").",
|
||||
"minLength": 1
|
||||
},
|
||||
"image": {
|
||||
"type": "string",
|
||||
"description": "Path to the 180x180 thumbnail (e.g. \"images/0001-2gPfomN.jpg\").",
|
||||
"pattern": "^images/.+\\.(jpg|jpeg|png)$"
|
||||
},
|
||||
"gif_url": {
|
||||
"type": "string",
|
||||
"description": "Path to the 180x180 animation GIF (e.g. \"videos/0001-2gPfomN.gif\").",
|
||||
"pattern": "^videos/.+\\.gif$"
|
||||
},
|
||||
"attribution": {
|
||||
"type": "string",
|
||||
"description": "Media copyright notice.",
|
||||
"minLength": 1
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"description": "ISO 8601 timestamp of record creation.",
|
||||
"format": "date-time"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"category",
|
||||
"body_part",
|
||||
"equipment",
|
||||
"instructions",
|
||||
"instruction_steps",
|
||||
"muscle_group",
|
||||
"secondary_muscles",
|
||||
"target",
|
||||
"media_id",
|
||||
"image",
|
||||
"gif_url",
|
||||
"attribution",
|
||||
"created_at"
|
||||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user