first commit

This commit is contained in:
Hamza-Ayed
2026-10-04 00:19:45 +03:00
commit 05f1c9ec6b
93 changed files with 10782 additions and 0 deletions
+150
View File
@@ -0,0 +1,150 @@
-- Fitness Tracking App - Production Database Schema
-- Database: fitness_app
-- Created: 2026-04-21
-- Create Database
CREATE DATABASE IF NOT EXISTS fitness_app CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE fitness_app;
-- Users Table
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
uuid CHAR(36) UNIQUE NOT NULL COMMENT 'Unique identifier for the user',
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL COMMENT 'bcrypt hash',
api_key VARCHAR(64) UNIQUE NOT NULL COMMENT 'API key for client authentication',
api_secret VARCHAR(64) NOT NULL COMMENT 'Secret for HMAC signature',
full_name VARCHAR(100),
avatar_url VARCHAR(255),
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_uuid (uuid),
INDEX idx_api_key (api_key),
INDEX idx_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- Workouts Table
CREATE TABLE IF NOT EXISTS workouts (
id INT AUTO_INCREMENT PRIMARY KEY,
workout_uuid CHAR(36) UNIQUE NOT NULL COMMENT 'Unique identifier for the workout',
user_id INT NOT NULL,
workout_type ENUM('running', 'walking') NOT NULL,
distance_meters INT NOT NULL COMMENT 'Total distance in meters',
duration_seconds INT NOT NULL COMMENT 'Total duration in seconds',
elevation_gain_meters INT DEFAULT 0 COMMENT 'Elevation gain in meters',
elevation_loss_meters INT DEFAULT 0 COMMENT 'Elevation loss in meters',
calories_burned FLOAT DEFAULT 0,
average_pace_mps FLOAT COMMENT 'Average pace in meters per second',
max_speed_mps FLOAT DEFAULT 0 COMMENT 'Max speed in meters per second',
route_polyline LONGTEXT NOT NULL COMMENT 'Encoded polyline format (Google Maps Polyline Algorithm)',
coordinate_count INT NOT NULL COMMENT 'Total number of GPS coordinates recorded',
start_lat DECIMAL(10, 8) NOT NULL,
start_lng DECIMAL(11, 8) NOT NULL,
end_lat DECIMAL(10, 8) NOT NULL,
end_lng DECIMAL(11, 8) NOT NULL,
start_time DATETIME NOT NULL COMMENT 'ISO 8601 datetime when workout started',
end_time DATETIME NOT NULL COMMENT 'ISO 8601 datetime when workout ended',
weather_condition VARCHAR(50),
temperature_celsius FLOAT,
notes TEXT,
is_public BOOLEAN DEFAULT FALSE,
synced_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
INDEX idx_workout_uuid (workout_uuid),
INDEX idx_user_id (user_id),
INDEX idx_workout_type (workout_type),
INDEX idx_synced_at (synced_at),
INDEX idx_created_at (created_at),
INDEX idx_user_created (user_id, created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- Workout Segments Table (for detailed route tracking if needed)
CREATE TABLE IF NOT EXISTS workout_segments (
id INT AUTO_INCREMENT PRIMARY KEY,
workout_id INT NOT NULL,
segment_order INT NOT NULL COMMENT 'Order of segment in workout',
duration_seconds INT,
distance_meters INT,
average_pace_mps FLOAT,
index_in_polyline INT COMMENT 'Start index in polyline',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (workout_id) REFERENCES workouts(id) ON DELETE CASCADE,
INDEX idx_workout_id (workout_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- API Logs Table (for debugging and analytics)
CREATE TABLE IF NOT EXISTS api_logs (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT,
endpoint VARCHAR(255),
method VARCHAR(10),
status_code INT,
request_hash VARCHAR(64) COMMENT 'Hash of request for deduplication',
ip_address VARCHAR(45),
user_agent VARCHAR(255),
response_time_ms INT,
error_message TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_user_id (user_id),
INDEX idx_created_at (created_at),
INDEX idx_endpoint (endpoint),
INDEX idx_request_hash (request_hash)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- Statistics Cache Table (for performance optimization)
CREATE TABLE IF NOT EXISTS user_stats_cache (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT UNIQUE NOT NULL,
total_workouts INT DEFAULT 0,
total_distance_meters INT DEFAULT 0,
total_duration_seconds INT DEFAULT 0,
total_calories_burned FLOAT DEFAULT 0,
average_pace_mps FLOAT,
last_workout_date DATETIME,
streak_days INT DEFAULT 0,
cached_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
INDEX idx_user_id (user_id),
INDEX idx_cached_at (cached_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- Create Triggers for audit trail
DELIMITER $$
CREATE TRIGGER workout_audit_insert AFTER INSERT ON workouts
FOR EACH ROW
BEGIN
INSERT INTO api_logs (endpoint, method, status_code, error_message, created_at)
VALUES ('workouts', 'INSERT', 201, NULL, NOW());
END $$
DELIMITER ;
-- Stored Procedure to get user workout statistics
DELIMITER $$
CREATE PROCEDURE GetUserStats(IN p_user_id INT)
BEGIN
SELECT
COUNT(*) as total_workouts,
SUM(distance_meters) as total_distance,
SUM(duration_seconds) as total_duration,
SUM(calories_burned) as total_calories,
AVG(average_pace_mps) as avg_pace,
MAX(created_at) as last_workout,
workout_type
FROM workouts
WHERE user_id = p_user_id
GROUP BY workout_type
ORDER BY created_at DESC;
END $$
DELIMITER ;
-- Initial indexes for optimal query performance
CREATE INDEX idx_workouts_stats ON workouts(user_id, workout_type, created_at);
CREATE INDEX idx_users_active ON users(is_active, created_at);