From a081e7279386517128c2b195cdd16438987fbd85 Mon Sep 17 00:00:00 2001 From: serafettin Date: Thu, 9 Jul 2026 06:08:43 +0300 Subject: [PATCH] Add JSON Schema for exercises dataset Adds data/exercises.schema.json (Draft 2020-12) describing every field, its type and constraints, so the dataset and community additions can be validated with any standard JSON Schema validator. Validated against all 1,324 records with zero errors. Also documents the previously undocumented instruction_steps field and references the schema from the README. --- README.md | 7 +- data/exercises.schema.json | 151 +++++++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 data/exercises.schema.json diff --git a/README.md b/README.md index 33e86c9..48e8eed 100644 --- a/README.md +++ b/README.md @@ -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.` | `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"`) | diff --git a/data/exercises.schema.json b/data/exercises.schema.json new file mode 100644 index 0000000..33b4b5b --- /dev/null +++ b/data/exercises.schema.json @@ -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 + } + } +}