massive frontend refactoring (works good)
This commit is contained in:
+224
@@ -0,0 +1,224 @@
|
||||
-- ============================================================
|
||||
-- Gym Tracker — SQLite schema v2
|
||||
-- Гибкие справочники + мультиклиентская схема
|
||||
-- ============================================================
|
||||
|
||||
PRAGMA foreign_keys = ON;
|
||||
PRAGMA journal_mode = WAL;
|
||||
|
||||
-- ============================================================
|
||||
-- 1. КЛИЕНТЫ (люди, чьи тренировки ведём)
|
||||
-- ============================================================
|
||||
CREATE TABLE clients (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
sync_id TEXT NOT NULL UNIQUE, -- UUID для синхронизации
|
||||
full_name TEXT NOT NULL,
|
||||
birth_date TEXT, -- ISO8601 (YYYY-MM-DD)
|
||||
goal TEXT DEFAULT '', -- цель тренировок
|
||||
notes TEXT DEFAULT '',
|
||||
is_active INTEGER NOT NULL DEFAULT 1,
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
|
||||
);
|
||||
|
||||
CREATE INDEX idx_clients_name ON clients(full_name);
|
||||
CREATE INDEX idx_clients_active ON clients(is_active);
|
||||
|
||||
-- ============================================================
|
||||
-- 2. СПРАВОЧНИК ТИПОВ ТРЕНИРОВОК
|
||||
-- ============================================================
|
||||
CREATE TABLE workout_types (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
sync_id TEXT NOT NULL UNIQUE,
|
||||
name TEXT NOT NULL UNIQUE,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- 3. СПРАВОЧНИК УПРАЖНЕНИЙ
|
||||
-- ============================================================
|
||||
CREATE TABLE exercises (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
sync_id TEXT NOT NULL UNIQUE,
|
||||
workout_type_id INTEGER, -- FK на workout_types
|
||||
name TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
||||
|
||||
FOREIGN KEY (workout_type_id) REFERENCES workout_types(id) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_exercises_name ON exercises(name);
|
||||
CREATE INDEX idx_exercises_type ON exercises(workout_type_id);
|
||||
|
||||
-- ============================================================
|
||||
-- 4. ТРЕНИРОВКИ
|
||||
-- ============================================================
|
||||
CREATE TABLE workouts (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
sync_id TEXT NOT NULL UNIQUE,
|
||||
client_id INTEGER, -- FK на clients
|
||||
workout_type_id INTEGER, -- FK на workout_types
|
||||
start_time TEXT NOT NULL, -- ISO8601
|
||||
end_time TEXT, -- NULL = активная
|
||||
notes TEXT DEFAULT '',
|
||||
synced INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
||||
|
||||
FOREIGN KEY (client_id) REFERENCES clients(id) ON DELETE SET NULL,
|
||||
FOREIGN KEY (workout_type_id) REFERENCES workout_types(id) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_workouts_client ON workouts(client_id);
|
||||
CREATE INDEX idx_workouts_start ON workouts(start_time);
|
||||
CREATE INDEX idx_workouts_synced ON workouts(synced);
|
||||
|
||||
-- ============================================================
|
||||
-- 5. УПРАЖНЕНИЯ ВНУТРИ ТРЕНИРОВКИ
|
||||
-- ============================================================
|
||||
CREATE TABLE workout_exercises (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
sync_id TEXT NOT NULL UNIQUE,
|
||||
workout_id INTEGER NOT NULL,
|
||||
exercise_id INTEGER, -- FK на exercises (может быть NULL)
|
||||
exercise_name TEXT NOT NULL, -- дублируем для истории
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
||||
|
||||
FOREIGN KEY (workout_id) REFERENCES workouts(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (exercise_id) REFERENCES exercises(id) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_wex_workout ON workout_exercises(workout_id);
|
||||
CREATE INDEX idx_wex_exercise ON workout_exercises(exercise_id);
|
||||
CREATE INDEX idx_wex_name ON workout_exercises(exercise_name);
|
||||
|
||||
-- ============================================================
|
||||
-- 6. ПОДХОДЫ
|
||||
-- ============================================================
|
||||
CREATE TABLE sets (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
sync_id TEXT NOT NULL UNIQUE,
|
||||
workout_exercise_id INTEGER NOT NULL,
|
||||
is_dropset INTEGER NOT NULL DEFAULT 0,
|
||||
weight REAL,
|
||||
reps INTEGER,
|
||||
rating INTEGER CHECK (rating BETWEEN 1 AND 5),
|
||||
notes TEXT DEFAULT '',
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
timestamp TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
||||
|
||||
FOREIGN KEY (workout_exercise_id) REFERENCES workout_exercises(id) ON DELETE CASCADE,
|
||||
|
||||
CHECK (
|
||||
(is_dropset = 0 AND weight IS NOT NULL AND reps IS NOT NULL) OR
|
||||
(is_dropset = 1 AND weight IS NULL AND reps IS NULL)
|
||||
)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_sets_wex ON sets(workout_exercise_id);
|
||||
CREATE INDEX idx_sets_timestamp ON sets(timestamp);
|
||||
|
||||
-- ============================================================
|
||||
-- 7. ЭЛЕМЕНТЫ ДРОП-СЕТА
|
||||
-- ============================================================
|
||||
CREATE TABLE dropset_items (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
set_id INTEGER NOT NULL,
|
||||
weight REAL NOT NULL,
|
||||
reps INTEGER NOT NULL,
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
FOREIGN KEY (set_id) REFERENCES sets(id) ON DELETE CASCADE,
|
||||
CHECK (weight > 0 AND reps > 0)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_dropset_set ON dropset_items(set_id);
|
||||
|
||||
-- ============================================================
|
||||
-- 8. КАРДИО
|
||||
-- ============================================================
|
||||
CREATE TABLE cardio (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
sync_id TEXT NOT NULL UNIQUE,
|
||||
workout_id INTEGER NOT NULL,
|
||||
cardio_type TEXT NOT NULL CHECK (cardio_type IN (
|
||||
'вело', 'ходьба', 'бег', 'эллипс', 'гребля'
|
||||
)),
|
||||
purpose TEXT NOT NULL CHECK (purpose IN (
|
||||
'warmup', 'cooldown', 'separate'
|
||||
)),
|
||||
duration INTEGER,
|
||||
distance REAL,
|
||||
speed REAL,
|
||||
incline REAL,
|
||||
resistance INTEGER,
|
||||
notes TEXT DEFAULT '',
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
||||
|
||||
FOREIGN KEY (workout_id) REFERENCES workouts(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX idx_cardio_workout ON cardio(workout_id);
|
||||
CREATE INDEX idx_cardio_purpose ON cardio(purpose);
|
||||
|
||||
-- ============================================================
|
||||
-- 9. СПРАВОЧНИК ТИПОВ ЗАМЕРОВ ТЕЛА
|
||||
-- ============================================================
|
||||
CREATE TABLE metric_types (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
sync_id TEXT NOT NULL UNIQUE,
|
||||
name TEXT NOT NULL UNIQUE, -- "Вес", "Грудь", "Бицепс", "Предплечье"...
|
||||
unit TEXT NOT NULL DEFAULT 'см', -- единица измерения
|
||||
category TEXT DEFAULT 'body', -- для группировки: body, strength, etc.
|
||||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- 10. ЗАМЕРЫ ТЕЛА (факт замера)
|
||||
-- ============================================================
|
||||
CREATE TABLE body_metrics (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
sync_id TEXT NOT NULL UNIQUE,
|
||||
client_id INTEGER, -- FK на clients
|
||||
metric_date TEXT NOT NULL, -- ISO8601
|
||||
notes TEXT DEFAULT '',
|
||||
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
||||
|
||||
FOREIGN KEY (client_id) REFERENCES clients(id) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_body_metrics_client ON body_metrics(client_id);
|
||||
CREATE INDEX idx_body_metrics_date ON body_metrics(metric_date);
|
||||
|
||||
-- ============================================================
|
||||
-- 11. ЗНАЧЕНИЯ ЗАМЕРОВ (нормализованно)
|
||||
-- ============================================================
|
||||
CREATE TABLE body_metric_values (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
body_metric_id INTEGER NOT NULL,
|
||||
metric_type_id INTEGER NOT NULL,
|
||||
value REAL NOT NULL,
|
||||
|
||||
FOREIGN KEY (body_metric_id) REFERENCES body_metrics(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (metric_type_id) REFERENCES metric_types(id) ON DELETE CASCADE,
|
||||
|
||||
UNIQUE (body_metric_id, metric_type_id) -- один тип замера — одно значение в замере
|
||||
);
|
||||
|
||||
CREATE INDEX idx_bmv_metric ON body_metric_values(body_metric_id);
|
||||
CREATE INDEX idx_bmv_type ON body_metric_values(metric_type_id);
|
||||
|
||||
-- ============================================================
|
||||
-- 12. ЛОГ СИНХРОНИЗАЦИИ
|
||||
-- ============================================================
|
||||
CREATE TABLE sync_log (
|
||||
device_id TEXT PRIMARY KEY,
|
||||
last_sync TEXT NOT NULL,
|
||||
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
|
||||
);
|
||||
Reference in New Issue
Block a user