# How to Extend the Exercises Dataset While Maintaining JSON Schema Compliance

> Easily extend the exercises dataset while maintaining JSON Schema compliance. Learn to add new records and media then validate your changes for a seamless update.

- Repository: [Hasan Emir Yıldırım/exercises-dataset](https://github.com/hasaneyldrm/exercises-dataset)
- Tags: how-to-guide
- Published: 2026-07-28

---

**To safely extend the exercises dataset while maintaining JSON Schema compliance, append a valid record to [`data/exercises.json`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.json), add matching 180×180 media files to `images/` and `videos/`, and validate the full array against [`data/exercises.schema.json`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.schema.json) using a tool such as ajv or Python's `jsonschema` before committing.**

The `hasaneyldrm/exercises-dataset` repository powers the LogPress fitness app with a strictly validated JSON dataset. To extend the exercises dataset while maintaining JSON Schema compliance, every new record must conform to the Draft 2020-12 schema defined in [`data/exercises.schema.json`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.schema.json). The repository architecture is intentionally simple, making it easy to append records, manage media, and validate changes before submission.

## Core Files and Schema Contract

The dataset is organized around a few key files that work together to ensure portability and downstream compatibility:

- **[`data/exercises.json`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.json)** — The master list of 1,324 exercise objects containing metadata, multilingual instructions, and media links.
- **[`data/exercises.schema.json`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.schema.json)** — The validation contract (Draft 2020-12 JSON Schema) that enforces field types, required properties, and enumerated values.
- **`images/`** — Directory of 180×180 thumbnail images (media © Gym visual).
- **`videos/`** — Directory of 180×180 animation GIFs (media © Gym visual).
- **[`index.html`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/index.html)** — A pure-client-side browser that renders each exercise card without requiring a server.
- **[`setup.html`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/setup.html)** — A developer guide that generates SQL-INSERT scripts, API-client snippets, and LLM prompts.

## Step-by-Step Workflow to Extend the Exercises Dataset

Follow these steps to grow the catalog while guaranteeing schema compliance. Each step maps directly to constraints defined in [`data/exercises.schema.json`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.schema.json).

### 1. Append a New Record to [`data/exercises.json`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.json)

Every object in the array must contain the schema-defined fields: `id`, `name`, `category`, `body_part`, `equipment`, `instructions`, `instruction_steps`, `muscle_group`, `image`, `gif_url`, and `attribution`. These required properties are specified in [`data/exercises.schema.json`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.schema.json) (lines 54–62, 64–71, and 85–88). Omitting any of them will cause validation to fail immediately.

### 2. Observe the Zero-Padded `id` Format

The schema mandates that `id` match the regular expression `"^[0-9]{4}$"` (lines 57–58), which means a zero-padded four-digit string such as `"1324"`. Use the next sequential number that does not clash with existing IDs. For example, if the current highest ID is `"1324"`, assign `"1325"` to the new record.

### 3. Choose a Valid `body_part` Enumeration

The `body_part` property only accepts values from a strict enum list defined in [`data/exercises.schema.json`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.schema.json) (lines 72–83). Allowed values include `"back"`, `"cardio"`, `"chest"`, and `"waist"` among others. Selecting a value outside this set will break schema compliance.

### 4. Populate Multilingual Instructions

The `instructions` field is a **language map** (`languageMap`) where each key is an ISO-639-1 language code. The schema requires every record to include `en`, `es`, `it`, `tr`, `ru`, `zh`, `hi`, `pl`, `ko`, and `fr` (schema `required` list, lines 26–27). The parallel `instruction_steps` field follows the `languageStepsMap` definition (lines 29–45) and must provide the same content as an array of step strings per language.

### 5. Add Corresponding Media Assets

Place a 180×180 thumbnail in `images/` and a matching GIF in `videos/`. Name them consistently, for example `1325-thumbnail.png` and `1325-animation.gif`. Reference them in the JSON via relative paths such as `"image": "images/1325-thumbnail.png"` and `"gif_url": "videos/1325-animation.gif"`.

### 6. Validate Against [`data/exercises.schema.json`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.schema.json)

Run a JSON Schema validator against the entire array before committing. If you use Node.js, **ajv** provides a fast CLI check:

```bash
npx ajv validate -s data/exercises.schema.json -d data/exercises.json

```

If the new record conforms, the command exits with status 0. Otherwise, it prints detailed error messages pointing to the offending property.

### 7. Preview in the Interactive Browser

Open [`index.html`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/index.html) in any modern browser to verify the new exercise renders correctly as a card. Use the search or filter controls to confirm that the `category`, `equipment`, and `body_part` facets behave as expected. This client-side preview does not require a backend server.

## Validation Examples and Scripts

These concrete examples show how to format a new record and validate it.

### Minimal New Exercise JSON

The following object illustrates the minimal structure for ID `"1325"`:

```json
{
  "id": "1325",
  "name": "Dumbbell Front Raise",
  "category": "shoulders",
  "body_part": "shoulders",
  "equipment": "dumbbell",
  "muscle_group": "anterior deltoid",
  "image": "images/1325-thumbnail.png",
  "gif_url": "videos/1325-animation.gif",
  "attribution": "Gym visual",
  "instructions": {
    "en": "Stand upright holding a dumbbell in each hand …",
    "es": "Párate erguido sosteniendo una mancuerna …",
    "it": "Stai in piedi con una kettlebell in entrambe le mani …",
    "tr": "Ayakta iki dambıl tutarak …",
    "ru": "Стоя, держите гантели …",
    "zh": "站立，双手各握一个哑铃 …",
    "hi": "खड़े होकर दो डंबल हाथों में …",
    "pl": "Stań prosto trzymając hantle …",
    "ko": "양손에 덤벨을 들고 서서 …",
    "fr": "Debout, tenez une haltère dans chaque main …"
  },
  "instruction_steps": {
    "en": [
      "Stand upright holding a dumbbell in each hand.",
      "Raise the dumbbells forward to shoulder height.",
      "Pause briefly, then lower slowly."
    ]
  }
}

```

Repeat the `instruction_steps` array structure for every required ISO-639-1 language key.

### Validate with the ajv CLI

Install **ajv-cli** globally and run validation:

```bash

# Install the validator (once)

npm install -g ajv-cli

# Validate the entire dataset after adding the new record

ajv validate -s data/exercises.schema.json -d data/exercises.json

```

### Validate Programmatically with Python

Use the `jsonschema` library to append and validate in one script:

```python
import json, jsonschema, pathlib

schema_path = pathlib.Path('data/exercises.schema.json')
data_path   = pathlib.Path('data/exercises.json')

with schema_path.open() as f:
    schema = json.load(f)

with data_path.open() as f:
    exercises = json.load(f)

new_ex = { ... }      # JSON object from Example 1

exercises.append(new_ex)

# Validate the full array

jsonschema.validate(instance=exercises, schema=schema)

# Write back if validation succeeded

with data_path.open('w') as f:
    json.dump(exercises, f, indent=2, ensure_ascii=False)

```

## Summary

- Append new records to [`data/exercises.json`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.json) using the exact required field set defined in [`data/exercises.schema.json`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.schema.json) (lines 54–88).
- Assign a zero-padded four-digit `id` and choose `body_part` values from the schema enum (lines 72–83).
- Include all ten mandatory ISO-639-1 language keys in both `instructions` and `instruction_steps`.
- Add 180×180 media files to `images/` and `videos/`, then reference them with relative paths.
- Validate the full array with **ajv** or Python's `jsonschema` before committing.
- Preview changes locally by opening [`index.html`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/index.html) in a browser.

## Frequently Asked Questions

### What fields are required for every exercise record?

The schema requires `id`, `name`, `category`, `body_part`, `equipment`, `instructions`, `instruction_steps`, `muscle_group`, `image`, `gif_url`, and `attribution` (see [`data/exercises.schema.json`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.schema.json), lines 54–62, 64–71, and 85–88). Every property must be present and correctly typed for the record to pass validation.

### Which languages are mandatory for the instructions object?

The `instructions` field must provide a **language map** containing the ISO-639-1 keys `en`, `es`, `it`, `tr`, `ru`, `zh`, `hi`, `pl`, `ko`, and `fr` (schema required list, lines 26–27). The same languages must appear in the `instruction_steps` array map defined at lines 29–45.

### How do I validate the dataset after adding a new exercise?

Run `npx ajv validate -s data/exercises.schema.json -d data/exercises.json` for a quick CLI check, or use a Python script with the `jsonschema` library to validate programmatically. A successful run exits with code 0; failures surface detailed paths to the invalid properties.

### Can I preview the dataset without setting up a backend server?

Yes. Open [`index.html`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/index.html) directly in a modern browser. It is a pure-client-side application that renders exercise cards, thumbnails, and GIFs without any server, and it reflects new records as soon as they are added to [`data/exercises.json`](https://github.com/hasaneyldrm/exercises-dataset/blob/main/data/exercises.json).