From: Ole B. Rosentreter Date: Thu, 11 Sep 2025 21:03:18 +0000 (+0200) Subject: Deepseek-Entwurf implementiert: X-Git-Url: https://git.laktatnebel.de/?a=commitdiff_plain;ds=sidebyside;p=athletik.triathlon-coaching.com.git Deepseek-Entwurf implementiert: https://chat.deepseek.com/a/chat/s/6dd814bc-36bb-4711-afea-e6df04cdc271 https://ticket.laktatnebel.de/issue.php?issuedetail=170 --- diff --git a/athletik-db/pom.xml b/athletik-db/pom.xml index 90adcbc..f041b3c 100644 --- a/athletik-db/pom.xml +++ b/athletik-db/pom.xml @@ -1,18 +1,17 @@ 4.0.0 - com.triathlon-coaching.product - athletik.athletik-db - 0.0.1-SNAPSHOT + athletik.db pom - ${product.artifactId} + ${project.artifactId} Athletik Training DB - de.laktatnebel.maven - laktatnebelscript - 2.1.9 + com.triathlon-coaching.product + athletik + 0.0.1-SNAPSHOT + diff --git a/athletik-db/sql/data.sql b/athletik-db/sql/data.sql new file mode 100644 index 0000000..a70f13f --- /dev/null +++ b/athletik-db/sql/data.sql @@ -0,0 +1,105 @@ +insert into athletik.users values +(default, 'oleb', 'Ole', 'training@ole-b-rosentreter.de', 'xyz'), +(default, 'lasse', 'Lasse', 'email@lasse-gehrmann.de', 'xyz') +; + +insert into athletik.tools values +(default, 'none', 'kein', 0, 0, 0, ''), +(default, 'Bodyweight', 'Körpergewicht', 0, 0, 0, ''), +(default, 'Barbell', 'Langhantel', 20, 2.5, 200, 'Scheiben auf der Langhantel immer mit Klammern sichern !!!'), +(default, 'Bumbbell', 'Kurzhantel', 10, 2.5, 70, ''), +(default, 'Mini Dumbbell', 'Minihantel', 1, 1, 20, ''), +(default, 'Cable', 'Kabelzug', 3.75, 2.5, 100, ''), +(default, 'Cable', 'Seilzug', 3.75, 2.5, 100, ''), +(default, 'Cable Row', 'Rudermaschine/Seilzug', 15, 10, 95, ''), +(default, 'Cable Lat', 'Latzug', 15, 10, 95, ''), +(default, 'Easy Bar', 'Curlhantel', 20, 2.5, 200, 'Scheiben auf der Curlhantel immer mit Klammern sichern !!!') +; + +insert into athletik.musclegroup values +(default, 'Upper Arms', 'Oberarme'), +(default, 'Shoulder', 'Schultern'), +(default, 'Chest', 'Brust'), +(default, 'Back', 'Rücken'), +(default, 'Waist', 'Rumpf'), +(default, 'Hips', 'Hüfte'), +(default, 'Tights', 'Ober-/Unterschenkel'), +(default, 'Calves', 'Wade'), +(default, 'Neck', 'Hals'), +(default, 'other', 'Sonstiges') +; + +insert into athletik.muscle values +(default, 'Triceps Brachii', 'Trizeps', 'Triceps', '', 'Armstreckung', (select id from athletik.musclegroup where name_english='Upper Arms')), +(default, 'Biceps Brachii', 'Bizeps', 'Biceps', '', 'Armbeugung', (select id from athletik.musclegroup where name_english='Upper Arms')), +(default, 'Brachialis', '', '', '', 'Armbeugung', (select id from athletik.musclegroup where name_english='Upper Arms')), +(default, 'Anterior Deltoid', '', '', '', 'Deltamuskel vorne', (select id from athletik.musclegroup where name_english='Shoulder')), +(default, 'Posterior Deltoid', '', '', '', 'Deltamuskel hinten', (select id from athletik.musclegroup where name_english='Shoulder')), +(default, 'Lateral Deltoid', '', '', '', 'Deltamuskel seitlich', (select id from athletik.musclegroup where name_english='Shoulder')), +(default, 'Supraspinatus', '', '', '', '', (select id from athletik.musclegroup where name_english='Shoulder')), +(default, 'Pectoralis Major Sternal', '', '', '', 'Brustmuskel groß, Ansatz am Brustbein', (select id from athletik.musclegroup where name_english='Chest')), +(default, 'Pectoralis Major Clavicular', '', '', '', 'Brustmuskel groß, Ansatz am Schlüsselbein', (select id from athletik.musclegroup where name_english='Chest')), +(default, 'Pectoralis Minor', '', '', '', 'Brustmuskel klein', (select id from athletik.musclegroup where name_english='Chest')), +(default, 'Serratus Anterior', '', '', '', 'Sägemuskel', (select id from athletik.musclegroup where name_english='Chest')) +; + + + +insert into athletik.exercise values +(default, 'Dumbbell Lying Triceps Extension', '', '', '', 'https://exrx.net/WeightExercises/Triceps/DBLyingTriExt', (select id from athletik.tools where toolname_german='Kurzhantel')), +(default, 'Cable Pushdown', '', '', '', 'https://exrx.net/WeightExercises/Triceps/CBPushdown', (select id from athletik.tools where toolname_german='Seilzug')), +(default, 'Barbell Curl', '', '', '', 'https://exrx.net/WeightExercises/Biceps/BBCurl', (select id from athletik.tools where toolname_german='Curlhantel')), +(default, 'Dumbbell Curl', '', '', '', 'https://exrx.net/WeightExercises/Biceps/DBCurl', (select id from athletik.tools where toolname_german='Kurzhantel')), +(default, 'Cable Curl', '', '', '', 'https://exrx.net/WeightExercises/Biceps/CBCurl', (select id from athletik.tools where toolname_german='Seilzug')), +(default, 'Dumbbell Preacher Curl', '', '', '', 'https://exrx.net/WeightExercises/Brachialis/DBPreacherCurl', (select id from athletik.tools where toolname_german='Kurzhantel')), +(default, 'Dumbbell Shoulder Press', '', '', '', 'https://exrx.net/WeightExercises/DeltoidAnterior/DBShoulderPress', (select id from athletik.tools where toolname_german='Kurzhantel')), +(default, 'Cable Reverse Fly', '', '', '', 'https://exrx.net/WeightExercises/DeltoidPosterior/CBStandingReverseFly', (select id from athletik.tools where toolname_german='Langhantel')), +(default, 'Barbell Upright Row', '', '', '', 'https://exrx.net/WeightExercises/DeltoidLateral/BBUprightRow', (select id from athletik.tools where toolname_german='Langhantel')), +(default, 'Dumbbell Front Lateral Raise', '', '', '', 'https://exrx.net/WeightExercises/Supraspinatus/DBFrontLateralRaise', (select id from athletik.tools where toolname_german='Kurzhantel')), +(default, 'Dumbbell Bench Press', '', '', '', 'https://exrx.net/WeightExercises/PectoralSternal/DBBenchPress', (select id from athletik.tools where toolname_german='Kurzhantel')), +(default, 'Barbell Bench Press', '', '', '', 'https://exrx.net/WeightExercises/PectoralSternal/BBBenchPress', (select id from athletik.tools where toolname_german='Langhantel')), +(default, 'Dumbbell Incline Bench Press', '', '', '', 'https://exrx.net/WeightExercises/PectoralClavicular/DBInclineBenchPress', (select id from athletik.tools where toolname_german='Kurzhantel')), +(default, 'Barbell Incline Bench Press', '', '', '', 'https://exrx.net/WeightExercises/PectoralClavicular/BBInclineBenchPress', (select id from athletik.tools where toolname_german='Langhantel')), +(default, 'Cable Incline Fly', '', '', '', 'https://exrx.net/WeightExercises/PectoralClavicular/CBInclineFly', (select id from athletik.tools where toolname_german='Seilzug')), +(default, 'Cable Standing Fly', '', '', '', 'https://exrx.net/WeightExercises/PectoralSternal/CBStandingFly', (select id from athletik.tools where toolname_german='Seilzug')), +(default, 'Barbell Incline Shoulder Raise', '', '', '', 'https://exrx.net/WeightExercises/SerratusAnterior/BBInclineShoulderRaise', (select id from athletik.tools where toolname_german='Langhantel')), +(default, 'Dumbbell Incline Shoulder Raise', '', '', '', 'https://exrx.net/WeightExercises/SerratusAnterior/DBInclineShoulderRaise', (select id from athletik.tools where toolname_german='Kurzhantel')) +; + + +insert into athletik.exercise_muscle values +((select id from athletik.exercise where name_english='Dumbbell Lying Triceps Extension'), (select id from athletik.muscle where name_latin='Triceps Brachii')); +insert into athletik.exercise_muscle values +((select id from athletik.exercise where name_english='Cable Pushdown'), (select id from athletik.muscle where name_latin='Triceps Brachii')); +insert into athletik.exercise_muscle values +((select id from athletik.exercise where name_english='Barbell Curl'), (select id from athletik.muscle where name_latin='Biceps Brachii')); +insert into athletik.exercise_muscle values +((select id from athletik.exercise where name_english='Dumbbell Curl'), (select id from athletik.muscle where name_latin='Biceps Brachii')); +insert into athletik.exercise_muscle values +((select id from athletik.exercise where name_english='Cable Curl'), (select id from athletik.muscle where name_latin='Biceps Brachii')); +insert into athletik.exercise_muscle values +((select id from athletik.exercise where name_english='Dumbbell Preacher Curl'), (select id from athletik.muscle where name_latin='Brachialis')); +insert into athletik.exercise_muscle values +((select id from athletik.exercise where name_english='Dumbbell Shoulder Press'), (select id from athletik.muscle where name_latin='Anterior Deltoid')); +insert into athletik.exercise_muscle values +((select id from athletik.exercise where name_english='Cable Reverse Fly'), (select id from athletik.muscle where name_latin='Posterior Deltoid')); +insert into athletik.exercise_muscle values +((select id from athletik.exercise where name_english='Barbell Upright Row'), (select id from athletik.muscle where name_latin='Lateral Deltoid')); +insert into athletik.exercise_muscle values +((select id from athletik.exercise where name_english='Dumbbell Front Lateral Raise'), (select id from athletik.muscle where name_latin='Supraspinatus')); +insert into athletik.exercise_muscle values +((select id from athletik.exercise where name_english='Dumbbell Bench Press'), (select id from athletik.muscle where name_latin='Pectoralis Major Sternal')); +insert into athletik.exercise_muscle values +((select id from athletik.exercise where name_english='Barbell Bench Press'), (select id from athletik.muscle where name_latin='Pectoralis Major Sternal')); +insert into athletik.exercise_muscle values +((select id from athletik.exercise where name_english='Dumbbell Incline Bench Press'), (select id from athletik.muscle where name_latin='Pectoralis Major Clavicular')); +insert into athletik.exercise_muscle values +((select id from athletik.exercise where name_english='Barbell Incline Bench Press'), (select id from athletik.muscle where name_latin='Pectoralis Major Clavicular')); +insert into athletik.exercise_muscle values +((select id from athletik.exercise where name_english='Cable Incline Fly'), (select id from athletik.muscle where name_latin='Pectoralis Major Clavicular')); +insert into athletik.exercise_muscle values +((select id from athletik.exercise where name_english='Cable Standing Fly'), (select id from athletik.muscle where name_latin='Pectoralis Minor')); +insert into athletik.exercise_muscle values +((select id from athletik.exercise where name_english='Barbell Incline Shoulder Raise'), (select id from athletik.muscle where name_latin='Serratus Anterior')); +insert into athletik.exercise_muscle values +((select id from athletik.exercise where name_english='Dumbbell Incline Shoulder Raise'), (select id from athletik.muscle where name_latin='Serratus Anterior')); \ No newline at end of file diff --git a/athletik-db/sql/schema.sql b/athletik-db/sql/schema.sql index 9cffbf9..d6cc6c0 100644 --- a/athletik-db/sql/schema.sql +++ b/athletik-db/sql/schema.sql @@ -1,144 +1,380 @@ +DROP SCHEMA athletik CASCADE; + CREATE SCHEMA athletik; --- Athleten -CREATE TABLE athletik.users ( - id SERIAL not null, - username varchar not null, - name_user varchar not null, - email varchar not null, - pass varchar not null +ALTER SCHEMA athletik OWNER TO oleb; + +-- athletik.tool definition +-- Definition des Geräts, ab dem trainiert wird. + +CREATE TABLE athletik.tool ( + id serial4 NOT NULL, + toolname_english varchar NOT NULL, + toolname_german varchar NOT NULL, + min_weight numeric(5, 2) DEFAULT 0 NOT NULL, + steps_weight numeric(5, 2) DEFAULT 0 NOT NULL, + max_weight numeric(5, 2) DEFAULT 0 NOT NULL, + description varchar NULL, + CONSTRAINT tool_pkey PRIMARY KEY (id) ); -ALTER TABLE athletik.users ADD CONSTRAINT users_pkey PRIMARY KEY (id); -ALTER TABLE athletik.users ADD CONSTRAINT users_ukey UNIQUE (username); - --- Geräte -CREATE TABLE athletik.tools ( - id SERIAL not null, - toolname_english varchar not null, - toolname_german varchar not null, - min_weight int4 not null default 0, - steps_weight int4 not null default 0, - description varchar default null +-- Permissions + +ALTER TABLE athletik.tool OWNER TO oleb; +GRANT ALL ON TABLE athletik.tool TO oleb; + + +-- athletik.gym definition +-- Bezeichnung des Fitnessstudios + +CREATE TABLE athletik.gym ( + id serial4 NOT NULL, + gymname varchar NOT NULL, + gymlocation varchar DEFAULT NULL, + CONSTRAINT gym_pkey PRIMARY KEY (id) ); -ALTER TABLE athletik.tools ADD CONSTRAINT tools_pkey PRIMARY KEY (id); +-- Permissions --- Muskeln -CREATE TABLE athletik.muscle ( - id SERIAL not null, - name_latin varchar not null, - name_english varchar default null, - name_german varchar default null, - movement varchar not null +ALTER TABLE athletik.gym OWNER TO oleb; +GRANT ALL ON TABLE athletik.gym TO oleb; + + +-- athletik.goal definition +-- Bezeichnung des Trainingsziels + +CREATE TABLE athletik.goal ( + id serial4 NOT NULL, + goalname varchar NOT NULL, + description text DEFAULT NULL, + CONSTRAINT goal_pkey PRIMARY KEY (id) +); + +-- Permissions + +ALTER TABLE athletik.goal OWNER TO oleb; +GRANT ALL ON TABLE athletik.goal TO oleb; + + +-- athletik.gymtool definition +-- Kreuztabelle aus Fitnessstudio und Gerät, da jedes Fitnessstudio andere Geräte mit anderen Gewichtsabstufungen haben kann. + +CREATE TABLE athletik.gymtool ( + fk_tool int4 NOT NULL, + fk_gym int4 NOT NULL, + CONSTRAINT gymtool_ukey UNIQUE (fk_tool, fk_gym), + CONSTRAINT gymtool_tool_fkey FOREIGN KEY (fk_tool) REFERENCES athletik.tool(id) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT gymtool_gym_fkey FOREIGN KEY (fk_gym) REFERENCES athletik.gym(id) ON DELETE CASCADE ON UPDATE CASCADE +); + +-- Permissions + +ALTER TABLE athletik.gymtool OWNER TO oleb; +GRANT ALL ON TABLE athletik.gymtool TO oleb; + + + +-- athletik.athlet definition +-- Der Athlet + +CREATE TABLE athletik.athlet ( + id serial4 NOT NULL, + username varchar NOT NULL, + fullname varchar NOT NULL, + email varchar NOT NULL, + pass varchar NOT NULL, + CONSTRAINT athlet_pkey PRIMARY KEY (id), + CONSTRAINT athlet_ukey UNIQUE (username) +); + +-- Permissions + +ALTER TABLE athletik.athlet OWNER TO oleb; +GRANT ALL ON TABLE athletik.athlet TO oleb; + + +-- athletik.athletgym definition +-- Kreuztabelle aus Athlet und Fitnessstudio, da ein Athlet in mehreren Fitnessstudios trainieren könnte + +CREATE TABLE athletik.athletgym ( + fk_athlet int4 NOT NULL, + fk_gym int4 NOT NULL, + CONSTRAINT athletgym_ukey UNIQUE (fk_athlet, fk_gym), + CONSTRAINT athlet_athlet_fkey FOREIGN KEY (fk_athlet) REFERENCES athletik.athlet(id) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT athlet_gym_fkey FOREIGN KEY (fk_gym) REFERENCES athletik.gym(id) ON DELETE CASCADE ON UPDATE CASCADE ); -ALTER TABLE athletik.muscle ADD CONSTRAINT muscle_pkey PRIMARY KEY (id); +-- Permissions + +ALTER TABLE athletik.athletgym OWNER TO oleb; +GRANT ALL ON TABLE athletik.athletgym TO oleb; + + + +-- athletik.exercise definition +-- Die Übung bestehend aus Namen, Beschreibung einer Video-URL und einem Verweis, an welchem Gerät diese durchgeführt werden soll. --- Übungen CREATE TABLE athletik.exercise ( - id SERIAL not null, - name_english varchar not null, - description_english varchar default null, - name_german varchar default null, - description_german varchar default null, - url_video varchar default null, - - fk_tool int4 not null + id serial4 NOT NULL, + name_english varchar NOT NULL, + description_english varchar NULL, + name_german varchar NULL, + description_german varchar NULL, + url_video varchar NULL, + fk_tool int4 NOT NULL, + CONSTRAINT exercise_pkey PRIMARY KEY (id), + CONSTRAINT exercise_tool_fkey FOREIGN KEY (fk_tool) REFERENCES athletik.tool(id) ON DELETE CASCADE ON UPDATE CASCADE ); -ALTER TABLE athletik.exercise ADD CONSTRAINT exercise_pkey PRIMARY KEY (id); -ALTER TABLE athletik.exercise ADD CONSTRAINT exercise_tool_fkey FOREIGN KEY (fk_tool) REFERENCES athletik.tools(id) ON UPDATE CASCADE ON DELETE CASCADE; - --- Test -CREATE TABLE athletik.test ( - fk_user int4 not null, - fk_exercise int4 not null, - testdate timestamp not null default now(), - fmax decimal default 0 +-- Permissions + +ALTER TABLE athletik.exercise OWNER TO oleb; +GRANT ALL ON TABLE athletik.exercise TO oleb; + + +-- athletik.muscle definition +-- Name und Beschreibung der Muskeln + +CREATE TABLE athletik.muscle ( + id serial4 NOT NULL, + muscle_name_latin varchar NOT NULL, + muscle_name_english varchar NULL, + muscle_name_german varchar NULL, + movement_english varchar NOT NULL, + movement_german varchar NOT NULL, + musclegroup_name_english varchar NULL, + musclegroup_name_german varchar NULL, + CONSTRAINT muscle_pkey PRIMARY KEY (id) ); -ALTER TABLE athletik.test ADD CONSTRAINT test_ukey UNIQUE (fk_exercise, fk_user, testdate); +-- Permissions + +ALTER TABLE athletik.muscle OWNER TO oleb; +GRANT ALL ON TABLE athletik.muscle TO oleb; -ALTER TABLE athletik.test ADD CONSTRAINT test_exercise_fkey FOREIGN KEY (fk_exercise) REFERENCES athletik.exercise(id) ON UPDATE CASCADE ON DELETE CASCADE; -ALTER TABLE athletik.test ADD CONSTRAINT test_user_fkey FOREIGN KEY (fk_user) REFERENCES athletik.users(id) ON UPDATE CASCADE ON DELETE CASCADE; --- Protokoll +-- athletik.protokoll definition +-- In dieser Tabelle werden die Test- und Trainingsaktivitäten persistiert. Je nach Modus (Test oder Training) werden Spalten leergelassen. + CREATE TABLE athletik.protokoll ( - fk_user int4 not null, - fk_exercise int4 not null, - trainingdate timestamp not null default now(), - number_of_set int4 default 1, - repetitions int4 default 1, - weight int4 default 0 + fk_athlet int4 NOT NULL, + fk_exercise int4 NOT NULL, + trainingdate timestamp DEFAULT now() NOT NULL, + number_of_set int4 DEFAULT 1, + repetitions int4 DEFAULT 1, + weight numeric(5, 2) DEFAULT 0, + is_test boolean DEFAULT FALSE, + CONSTRAINT protokoll_ukey UNIQUE (fk_exercise, fk_athlet, trainingdate, number_of_set), + CONSTRAINT protokoll_exercise_fkey FOREIGN KEY (fk_exercise) REFERENCES athletik.exercise(id) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT protokoll_athlet_fkey FOREIGN KEY (fk_athlet) REFERENCES athletik.athlet(id) ON DELETE CASCADE ON UPDATE CASCADE ); -ALTER TABLE athletik.protokoll ADD CONSTRAINT protokoll_ukey UNIQUE (fk_exercise, fk_user, trainingdate, number_of_set); +-- Permissions -ALTER TABLE athletik.protokoll ADD CONSTRAINT protokoll_exercise_fkey FOREIGN KEY (fk_exercise) REFERENCES athletik.exercise(id) ON UPDATE CASCADE ON DELETE CASCADE; -ALTER TABLE athletik.protokoll ADD CONSTRAINT protokoll_user_fkey FOREIGN KEY (fk_user) REFERENCES athletik.users(id) ON UPDATE CASCADE ON DELETE CASCADE; +ALTER TABLE athletik.protokoll OWNER TO oleb; +GRANT ALL ON TABLE athletik.protokoll TO oleb; + + +-- athletik.log definition +-- In der Logtabelle werden die Aktivitäten der Software gespeichert + +CREATE TABLE athletik.log ( + id serial4 NOT NULL, + created timestamp DEFAULT now() NOT NULL, + logdata text NOT NULL, + fk_athlet int4 NOT NULL, + sid text NOT NULL, + script varchar NOT NULL, + CONSTRAINT sqllog_pkey PRIMARY KEY (id), + CONSTRAINT sqllog_athlet_fkey FOREIGN KEY (fk_athlet) REFERENCES athletik.athlet(id) ON DELETE CASCADE ON UPDATE CASCADE +); + +-- Permissions + +ALTER TABLE athletik.log OWNER TO oleb; +GRANT ALL ON TABLE athletik.log TO oleb; + + +-- athletik.training definition +-- Diese Tabelle verknüpft den Athleten, die Übungen und das Trainingsziel, die er durchführen kann und stellt damit ein Trainingsprogramm dar. +-- Dabei werden Gewicht, Sätze und Wiederholungen ergänzt. +-- Die Zeitstempel versionieren das Ganze. --- Trainingspläne CREATE TABLE athletik.training ( - id SERIAL not null, - title varchar not null, - description text default null, - fk_user int4 not null, - fk_exercise int4 not null, - repetitions_of_set int4 default 1, - repetitions int4 default 1, - factor_of_fmax int4 default 0, - created timestamp not null default now(), - valid_since timestamp not null default now() + id serial4 NOT NULL, + title varchar NOT NULL, + fk_goal int4 NOT NULL, -- Zweck des Trainings. Kraftausdauer, Schnellkraft, ... + description text NULL, + fk_athlet int4 NOT NULL, + fk_exercise int4 NOT NULL, + repetitions_of_set int4 DEFAULT 1 NULL, + repetitions int4 DEFAULT 1 NULL, + factor_of_fmax numeric(5, 2) DEFAULT 0 NULL, + created timestamp DEFAULT now() NOT NULL, + valid_since timestamp DEFAULT now() NOT NULL, + CONSTRAINT training_ukey UNIQUE (fk_exercise, fk_athlet, repetitions_of_set, repetitions, factor_of_fmax), + CONSTRAINT training_goal_fkey FOREIGN KEY (fk_goal) REFERENCES athletik.goal(id) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT training_exercise_fkey FOREIGN KEY (fk_exercise) REFERENCES athletik.exercise(id) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT training_athlet_fkey FOREIGN KEY (fk_athlet) REFERENCES athletik.athlet(id) ON DELETE CASCADE ON UPDATE CASCADE ); -ALTER TABLE athletik.training ADD CONSTRAINT training_ukey UNIQUE (fk_exercise, fk_user, repetitions_of_set, repetitions, factor_of_fmax); +-- Permissions + +ALTER TABLE athletik.training OWNER TO oleb; +GRANT ALL ON TABLE athletik.training TO oleb; + -ALTER TABLE athletik.training ADD CONSTRAINT training_exercise_fkey FOREIGN KEY (fk_exercise) REFERENCES athletik.exercise(id) ON UPDATE CASCADE ON DELETE CASCADE; -ALTER TABLE athletik.training ADD CONSTRAINT training_user_fkey FOREIGN KEY (fk_user) REFERENCES athletik.users(id) ON UPDATE CASCADE ON DELETE CASCADE; +-- athletik.exercise_muscle definition +-- Eine Kreuztabelle, die Übungen und Muskeln zusammenführt. +-- Eine Übung ist meistens für mehrere Muskeln geeinet, aber für wenige primär. --- Log -CREATE TABLE athletik.sqllog ( - id SERIAL not null, - created timestamp not null default now(), - sql text not null, - fk_user int4 not null, - sid text not null, - script varchar not null +CREATE TABLE athletik.exercise_muscle ( + fk_exercise int4 NOT NULL, + fk_muscle int4 NOT NULL, + isprimary boolean DEFAULT false, + CONSTRAINT exercise_muscle_ukey UNIQUE (fk_exercise, fk_muscle), + CONSTRAINT exercise_muscle_exercise_fkey FOREIGN KEY (fk_exercise) REFERENCES athletik.exercise(id) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT exercise_muscle_muscle_fkey FOREIGN KEY (fk_muscle) REFERENCES athletik.muscle(id) ON DELETE CASCADE ON UPDATE CASCADE ); -ALTER TABLE athletik.sqllog ADD CONSTRAINT sqllog_pkey PRIMARY KEY (id); - -ALTER TABLE athletik.sqllog ADD CONSTRAINT sqllog_user_fkey FOREIGN KEY (fk_user) REFERENCES athletik.users(id) ON UPDATE CASCADE ON DELETE CASCADE; +-- Permissions +ALTER TABLE athletik.exercise_muscle OWNER TO oleb; +GRANT ALL ON TABLE athletik.exercise_muscle TO oleb; +-- athletik.view_allexercises source --- ALTER SCHEMA athletik OWNER TO laktatnebel; +CREATE OR REPLACE VIEW athletik.view_allexercises +AS SELECT e.id AS id_exercise, + e.name_english, + e.description_english, + e.name_german, + e.description_german, + e.url_video, + t.id AS id_tool, + t.toolname_english, + t.toolname_german, + t.min_weight, + t.max_weight, + t.steps_weight, + t.description, + em.isprimary, + m.id, + m.muscle_name_latin, + m.muscle_name_english, + m.muscle_name_german, + m.movement_english, + m.movement_german, + m.musclegroup_name_english, + m.musclegroup_name_german + FROM athletik.exercise_muscle em + JOIN athletik.muscle m ON m.id = em.fk_muscle + JOIN athletik.exercise e ON e.id = em.fk_exercise + JOIN athletik.tool t ON t.id = e.fk_tool; --- ALTER TABLE athletik.users OWNER TO laktatnebel; --- ALTER TABLE athletik.tools OWNER TO laktatnebel; --- ALTER TABLE athletik.muscle OWNER TO laktatnebel; --- ALTER TABLE athletik.exercise OWNER TO laktatnebel; --- ALTER TABLE athletik.test OWNER TO laktatnebel; --- ALTER TABLE athletik.protokoll OWNER TO laktatnebel; --- ALTER TABLE athletik.training OWNER TO laktatnebel; --- ALTER TABLE athletik.sqllog OWNER TO laktatnebel; +-- Permissions --- GRANT ALL ON SCHEMA athletik TO laktatnebel; +ALTER TABLE athletik.view_allexercises OWNER TO oleb; +GRANT ALL ON TABLE athletik.view_allexercises TO oleb; -ALTER SCHEMA athletik OWNER TO oleb; +-- athletik.view_musclegroups source -ALTER TABLE athletik.users OWNER TO oleb; -ALTER TABLE athletik.tools OWNER TO oleb; -ALTER TABLE athletik.muscle OWNER TO oleb; -ALTER TABLE athletik.exercise OWNER TO oleb; -ALTER TABLE athletik.test OWNER TO oleb; -ALTER TABLE athletik.protokoll OWNER TO oleb; -ALTER TABLE athletik.training OWNER TO oleb; -ALTER TABLE athletik.sqllog OWNER TO oleb; +CREATE OR REPLACE VIEW athletik.view_musclegroups +AS SELECT DISTINCT + m.musclegroup_name_english, + m.musclegroup_name_german + FROM athletik.muscle m; + +-- Permissions + +ALTER TABLE athletik.view_musclegroups OWNER TO oleb; +GRANT ALL ON TABLE athletik.view_musclegroups TO oleb; + + +-- athletik.view_muscles source + +CREATE OR REPLACE VIEW athletik.view_muscles +AS SELECT m.id, + m.muscle_name_latin, + m.muscle_name_english, + m.muscle_name_german, + m.movement_english, + m.movement_german, + m.musclegroup_name_english, + m.musclegroup_name_german + FROM athletik.muscle m; + +-- Permissions + +ALTER TABLE athletik.view_muscles OWNER TO oleb; +GRANT ALL ON TABLE athletik.view_muscles TO oleb; + + +-- athletik.view_protokollsetsoftoday source + +CREATE OR REPLACE VIEW athletik.view_protokollsetsoftoday +AS SELECT fk_athlet, + fk_exercise, + trainingdate, + number_of_set + FROM athletik.protokoll p; + +-- Permissions + +ALTER TABLE athletik.view_protokollsetsoftoday OWNER TO oleb; +GRANT ALL ON TABLE athletik.view_protokollsetsoftoday TO oleb; + + +-- athletik.view_tool source + +CREATE OR REPLACE VIEW athletik.view_tool +AS SELECT id, + toolname_english, + toolname_german, + min_weight, + steps_weight, + max_weight, + description + FROM athletik.tool t; + +-- Permissions + +ALTER TABLE athletik.view_tool OWNER TO oleb; +GRANT ALL ON TABLE athletik.view_tool TO oleb; + + +-- athletik.view_toolweights source + +CREATE OR REPLACE VIEW athletik.view_toolweights +AS SELECT id, + min_weight, + steps_weight, + max_weight + FROM athletik.tool t; + +-- Permissions + +ALTER TABLE athletik.view_toolweights OWNER TO oleb; +GRANT ALL ON TABLE athletik.view_toolweights TO oleb; + + +-- athletik.view_athlet source + +CREATE OR REPLACE VIEW athletik.view_athlet +AS SELECT id, + username, + fullname, + email, + pass + FROM athletik.athlet u; + +-- Permissions + +ALTER TABLE athletik.view_athlet OWNER TO oleb; +GRANT ALL ON TABLE athletik.view_athlet TO oleb; GRANT ALL ON SCHEMA athletik TO oleb; diff --git a/athletik-service/pom.xml b/athletik-service/pom.xml new file mode 100644 index 0000000..60cdd77 --- /dev/null +++ b/athletik-service/pom.xml @@ -0,0 +1,365 @@ + + 4.0.0 + athletik.service + + ${project.artifactId} + Athletik Training Sevice + + + com.triathlon-coaching.product + athletik + 0.0.1-SNAPSHOT + + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + + org.postgresql + postgresql + ${postgresql.version} + + + + + javax.servlet + javax.servlet-api + ${javax.servlet-api.version} + provided + + + org.hibernate + hibernate-core + ${hibernate-core.version} + + + + + javax.mail + javax.mail-api + ${javax.mail.version} + + + com.sun.mail + javax.mail + ${javax.mail.version} + + + + + org.springframework + spring-webmvc + ${springframework.version} + + + org.springframework + spring-orm + ${springframework.version} + + + + + org.springframework.boot + spring-boot-starter-data-jpa + ${spring-boot.version} + + + + + org.projectlombok + lombok + ${lombok.version} + provided + + + + + org.springframework.boot + spring-boot-starter-validation + ${spring-boot.version} + + + + + org.springframework.boot + spring-boot-starter-security + ${spring-boot.version} + + + + + org.springframework.boot + spring-boot-starter-mail + ${spring-boot.version} + + + + + + org.thymeleaf + thymeleaf-spring5 + ${thymeleaf.version} + + + + de.laktatnebel.libs + utillib + ${utillib.version} + + + + + + + + + + org.postgresql + postgresql + + + + + org.hibernate + hibernate-core + + + + + javax.servlet + javax.servlet-api + provided + + + + + javax.mail + javax.mail-api + + + com.sun.mail + javax.mail + + + + + org.springframework + spring-webmvc + + + org.springframework + spring-orm + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + + org.projectlombok + lombok + + + + + org.springframework.boot + spring-boot-starter-validation + + + + + org.springframework.boot + spring-boot-starter-security + + + + + org.springframework.boot + spring-boot-starter-mail + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.thymeleaf + thymeleaf-spring5 + + + + de.laktatnebel.libs + utillib + + + + + + ${project.artifactId} + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${java.version} + ${java.version} + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven-javadoc-plugin.version} + + + org.apache.maven.plugins + maven-enforcer-plugin + ${maven-enforcer-plugin.version} + + + org.apache.maven.plugins + maven-source-plugin + ${maven-source-plugin.version} + + + org.apache.maven.plugins + maven-deploy-plugin + ${maven-deploy-plugin.version} + + + org.apache.maven.plugins + maven-release-plugin + ${maven-release-plugin.version} + + develop + false + true + + + + org.apache.maven.plugins + maven-site-plugin + ${maven-site-plugin.version} + + + + site + + + + + + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + ${javadoc.opts} + none + + + + attach-javadocs + + jar + + + ${javadoc.opts} + none + + + + + + org.apache.maven.plugins + maven-site-plugin + + + maven-compiler-plugin + + ${java.version} + + + + maven-enforcer-plugin + + + enforce-versions + + enforce + + + + + + + + [3.0,) + + + ${java.version} + + + + + + org.apache.tomcat.maven + tomcat7-maven-plugin + 2.0 + + localtomcat + http://localhost:8080/manager/text + + true + + + + org.springframework.boot + spring-boot-maven-plugin + + + ${project.groupId}.${project.artifactId}.AthletikBackendApplication + + + + + + + diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/AthletikBackendApplication.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/AthletikBackendApplication.java new file mode 100644 index 0000000..fe65611 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/AthletikBackendApplication.java @@ -0,0 +1,17 @@ +package com.triathlon_coaching.product.athletik.backend; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + +@SpringBootApplication +@EntityScan("com.triathlon_coaching.product.athletik.models") +@EnableJpaRepositories("com.triathlon_coaching.product.athletik.backend.repositories") +@ComponentScan({"com.triathlon_coaching.product.athletik.backend", "com.triathlon_coaching.product.athletik.services"}) +public class AthletikBackendApplication { + public static void main(String[] args) { + SpringApplication.run(AthletikBackendApplication.class, args); + } +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/config/SecurityConfig.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/config/SecurityConfig.java new file mode 100644 index 0000000..1da2d94 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/config/SecurityConfig.java @@ -0,0 +1,74 @@ +package com.triathlon_coaching.product.athletik.backend.config; + +import com.triathlon_coaching.product.athletik.backend.service.AthletService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; + +import javax.sql.DataSource; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +@Configuration +@EnableWebSecurity +public class SecurityConfig extends WebSecurityConfigurerAdapter { + + @Autowired + private DataSource dataSource; + + @Autowired + private AthletService athletService; + + @Bean + public PasswordEncoder passwordEncoder() { + return new PasswordEncoder() { + @Override + public String encode(CharSequence rawPassword) { + try { + MessageDigest digest = MessageDigest.getInstance("SHA-512"); + byte[] hash = digest.digest(rawPassword.toString().getBytes()); + StringBuilder hexString = new StringBuilder(); + for (byte b : hash) { + String hex = Integer.toHexString(0xff & b); + if (hex.length() == 1) + hexString.append('0'); + hexString.append(hex); + } + return hexString.toString(); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("SHA-512 Algorithmus nicht verfügbar", e); + } + } + + @Override + public boolean matches(CharSequence rawPassword, String encodedPassword) { + return encode(rawPassword).equals(encodedPassword); + } + }; + } + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + auth.jdbcAuthentication().dataSource(dataSource) + .usersByUsernameQuery("SELECT username, pass, true FROM athletik.athlet WHERE username = ?") + .authoritiesByUsernameQuery("SELECT username, 'USER' FROM athletik.athlet WHERE username = ?") + .passwordEncoder(passwordEncoder()); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.authorizeRequests().antMatchers("/", "/home", "/api/auth/register", "/css/**", "/js/**", "/img/**") + .permitAll().anyRequest().authenticated().and().formLogin().loginPage("/login") + .defaultSuccessUrl("/training", true).permitAll().and().logout() + .logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/login?logout") + .permitAll().and().csrf().ignoringAntMatchers("/api/**") // CSRF für API-Endpunkte deaktivieren + .and().sessionManagement().sessionFixation().migrateSession(); + } +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/AthletController.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/AthletController.java new file mode 100644 index 0000000..982e907 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/AthletController.java @@ -0,0 +1,144 @@ +package com.triathlon_coaching.product.athletik.backend.contoller; + +import com.triathlon_coaching.product.athletik.backend.model.Athlet; +import com.triathlon_coaching.product.athletik.backend.service.AthletService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpSession; +import javax.validation.Valid; +import java.util.List; +import java.util.Optional; + +@RestController +@RequestMapping("/api/athleten") +public class AthletController { + + @Autowired + private AthletService athletService; + + @GetMapping + public ResponseEntity> getAllAthleten() { + List athleten = athletService.findAllAthleten(); + return ResponseEntity.ok(athleten); + } + + @GetMapping("/{id}") + public ResponseEntity getAthletById(@PathVariable Long id) { + Optional athlet = athletService.findAthletById(id); + return athlet.map(ResponseEntity::ok) + .orElse(ResponseEntity.notFound().build()); + } + + @GetMapping("/username/{username}") + public ResponseEntity getAthletByUsername(@PathVariable String username) { + Optional athlet = athletService.findAthletByUsername(username); + return athlet.map(ResponseEntity::ok) + .orElse(ResponseEntity.notFound().build()); + } + + @GetMapping("/email/{email}") + public ResponseEntity getAthletByEmail(@PathVariable String email) { + Optional athlet = athletService.findAthletByEmail(email); + return athlet.map(ResponseEntity::ok) + .orElse(ResponseEntity.notFound().build()); + } + + @GetMapping("/gym/{gymId}") + public ResponseEntity> getAthletenByGymId(@PathVariable Long gymId) { + List athleten = athletService.findAthletenByGymId(gymId); + return ResponseEntity.ok(athleten); + } + + @PostMapping + public ResponseEntity createAthlet(@Valid @RequestBody Athlet athlet) { + if (athletService.existsByUsername(athlet.getUsername())) { + return ResponseEntity.badRequest().body("Username already exists"); + } + if (athletService.existsByEmail(athlet.getEmail())) { + return ResponseEntity.badRequest().body("Email already exists"); + } + + Athlet savedAthlet = athletService.saveAthlet(athlet); + return ResponseEntity.ok(savedAthlet); + } + + @PutMapping("/{id}") + public ResponseEntity updateAthlet(@PathVariable Long id, @Valid @RequestBody Athlet athletDetails) { + Optional athletOptional = athletService.findAthletById(id); + if (!athletOptional.isPresent()) { + return ResponseEntity.notFound().build(); + } + + Athlet athlet = athletOptional.get(); + athlet.setFullname(athletDetails.getFullname()); + athlet.setEmail(athletDetails.getEmail()); + // Passwort sollte separat geupdated werden + + Athlet updatedAthlet = athletService.saveAthlet(athlet); + return ResponseEntity.ok(updatedAthlet); + } + + @PutMapping("/{id}/password") + public ResponseEntity updatePassword(@PathVariable Long id, + @RequestParam String currentPassword, + @RequestParam String newPassword) { + Optional athletOptional = athletService.findAthletById(id); + if (!athletOptional.isPresent()) { + return ResponseEntity.notFound().build(); + } + + boolean success = athletService.updatePassword(id, currentPassword, newPassword); + if (success) { + return ResponseEntity.ok().build(); + } else { + return ResponseEntity.badRequest().body("Current password is incorrect"); + } + } + + @DeleteMapping("/{id}") + public ResponseEntity deleteAthlet(@PathVariable Long id) { + if (!athletService.findAthletById(id).isPresent()) { + return ResponseEntity.notFound().build(); + } + athletService.deleteAthlet(id); + return ResponseEntity.noContent().build(); + } + + @PostMapping("/{id}/deactivate") + public ResponseEntity deactivateAthlet(@PathVariable Long id) { + athletService.deactivateAthlet(id); + return ResponseEntity.ok().build(); + } + + @PostMapping("/{id}/activate") + public ResponseEntity activateAthlet(@PathVariable Long id) { + athletService.activateAthlet(id); + return ResponseEntity.ok().build(); + } + + @GetMapping("/profile") + public ResponseEntity getProfile(HttpSession session) { + Athlet athlet = (Athlet) session.getAttribute("athlet"); + if (athlet == null) { + return ResponseEntity.status(401).build(); + } + return ResponseEntity.ok(athlet); + } + + @PutMapping("/profile") + public ResponseEntity updateProfile(@Valid @RequestBody Athlet athletDetails, HttpSession session) { + Athlet currentAthlet = (Athlet) session.getAttribute("athlet"); + if (currentAthlet == null) { + return ResponseEntity.status(401).build(); + } + + currentAthlet.setFullname(athletDetails.getFullname()); + currentAthlet.setEmail(athletDetails.getEmail()); + + Athlet updatedAthlet = athletService.saveAthlet(currentAthlet); + session.setAttribute("athlet", updatedAthlet); + return ResponseEntity.ok(updatedAthlet); + } +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/AuthController.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/AuthController.java new file mode 100644 index 0000000..f1c8bbe --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/AuthController.java @@ -0,0 +1,45 @@ +package com.triathlon_coaching.product.athletik.backend.contoller; + +import com.triathlon_coaching.product.athletik.backend.model.Athlet; +import com.triathlon_coaching.product.athletik.backend.service.AthletService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpSession; +import java.util.Optional; + +@RestController +@RequestMapping("/api/auth") +public class AuthController { + + @Autowired + private AthletService athletService; + + @PostMapping("/login") + public ResponseEntity login(@RequestParam String username, + @RequestParam String password, + HttpSession session) { + Optional athlet = athletService.authenticate(username, password); + if (athlet.isPresent()) { + session.setAttribute("athlet", athlet.get()); + return ResponseEntity.ok(athlet.get()); + } + return ResponseEntity.status(401).body("Ungültige Anmeldedaten"); + } + + @PostMapping("/register") + public ResponseEntity register(@RequestBody Athlet athlet) { + Optional newAthlet = athletService.registerAthlet(athlet); + if (newAthlet.isPresent()) { + return ResponseEntity.ok(newAthlet.get()); + } + return ResponseEntity.badRequest().body("Benutzername oder E-Mail bereits vergeben"); + } + + @PostMapping("/logout") + public ResponseEntity logout(HttpSession session) { + session.invalidate(); + return ResponseEntity.ok("Abgemeldet"); + } +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/ExerciseController.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/ExerciseController.java new file mode 100644 index 0000000..f00dbc7 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/ExerciseController.java @@ -0,0 +1,74 @@ +package com.triathlon_coaching.product.athletik.backend.contoller; + +import com.triathlon_coaching.product.athletik.backend.model.Exercise; +import com.triathlon_coaching.product.athletik.backend.model.Muscle; +import com.triathlon_coaching.product.athletik.backend.service.ExerciseService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/api/exercises") +public class ExerciseController { + + @Autowired + private ExerciseService exerciseService; + + @GetMapping + public ResponseEntity> getAllExercises() { + List exercises = exerciseService.findAllExercises(); + return ResponseEntity.ok(exercises); + } + + @GetMapping("/{id}") + public ResponseEntity getExerciseById(@PathVariable Long id) { + return exerciseService.findExerciseById(id) + .map(ResponseEntity::ok) + .orElse(ResponseEntity.notFound().build()); + } + + @GetMapping("/musclegroup/{muscleGroup}") + public ResponseEntity> getExercisesByMuscleGroup(@PathVariable String muscleGroup) { + List exercises = exerciseService.findExercisesByMuscleGroup(muscleGroup); + return ResponseEntity.ok(exercises); + } + + @GetMapping("/muscle/{muscleId}") + public ResponseEntity> getExercisesByMuscleId(@PathVariable Long muscleId) { + List exercises = exerciseService.findExercisesByMuscleId(muscleId); + return ResponseEntity.ok(exercises); + } + + @GetMapping("/musclegroups") + public ResponseEntity> getAllMuscleGroups() { + List muscleGroups = exerciseService.findAllMuscleGroups(); + return ResponseEntity.ok(muscleGroups); + } + + @GetMapping("/muscles") + public ResponseEntity> getAllMuscles() { + List muscles = exerciseService.findAllMuscles(); + return ResponseEntity.ok(muscles); + } + + @GetMapping("/muscles/group/{muscleGroup}") + public ResponseEntity> getMusclesByGroup(@PathVariable String muscleGroup) { + List muscles = exerciseService.findMusclesByGroup(muscleGroup); + return ResponseEntity.ok(muscles); + } + + @GetMapping("/tools/weights/{toolId}") + public ResponseEntity> getWeightsForTool(@PathVariable Long toolId) { + List weights = exerciseService.getWeightsForTool(toolId); + return ResponseEntity.ok(weights); + } + + @GetMapping("/summary") + public ResponseEntity> getExerciseSummary() { + Map summary = exerciseService.getExerciseSummary(); + return ResponseEntity.ok(summary); + } +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/GoalController.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/GoalController.java new file mode 100644 index 0000000..4660628 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/GoalController.java @@ -0,0 +1,96 @@ +package com.triathlon_coaching.product.athletik.backend.contoller; + +import com.triathlon_coaching.product.athletik.backend.model.Goal; +import com.triathlon_coaching.product.athletik.backend.service.GoalService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; +import java.util.Optional; + +@RestController +@RequestMapping("/api/goals") +public class GoalController { + + @Autowired + private GoalService goalService; + + @GetMapping + public ResponseEntity> getAllGoals() { + List goals = goalService.findAllGoals(); + return ResponseEntity.ok(goals); + } + + @GetMapping("/{id}") + public ResponseEntity getGoalById(@PathVariable Long id) { + Optional goal = goalService.findGoalById(id); + return goal.map(ResponseEntity::ok) + .orElse(ResponseEntity.notFound().build()); + } + + @GetMapping("/name/{goalname}") + public ResponseEntity getGoalByName(@PathVariable String goalname) { + Optional goal = goalService.findGoalByName(goalname); + return goal.map(ResponseEntity::ok) + .orElse(ResponseEntity.notFound().build()); + } + + @GetMapping("/athlet/{athletId}") + public ResponseEntity> getGoalsByAthletId(@PathVariable Long athletId) { + List goals = goalService.findGoalsByAthletId(athletId); + return ResponseEntity.ok(goals); + } + + @GetMapping("/exercise/{exerciseId}") + public ResponseEntity> getGoalsByExerciseId(@PathVariable Long exerciseId) { + List goals = goalService.findGoalsByExerciseId(exerciseId); + return ResponseEntity.ok(goals); + } + + @GetMapping("/available/athlet/{athletId}") + public ResponseEntity> getAvailableGoalsForAthlet(@PathVariable Long athletId) { + List goals = goalService.findAvailableGoalsForAthlet(athletId); + return ResponseEntity.ok(goals); + } + + @GetMapping("/search") + public ResponseEntity> searchGoals(@RequestParam String q) { + List goals = goalService.searchGoals(q); + return ResponseEntity.ok(goals); + } + + @PostMapping + public ResponseEntity createGoal(@Valid @RequestBody Goal goal) { + if (goalService.existsByName(goal.getGoalname())) { + return ResponseEntity.badRequest().build(); + } + Goal savedGoal = goalService.saveGoal(goal); + return ResponseEntity.ok(savedGoal); + } + + @PutMapping("/{id}") + public ResponseEntity updateGoal(@PathVariable Long id, @Valid @RequestBody Goal goalDetails) { + Optional goalOptional = goalService.findGoalById(id); + if (!goalOptional.isPresent()) { + return ResponseEntity.notFound().build(); + } + + Goal goal = goalOptional.get(); + goal.setGoalname(goalDetails.getGoalname()); + goal.setDescription(goalDetails.getDescription()); + + Goal updatedGoal = goalService.saveGoal(goal); + return ResponseEntity.ok(updatedGoal); + } + + @DeleteMapping("/{id}") + public ResponseEntity deleteGoal(@PathVariable Long id) { + if (!goalService.findGoalById(id).isPresent()) { + return ResponseEntity.notFound().build(); + } + goalService.deleteGoal(id); + return ResponseEntity.noContent().build(); + } +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/GymController.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/GymController.java new file mode 100644 index 0000000..c6644a3 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/GymController.java @@ -0,0 +1,57 @@ +package com.triathlon_coaching.product.athletik.backend.contoller; + +import java.util.List; +import javax.servlet.http.HttpSession; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.triathlon_coaching.product.athletik.backend.model.Gym; +import com.triathlon_coaching.product.athletik.backend.service.GymService; + +@RestController +@RequestMapping("/api/gyms") +public class GymController { + + @Autowired + private GymService gymService; + + @GetMapping + public ResponseEntity> getAllGyms() { + List gyms = gymService.findAllGyms(); + return ResponseEntity.ok(gyms); + } + + @GetMapping("/{id}") + public ResponseEntity getGymById(@PathVariable Long id) { + return gymService.findGymById(id) + .map(ResponseEntity::ok) + .orElse(ResponseEntity.notFound().build()); + } + + @GetMapping("/athlet/{athletId}") + public ResponseEntity> getGymsByAthletId(@PathVariable Long athletId) { + List gyms = gymService.findGymsByAthletId(athletId); + return ResponseEntity.ok(gyms); + } + + @PostMapping("/{gymId}/select") + public ResponseEntity selectGym(@PathVariable Long gymId, HttpSession session) { + // Setzt das ausgewählte Gym in der Session + gymService.findGymById(gymId).ifPresent(gym -> { + session.setAttribute("selectedGym", gym); + }); + return ResponseEntity.ok().build(); + } + + @GetMapping("/selected") + public ResponseEntity getSelectedGym(HttpSession session) { + Gym selectedGym = (Gym) session.getAttribute("selectedGym"); + return ResponseEntity.ok(selectedGym); + } +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/LogController.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/LogController.java new file mode 100644 index 0000000..eda57b1 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/LogController.java @@ -0,0 +1,145 @@ +package com.triathlon_coaching.product.athletik.backend.contoller; + +import com.triathlon_coaching.product.athletik.backend.model.Log; +import com.triathlon_coaching.product.athletik.backend.service.LogService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpSession; +import java.time.LocalDateTime; +import java.util.List; + +@RestController +@RequestMapping("/api/logs") +public class LogController { + + @Autowired + private LogService logService; + + @GetMapping + public ResponseEntity> getAllLogs(HttpSession session) { + // Nur Admin-Zugriff erlauben + // Hier vereinfacht - in Produktion sollte eine richtige Autorisierung implementiert werden + return ResponseEntity.ok(logService.findAllLogs()); + } + + @GetMapping("/my-logs") + public ResponseEntity> getMyLogs(HttpSession session) { + Long athletId = getAthletIdFromSession(session); + if (athletId == null) { + return ResponseEntity.status(401).build(); + } + + List logs = logService.findByAthletId(athletId); + return ResponseEntity.ok(logs); + } + + @GetMapping("/my-logs/paged") + public ResponseEntity> getMyLogsPaged( + HttpSession session, + @RequestParam(defaultValue = "0") int page, + @RequestParam(defaultValue = "20") int size) { + + Long athletId = getAthletIdFromSession(session); + if (athletId == null) { + return ResponseEntity.status(401).build(); + } + + Pageable pageable = PageRequest.of(page, size, Sort.by("created").descending()); + Page logs = logService.findByAthletId(athletId, pageable); + return ResponseEntity.ok(logs); + } + + @GetMapping("/search") + public ResponseEntity> searchLogs( + HttpSession session, + @RequestParam(required = false) String level, + @RequestParam(required = false) String searchTerm, + @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startDate, + @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endDate) { + + Long athletId = getAthletIdFromSession(session); + if (athletId == null) { + return ResponseEntity.status(401).build(); + } + + List logs; + if (level != null) { + logs = logService.findByAthletIdAndLogLevel(athletId, level); + } else if (searchTerm != null) { + logs = logService.searchByAthletIdAndLogdata(athletId, searchTerm); + } else if (startDate != null && endDate != null) { + logs = logService.findByAthletIdAndDateRange(athletId, startDate, endDate); + } else { + logs = logService.findByAthletId(athletId); + } + + return ResponseEntity.ok(logs); + } + + @GetMapping("/stats") + public ResponseEntity getLogStats(HttpSession session) { + Long athletId = getAthletIdFromSession(session); + if (athletId == null) { + return ResponseEntity.status(401).build(); + } + + LocalDateTime last24Hours = LocalDateTime.now().minusHours(24); + Long countLast24Hours = logService.getLogCountSince(athletId, last24Hours); + + List scripts = logService.getDistinctScripts(athletId); + List levels = logService.getDistinctLogLevels(athletId); + Log latestLog = logService.getLatestLog(athletId); + + return ResponseEntity.ok(new LogStats(countLast24Hours, scripts, levels, latestLog)); + } + + @DeleteMapping("/{id}") + public ResponseEntity deleteLog(@PathVariable Long id, HttpSession session) { + // Prüfen, ob der Benutzer berechtigt ist, diesen Log zu löschen + Long athletId = getAthletIdFromSession(session); + if (athletId == null) { + return ResponseEntity.status(401).build(); + } + + // Hier sollte zusätzlich geprüft werden, ob der Log zum Benutzer gehört + logService.deleteLog(id); + return ResponseEntity.noContent().build(); + } + + // Hilfsmethode zur Extraktion der Athlet-ID aus der Session + private Long getAthletIdFromSession(HttpSession session) { + Object athletObj = session.getAttribute("athlet"); + if (athletObj instanceof com.triathlon_coaching.product.athletik.backend.model.Athlet) { + return ((com.triathlon_coaching.product.athletik.backend.model.Athlet) athletObj).getId(); + } + return null; + } + + // DTO für Log-Statistiken + private static class LogStats { + private Long countLast24Hours; + private List scripts; + private List levels; + private Log latestLog; + + public LogStats(Long countLast24Hours, List scripts, List levels, Log latestLog) { + this.countLast24Hours = countLast24Hours; + this.scripts = scripts; + this.levels = levels; + this.latestLog = latestLog; + } + + // Getter + public Long getCountLast24Hours() { return countLast24Hours; } + public List getScripts() { return scripts; } + public List getLevels() { return levels; } + public Log getLatestLog() { return latestLog; } + } +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/MuscleController.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/MuscleController.java new file mode 100644 index 0000000..1b97002 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/MuscleController.java @@ -0,0 +1,54 @@ +package com.triathlon_coaching.product.athletik.backend.contoller; + +import com.triathlon_coaching.product.athletik.backend.model.Muscle; +import com.triathlon_coaching.product.athletik.backend.service.MuscleService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/api/muscles") +public class MuscleController { + + @Autowired + private MuscleService muscleService; + + @GetMapping + public ResponseEntity> getAllMuscles() { + List muscles = muscleService.findAllMuscles(); + return ResponseEntity.ok(muscles); + } + + @GetMapping("/{id}") + public ResponseEntity getMuscleById(@PathVariable Long id) { + return muscleService.findMuscleById(id) + .map(ResponseEntity::ok) + .orElse(ResponseEntity.notFound().build()); + } + + @GetMapping("/group/{muscleGroup}") + public ResponseEntity> getMusclesByGroup(@PathVariable String muscleGroup) { + List muscles = muscleService.findMusclesByGroup(muscleGroup); + return ResponseEntity.ok(muscles); + } + + @GetMapping("/groups") + public ResponseEntity> getAllMuscleGroups() { + List muscleGroups = muscleService.findAllMuscleGroups(); + return ResponseEntity.ok(muscleGroups); + } + + @GetMapping("/exercise/{exerciseId}") + public ResponseEntity> getMusclesByExerciseId(@PathVariable Long exerciseId) { + List muscles = muscleService.findMusclesByExerciseId(exerciseId); + return ResponseEntity.ok(muscles); + } + + @GetMapping("/primary/exercise/{exerciseId}") + public ResponseEntity> getPrimaryMusclesByExerciseId(@PathVariable Long exerciseId) { + List muscles = muscleService.findPrimaryMusclesByExerciseId(exerciseId); + return ResponseEntity.ok(muscles); + } +} diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/ProtokollController.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/ProtokollController.java new file mode 100644 index 0000000..f2961a0 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/ProtokollController.java @@ -0,0 +1,252 @@ +package com.triathlon_coaching.product.athletik.backend.contoller; + +import com.triathlon_coaching.product.athletik.backend.model.Protokoll; +import com.triathlon_coaching.product.athletik.backend.service.ProtokollService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpSession; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; + +@RestController +@RequestMapping("/api/protokoll") +public class ProtokollController { + + @Autowired + private ProtokollService protokollService; + + @GetMapping + public ResponseEntity> getAllProtokolls() { + List protokolls = protokollService.findAllProtokolls(); + return ResponseEntity.ok(protokolls); + } + + @GetMapping("/{id}") + public ResponseEntity getProtokollById(@PathVariable Long id) { + Optional protokoll = protokollService.findProtokollById(id); + return protokoll.map(ResponseEntity::ok) + .orElse(ResponseEntity.notFound().build()); + } + + @GetMapping("/my-protokolls") + public ResponseEntity> getMyProtokolls(HttpSession session) { + Long athletId = getAthletIdFromSession(session); + if (athletId == null) { + return ResponseEntity.status(401).build(); + } + + List protokolls = protokollService.findByAthletId(athletId); + return ResponseEntity.ok(protokolls); + } + + @GetMapping("/exercise/{exerciseId}") + public ResponseEntity> getProtokollsByExercise( + @PathVariable Long exerciseId, HttpSession session) { + Long athletId = getAthletIdFromSession(session); + if (athletId == null) { + return ResponseEntity.status(401).build(); + } + + List protokolls = protokollService.findByAthletIdAndExerciseId(athletId, exerciseId); + return ResponseEntity.ok(protokolls); + } + + @GetMapping("/exercise/{exerciseId}/paged") + public ResponseEntity> getProtokollsByExercisePaged( + @PathVariable Long exerciseId, + @RequestParam(defaultValue = "0") int page, + @RequestParam(defaultValue = "10") int size, + HttpSession session) { + Long athletId = getAthletIdFromSession(session); + if (athletId == null) { + return ResponseEntity.status(401).build(); + } + + Pageable pageable = PageRequest.of(page, size, Sort.by("trainingDate").descending()); + Page protokolls = protokollService.findByAthletIdAndExerciseIdPaged(athletId, exerciseId, pageable); + return ResponseEntity.ok(protokolls); + } + + @GetMapping("/today") + public ResponseEntity> getTodaySessions(HttpSession session) { + Long athletId = getAthletIdFromSession(session); + if (athletId == null) { + return ResponseEntity.status(401).build(); + } + + List todaySessions = protokollService.findTodaySessionsByAthletId(athletId); + return ResponseEntity.ok(todaySessions); + } + + @GetMapping("/date-range") + public ResponseEntity> getProtokollsByDateRange( + @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime start, + @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime end, + HttpSession session) { + Long athletId = getAthletIdFromSession(session); + if (athletId == null) { + return ResponseEntity.status(401).build(); + } + + List protokolls = protokollService.findByAthletIdAndDateRange(athletId, start, end); + return ResponseEntity.ok(protokolls); + } + + @GetMapping("/tests") + public ResponseEntity> getMyTests(HttpSession session) { + Long athletId = getAthletIdFromSession(session); + if (athletId == null) { + return ResponseEntity.status(401).build(); + } + + List tests = protokollService.findTestsByAthletId(athletId); + return ResponseEntity.ok(tests); + } + + @GetMapping("/tests/exercise/{exerciseId}") + public ResponseEntity> getTestsByExercise( + @PathVariable Long exerciseId, HttpSession session) { + Long athletId = getAthletIdFromSession(session); + if (athletId == null) { + return ResponseEntity.status(401).build(); + } + + List tests = protokollService.findLatestTestsByAthletAndExercise(athletId, exerciseId); + return ResponseEntity.ok(tests); + } + + @GetMapping("/personal-records") + public ResponseEntity> getPersonalRecords(HttpSession session) { + Long athletId = getAthletIdFromSession(session); + if (athletId == null) { + return ResponseEntity.status(401).build(); + } + + List records = protokollService.findPersonalRecords(athletId); + return ResponseEntity.ok(records); + } + + @GetMapping("/stats/volume") + public ResponseEntity getVolumeStats(HttpSession session) { + Long athletId = getAthletIdFromSession(session); + if (athletId == null) { + return ResponseEntity.status(401).build(); + } + + Double dailyVolume = protokollService.calculateDailyVolume(athletId); + Double weeklyVolume = protokollService.calculateWeeklyVolume(athletId); + + return ResponseEntity.ok(new VolumeStats(dailyVolume, weeklyVolume)); + } + + @PostMapping + public ResponseEntity createProtokoll(@RequestBody Protokoll protokoll, HttpSession session) { + Long athletId = getAthletIdFromSession(session); + if (athletId == null) { + return ResponseEntity.status(401).build(); + } + + // Stellen Sie sicher, dass der Protokoll-Eintrag zum eingeloggten Athleten gehört + if (protokoll.getAthlet() == null || !protokoll.getAthlet().getId().equals(athletId)) { + return ResponseEntity.status(403).build(); + } + + Protokoll savedProtokoll = protokollService.saveProtokoll(protokoll); + return ResponseEntity.ok(savedProtokoll); + } + + @PutMapping("/{id}") + public ResponseEntity updateProtokoll(@PathVariable Long id, @RequestBody Protokoll protokollDetails, HttpSession session) { + Long athletId = getAthletIdFromSession(session); + if (athletId == null) { + return ResponseEntity.status(401).build(); + } + + Optional protokollOptional = protokollService.findProtokollById(id); + if (!protokollOptional.isPresent()) { + return ResponseEntity.notFound().build(); + } + + Protokoll protokoll = protokollOptional.get(); + // Prüfen, ob der Protokoll-Eintrag zum eingeloggten Athleten gehört + if (!protokoll.getAthlet().getId().equals(athletId)) { + return ResponseEntity.status(403).build(); + } + + // Aktualisieren der Felder + protokoll.setTrainingDate(protokollDetails.getTrainingDate()); + protokoll.setNumberOfSet(protokollDetails.getNumberOfSet()); + protokoll.setRepetitions(protokollDetails.getRepetitions()); + protokoll.setWeight(protokollDetails.getWeight()); + protokoll.setIsTest(protokollDetails.getIsTest()); + protokoll.setNotes(protokollDetails.getNotes()); + protokoll.setRpe(protokollDetails.getRpe()); + protokoll.setRestTime(protokollDetails.getRestTime()); + + Protokoll updatedProtokoll = protokollService.saveProtokoll(protokoll); + return ResponseEntity.ok(updatedProtokoll); + } + + @DeleteMapping("/{id}") + public ResponseEntity deleteProtokoll(@PathVariable Long id, HttpSession session) { + Long athletId = getAthletIdFromSession(session); + if (athletId == null) { + return ResponseEntity.status(401).build(); + } + + Optional protokollOptional = protokollService.findProtokollById(id); + if (!protokollOptional.isPresent()) { + return ResponseEntity.notFound().build(); + } + + // Prüfen, ob der Protokoll-Eintrag zum eingeloggten Athleten gehört + if (!protokollOptional.get().getAthlet().getId().equals(athletId)) { + return ResponseEntity.status(403).build(); + } + + protokollService.deleteProtokoll(id); + return ResponseEntity.noContent().build(); + } + + @PostMapping("/send-summary") + public ResponseEntity sendTrainingSummary(HttpSession session) { + Long athletId = getAthletIdFromSession(session); + if (athletId == null) { + return ResponseEntity.status(401).build(); + } + + protokollService.sendTrainingSummaryEmail(athletId); + return ResponseEntity.ok().build(); + } + + // Hilfsmethode zur Extraktion der Athlet-ID aus der Session + private Long getAthletIdFromSession(HttpSession session) { + Object athletObj = session.getAttribute("athlet"); + if (athletObj instanceof com.triathlon_coaching.product.athletik.backend.model.Athlet) { + return ((com.triathlon_coaching.product.athletik.backend.model.Athlet) athletObj).getId(); + } + return null; + } + + // DTO für Volumen-Statistiken + private static class VolumeStats { + private Double dailyVolume; + private Double weeklyVolume; + + public VolumeStats(Double dailyVolume, Double weeklyVolume) { + this.dailyVolume = dailyVolume; + this.weeklyVolume = weeklyVolume; + } + + public Double getDailyVolume() { return dailyVolume; } + public Double getWeeklyVolume() { return weeklyVolume; } + } +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/ToolController.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/ToolController.java new file mode 100644 index 0000000..13a5d62 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/ToolController.java @@ -0,0 +1,88 @@ +package com.triathlon_coaching.product.athletik.backend.contoller; + +import com.triathlon_coaching.product.athletik.backend.model.Tool; +import com.triathlon_coaching.product.athletik.backend.service.ToolService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Set; + +@RestController +@RequestMapping("/api/tools") +public class ToolController { + + @Autowired + private ToolService toolService; + + @GetMapping + public ResponseEntity> getAllTools() { + List tools = toolService.findAllTools(); + return ResponseEntity.ok(tools); + } + + @GetMapping("/{id}") + public ResponseEntity getToolById(@PathVariable Long id) { + return toolService.findToolById(id) + .map(ResponseEntity::ok) + .orElse(ResponseEntity.notFound().build()); + } + + @GetMapping("/gym/{gymId}") + public ResponseEntity> getToolsByGymId(@PathVariable Long gymId) { + List tools = toolService.findToolsByGymId(gymId); + return ResponseEntity.ok(tools); + } + + @GetMapping("/{id}/weights") + public ResponseEntity> getAvailableWeights(@PathVariable Long id) { + return toolService.findToolById(id) + .map(tool -> ResponseEntity.ok(tool.getAvailableWeights())) + .orElse(ResponseEntity.notFound().build()); + } + + @GetMapping("/search") + public ResponseEntity> searchTools( + @RequestParam(required = false) String name, + @RequestParam(required = false) String language) { + + List tools; + if (name != null && !name.trim().isEmpty()) { + if ("german".equalsIgnoreCase(language)) { + tools = toolService.findByToolnameGermanContainingIgnoreCase(name); + } else { + tools = toolService.findByToolnameEnglishContainingIgnoreCase(name); + } + } else { + tools = toolService.findAllTools(); + } + + return ResponseEntity.ok(tools); + } + + @PostMapping + public ResponseEntity createTool(@RequestBody Tool tool) { + Tool savedTool = toolService.saveTool(tool); + return ResponseEntity.ok(savedTool); + } + + @PutMapping("/{id}") + public ResponseEntity updateTool(@PathVariable Long id, @RequestBody Tool tool) { + if (!toolService.findToolById(id).isPresent()) { + return ResponseEntity.notFound().build(); + } + tool.setId(id); + Tool updatedTool = toolService.saveTool(tool); + return ResponseEntity.ok(updatedTool); + } + + @DeleteMapping("/{id}") + public ResponseEntity deleteTool(@PathVariable Long id) { + if (!toolService.findToolById(id).isPresent()) { + return ResponseEntity.notFound().build(); + } + toolService.deleteTool(id); + return ResponseEntity.noContent().build(); + } +} diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/TrainingController.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/TrainingController.java new file mode 100644 index 0000000..f08ef84 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/contoller/TrainingController.java @@ -0,0 +1,40 @@ +package com.triathlon_coaching.product.athletik.backend.contoller; + +import javax.servlet.http.HttpSession; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.triathlon_coaching.product.athletik.backend.model.Athlet; +import com.triathlon_coaching.product.athletik.backend.service.TrainingService; + +@RestController +@RequestMapping("/api/training") +public class TrainingController { + + @Autowired + private TrainingService trainingService; + + + @PostMapping("/send-summary") + public ResponseEntity sendTrainingSummary(HttpSession session) { + Athlet athlet = (Athlet) session.getAttribute("athlet"); + if (athlet == null) { + return ResponseEntity.status(401).build(); + } + trainingService.sendTrainingSummaryEmail(athlet.getId()); + return ResponseEntity.ok("Zusammenfassung wurde per E-Mail versendet"); + } + + @GetMapping("/calculate-orm") + public ResponseEntity calculateOneRepMax(@RequestParam double weight, + @RequestParam int repetitions) { + double oneRepMax = trainingService.calculateOneRepMax(weight, repetitions); + return ResponseEntity.ok(oneRepMax); + } +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Athlet.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Athlet.java new file mode 100644 index 0000000..cbe960c --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Athlet.java @@ -0,0 +1,380 @@ +package com.triathlon_coaching.product.athletik.backend.model; + +import java.time.LocalDateTime; +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinTable; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToMany; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +@Entity +@Table(name = "athlet", schema = "athletik") +public class Athlet { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false, unique = true, length = 50) + private String username; + + @Column(name = "fullname", nullable = false, length = 100) + private String fullname; + + @Column(nullable = false, unique = true, length = 100) + private String email; + + @Column(nullable = false, length = 128) + private String pass; + + @Column(name = "created_at", updatable = false) + private LocalDateTime createdAt; + + @Column(name = "last_login") + private LocalDateTime lastLogin; + + @Column(name = "is_active") + private Boolean isActive = true; + + @ManyToMany + @JoinTable( + name = "athletgym", + schema = "athletik", + joinColumns = @JoinColumn(name = "fk_athlet"), + inverseJoinColumns = @JoinColumn(name = "fk_gym") + ) + private Set gyms = new HashSet<>(); + + @OneToMany(mappedBy = "athlet", cascade = CascadeType.ALL, orphanRemoval = true) + private Set protokolls = new HashSet<>(); + + @OneToMany(mappedBy = "athlet", cascade = CascadeType.ALL, orphanRemoval = true) + private Set trainings = new HashSet<>(); + + @OneToMany(mappedBy = "athlet", cascade = CascadeType.ALL, orphanRemoval = true) + private Set logs = new HashSet<>(); + + public Athlet() { + super(); + // TODO Auto-generated constructor stub + } + + + public Athlet(Long id, String username, String fullname, String email, String pass, LocalDateTime createdAt, + LocalDateTime lastLogin, Boolean isActive, Set gyms, Set protokolls, + Set trainings, Set logs) { + super(); + this.username = username; + this.fullname = fullname; + this.email = email; + this.pass = pass; + this.createdAt = createdAt; + this.lastLogin = lastLogin; + this.isActive = isActive; + this.gyms = gyms; + this.protokolls = protokolls; + this.trainings = trainings; + this.logs = logs; + } + + /** + * @return the id + */ + public Long getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(Long id) { + this.id = id; + } + + /** + * @return the username + */ + public String getUsername() { + return username; + } + + /** + * @param username the username to set + */ + public void setUsername(String username) { + this.username = username; + } + + /** + * @return the fullname + */ + public String getFullname() { + return fullname; + } + + /** + * @param fullname the fullname to set + */ + public void setFullname(String fullname) { + this.fullname = fullname; + } + + /** + * @return the email + */ + public String getEmail() { + return email; + } + + /** + * @param email the email to set + */ + public void setEmail(String email) { + this.email = email; + } + + /** + * @return the pass + */ + public String getPass() { + return pass; + } + + /** + * @param pass the pass to set + */ + public void setPass(String pass) { + this.pass = pass; + } + + /** + * @return the gyms + */ + public Set getGyms() { + return gyms; + } + + /** + * @param gyms the gyms to set + */ + public void setGyms(Set gyms) { + this.gyms = gyms; + } + + /** + * @return the createdAt + */ + public LocalDateTime getCreatedAt() { + return createdAt; + } + + /** + * @param createdAt the createdAt to set + */ + public void setCreatedAt(LocalDateTime createdAt) { + this.createdAt = createdAt; + } + + /** + * @return the lastLogin + */ + public LocalDateTime getLastLogin() { + return lastLogin; + } + + /** + * @param lastLogin the lastLogin to set + */ + public void setLastLogin(LocalDateTime lastLogin) { + this.lastLogin = lastLogin; + } + + /** + * @return the isActive + */ + public Boolean getIsActive() { + return isActive; + } + + /** + * @param isActive the isActive to set + */ + public void setIsActive(Boolean isActive) { + this.isActive = isActive; + } + + /** + * @return the protokolls + */ + public Set getProtokolls() { + return protokolls; + } + + /** + * @param protokolls the protokolls to set + */ + public void setProtokolls(Set protokolls) { + this.protokolls = protokolls; + } + + /** + * @return the trainings + */ + public Set getTrainings() { + return trainings; + } + + /** + * @param trainings the trainings to set + */ + public void setTrainings(Set trainings) { + this.trainings = trainings; + } + + /** + * @return the logs + */ + public Set getLogs() { + return logs; + } + + /** + * @param logs the logs to set + */ + public void setLogs(Set logs) { + this.logs = logs; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((createdAt == null) ? 0 : createdAt.hashCode()); + result = prime * result + ((email == null) ? 0 : email.hashCode()); + result = prime * result + ((fullname == null) ? 0 : fullname.hashCode()); + result = prime * result + ((gyms == null) ? 0 : gyms.hashCode()); + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((isActive == null) ? 0 : isActive.hashCode()); + result = prime * result + ((lastLogin == null) ? 0 : lastLogin.hashCode()); + result = prime * result + ((logs == null) ? 0 : logs.hashCode()); + result = prime * result + ((pass == null) ? 0 : pass.hashCode()); + result = prime * result + ((protokolls == null) ? 0 : protokolls.hashCode()); + result = prime * result + ((trainings == null) ? 0 : trainings.hashCode()); + result = prime * result + ((username == null) ? 0 : username.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Athlet other = (Athlet) obj; + if (createdAt == null) { + if (other.createdAt != null) + return false; + } else if (!createdAt.equals(other.createdAt)) + return false; + if (email == null) { + if (other.email != null) + return false; + } else if (!email.equals(other.email)) + return false; + if (fullname == null) { + if (other.fullname != null) + return false; + } else if (!fullname.equals(other.fullname)) + return false; + if (gyms == null) { + if (other.gyms != null) + return false; + } else if (!gyms.equals(other.gyms)) + return false; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (isActive == null) { + if (other.isActive != null) + return false; + } else if (!isActive.equals(other.isActive)) + return false; + if (lastLogin == null) { + if (other.lastLogin != null) + return false; + } else if (!lastLogin.equals(other.lastLogin)) + return false; + if (logs == null) { + if (other.logs != null) + return false; + } else if (!logs.equals(other.logs)) + return false; + if (pass == null) { + if (other.pass != null) + return false; + } else if (!pass.equals(other.pass)) + return false; + if (protokolls == null) { + if (other.protokolls != null) + return false; + } else if (!protokolls.equals(other.protokolls)) + return false; + if (trainings == null) { + if (other.trainings != null) + return false; + } else if (!trainings.equals(other.trainings)) + return false; + if (username == null) { + if (other.username != null) + return false; + } else if (!username.equals(other.username)) + return false; + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Athlet [id="); + builder.append(id); + builder.append(", username="); + builder.append(username); + builder.append(", fullname="); + builder.append(fullname); + builder.append(", email="); + builder.append(email); + builder.append(", pass="); + builder.append(pass); + builder.append(", createdAt="); + builder.append(createdAt); + builder.append(", lastLogin="); + builder.append(lastLogin); + builder.append(", isActive="); + builder.append(isActive); + builder.append(", gyms="); + builder.append(gyms); + builder.append(", protokolls="); + builder.append(protokolls); + builder.append(", trainings="); + builder.append(trainings); + builder.append(", logs="); + builder.append(logs); + builder.append("]"); + return builder.toString(); + } + + + +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Exercise.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Exercise.java new file mode 100644 index 0000000..a48d4da --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Exercise.java @@ -0,0 +1,273 @@ +package com.triathlon_coaching.product.athletik.backend.model; + +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +@Entity +@Table(name = "exercise", schema = "athletik") +public class Exercise { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "name_english", nullable = false) + private String nameEnglish; + + @Column(name = "description_english") + private String descriptionEnglish; + + @Column(name = "name_german") + private String nameGerman; + + @Column(name = "description_german") + private String descriptionGerman; + + @Column(name = "url_video") + private String urlVideo; + + @ManyToOne + @JoinColumn(name = "fk_tool", nullable = false) + private Tool tool; + + @ManyToMany + @JoinTable( + name = "exercise_muscle", + schema = "athletik", + joinColumns = @JoinColumn(name = "fk_exercise"), + inverseJoinColumns = @JoinColumn(name = "fk_muscle") + ) + private Set muscles = new HashSet<>(); + + public Exercise() { + super(); + // TODO Auto-generated constructor stub + } + + public Exercise(String nameEnglish, String descriptionEnglish, String nameGerman, String descriptionGerman, + String urlVideo, Tool tool, Set muscles) { + super(); + this.nameEnglish = nameEnglish; + this.descriptionEnglish = descriptionEnglish; + this.nameGerman = nameGerman; + this.descriptionGerman = descriptionGerman; + this.urlVideo = urlVideo; + this.tool = tool; + this.muscles = muscles; + } + + /** + * @return the id + */ + public Long getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(Long id) { + this.id = id; + } + + /** + * @return the nameEnglish + */ + public String getNameEnglish() { + return nameEnglish; + } + + /** + * @param nameEnglish the nameEnglish to set + */ + public void setNameEnglish(String nameEnglish) { + this.nameEnglish = nameEnglish; + } + + /** + * @return the descriptionEnglish + */ + public String getDescriptionEnglish() { + return descriptionEnglish; + } + + /** + * @param descriptionEnglish the descriptionEnglish to set + */ + public void setDescriptionEnglish(String descriptionEnglish) { + this.descriptionEnglish = descriptionEnglish; + } + + /** + * @return the nameGerman + */ + public String getNameGerman() { + return nameGerman; + } + + /** + * @param nameGerman the nameGerman to set + */ + public void setNameGerman(String nameGerman) { + this.nameGerman = nameGerman; + } + + /** + * @return the descriptionGerman + */ + public String getDescriptionGerman() { + return descriptionGerman; + } + + /** + * @param descriptionGerman the descriptionGerman to set + */ + public void setDescriptionGerman(String descriptionGerman) { + this.descriptionGerman = descriptionGerman; + } + + /** + * @return the urlVideo + */ + public String getUrlVideo() { + return urlVideo; + } + + /** + * @param urlVideo the urlVideo to set + */ + public void setUrlVideo(String urlVideo) { + this.urlVideo = urlVideo; + } + + /** + * @return the tool + */ + public Tool getTool() { + return tool; + } + + /** + * @param tool the tool to set + */ + public void setTool(Tool tool) { + this.tool = tool; + } + + /** + * @return the muscles + */ + public Set getMuscles() { + return muscles; + } + + /** + * @param muscles the muscles to set + */ + public void setMuscles(Set muscles) { + this.muscles = muscles; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((descriptionEnglish == null) ? 0 : descriptionEnglish.hashCode()); + result = prime * result + ((descriptionGerman == null) ? 0 : descriptionGerman.hashCode()); + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((muscles == null) ? 0 : muscles.hashCode()); + result = prime * result + ((nameEnglish == null) ? 0 : nameEnglish.hashCode()); + result = prime * result + ((nameGerman == null) ? 0 : nameGerman.hashCode()); + result = prime * result + ((tool == null) ? 0 : tool.hashCode()); + result = prime * result + ((urlVideo == null) ? 0 : urlVideo.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Exercise other = (Exercise) obj; + if (descriptionEnglish == null) { + if (other.descriptionEnglish != null) + return false; + } else if (!descriptionEnglish.equals(other.descriptionEnglish)) + return false; + if (descriptionGerman == null) { + if (other.descriptionGerman != null) + return false; + } else if (!descriptionGerman.equals(other.descriptionGerman)) + return false; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (muscles == null) { + if (other.muscles != null) + return false; + } else if (!muscles.equals(other.muscles)) + return false; + if (nameEnglish == null) { + if (other.nameEnglish != null) + return false; + } else if (!nameEnglish.equals(other.nameEnglish)) + return false; + if (nameGerman == null) { + if (other.nameGerman != null) + return false; + } else if (!nameGerman.equals(other.nameGerman)) + return false; + if (tool == null) { + if (other.tool != null) + return false; + } else if (!tool.equals(other.tool)) + return false; + if (urlVideo == null) { + if (other.urlVideo != null) + return false; + } else if (!urlVideo.equals(other.urlVideo)) + return false; + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Exercise [id="); + builder.append(id); + builder.append(", nameEnglish="); + builder.append(nameEnglish); + builder.append(", descriptionEnglish="); + builder.append(descriptionEnglish); + builder.append(", nameGerman="); + builder.append(nameGerman); + builder.append(", descriptionGerman="); + builder.append(descriptionGerman); + builder.append(", urlVideo="); + builder.append(urlVideo); + builder.append(", tool="); + builder.append(tool); + builder.append(", muscles="); + builder.append(muscles); + builder.append("]"); + return builder.toString(); + } + + + +} diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Goal.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Goal.java new file mode 100644 index 0000000..5120f37 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Goal.java @@ -0,0 +1,158 @@ +package com.triathlon_coaching.product.athletik.backend.model; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import java.util.HashSet; +import java.util.Set; + +@Entity +@Table(name = "goal", schema = "athletik") +public class Goal { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "goalname", nullable = false, length = 100) + private String goalname; + + @Column(name = "description", columnDefinition = "TEXT") + private String description; + + @OneToMany(mappedBy = "goal", cascade = CascadeType.ALL, orphanRemoval = true) + private Set trainings = new HashSet<>(); + + public Goal() { + super(); + // TODO Auto-generated constructor stub + } + + public Goal(String goalname, String description, Set trainings) { + super(); + this.goalname = goalname; + this.description = description; + this.trainings = trainings; + } + + /** + * @return the id + */ + public Long getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(Long id) { + this.id = id; + } + + /** + * @return the goalname + */ + public String getGoalname() { + return goalname; + } + + /** + * @param goalname the goalname to set + */ + public void setGoalname(String goalname) { + this.goalname = goalname; + } + + /** + * @return the description + */ + public String getDescription() { + return description; + } + + /** + * @param description the description to set + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * @return the trainings + */ + public Set getTrainings() { + return trainings; + } + + /** + * @param trainings the trainings to set + */ + public void setTrainings(Set trainings) { + this.trainings = trainings; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + ((goalname == null) ? 0 : goalname.hashCode()); + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((trainings == null) ? 0 : trainings.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Goal other = (Goal) obj; + if (description == null) { + if (other.description != null) + return false; + } else if (!description.equals(other.description)) + return false; + if (goalname == null) { + if (other.goalname != null) + return false; + } else if (!goalname.equals(other.goalname)) + return false; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (trainings == null) { + if (other.trainings != null) + return false; + } else if (!trainings.equals(other.trainings)) + return false; + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Goal [id="); + builder.append(id); + builder.append(", goalname="); + builder.append(goalname); + builder.append(", description="); + builder.append(description); + builder.append(", trainings="); + builder.append(trainings); + builder.append("]"); + return builder.toString(); + } + + +} diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Gym.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Gym.java new file mode 100644 index 0000000..c61d298 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Gym.java @@ -0,0 +1,217 @@ +package com.triathlon_coaching.product.athletik.backend.model; + +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinTable; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToMany; +import javax.persistence.Table; + +@Entity +@Table(name = "gym", schema = "athletik") +public class Gym { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private String gymname; + + @Column + private String gymlocation; + + @ManyToMany(mappedBy = "gyms") + private Set athleten = new HashSet<>(); + + @ManyToMany + @JoinTable( + name = "gymtool", + schema = "athletik", + joinColumns = @JoinColumn(name = "fk_gym"), + inverseJoinColumns = @JoinColumn(name = "fk_tool") + ) + private Set tools = new HashSet<>(); + + public Gym() { + super(); + // TODO Auto-generated constructor stub + } + + public Gym(String gymname, String gymlocation, Set athleten, Set tools) { + super(); + this.gymname = gymname; + this.gymlocation = gymlocation; + this.athleten = athleten; + this.tools = tools; + } + + /** + * @return the id + */ + public Long getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(Long id) { + this.id = id; + } + + /** + * @return the gymname + */ + public String getGymname() { + return gymname; + } + + /** + * @param gymname the gymname to set + */ + public void setGymname(String gymname) { + this.gymname = gymname; + } + + /** + * @return the gymlocation + */ + public String getGymlocation() { + return gymlocation; + } + + /** + * @param gymlocation the gymlocation to set + */ + public void setGymlocation(String gymlocation) { + this.gymlocation = gymlocation; + } + + /** + * @return the athleten + */ + public Set getAthleten() { + return athleten; + } + + /** + * @param athleten the athleten to set + */ + public void setAthleten(Set athleten) { + this.athleten = athleten; + } + + /** + * @return the tools + */ + public Set getTools() { + return tools; + } + + /** + * @param tools the tools to set + */ + public void setTools(Set tools) { + this.tools = tools; + } + + // Hilfsmethoden +/* + public void addAthlet(Athlet athlet) { + this.athleten.add(athlet); + athlet.getGyms().add(this); + } + + public void removeAthlet(Athlet athlet) { + this.athleten.remove(athlet); + athlet.getGyms().remove(this); + } + + public void addTool(Tool tool) { + this.tools.add(tool); + tool.getGyms().add(this); + } + + public void removeTool(Tool tool) { + this.tools.remove(tool); + tool.getGyms().remove(this); + } +*/ + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((athleten == null) ? 0 : athleten.hashCode()); + result = prime * result + ((gymlocation == null) ? 0 : gymlocation.hashCode()); + result = prime * result + ((gymname == null) ? 0 : gymname.hashCode()); + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((tools == null) ? 0 : tools.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Gym other = (Gym) obj; + if (athleten == null) { + if (other.athleten != null) + return false; + } else if (!athleten.equals(other.athleten)) + return false; + if (gymlocation == null) { + if (other.gymlocation != null) + return false; + } else if (!gymlocation.equals(other.gymlocation)) + return false; + if (gymname == null) { + if (other.gymname != null) + return false; + } else if (!gymname.equals(other.gymname)) + return false; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (tools == null) { + if (other.tools != null) + return false; + } else if (!tools.equals(other.tools)) + return false; + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Gym [id="); + builder.append(id); + builder.append(", gymname="); + builder.append(gymname); + builder.append(", gymlocation="); + builder.append(gymlocation); + builder.append(", athleten="); + builder.append(athleten); + builder.append(", tools="); + builder.append(tools); + builder.append("]"); + return builder.toString(); + } + + + + +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Log.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Log.java new file mode 100644 index 0000000..bdf6c2e --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Log.java @@ -0,0 +1,328 @@ +package com.triathlon_coaching.product.athletik.backend.model; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.PrePersist; +import javax.persistence.Table; +import java.time.LocalDateTime; + +@Entity +@Table(name = "log", schema = "athletik") +public class Log { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "created", nullable = false, updatable = false) + private LocalDateTime created; + + @Column(name = "logdata", nullable = false, columnDefinition = "TEXT") + private String logdata; + + @Column(name = "sid", nullable = false, length = 100) + private String sid; + + @Column(name = "script", nullable = false, length = 255) + private String script; + + @Column(name = "log_level", length = 20) + private String logLevel; + + @Column(name = "ip_address", length = 45) + private String ipAddress; + + @Column(name = "user_agent", length = 500) + private String userAgent; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "fk_athlet", nullable = false) + private Athlet athlet; + + // Konstruktoren + public Log() { + this.created = LocalDateTime.now(); + } + + + + public Log(LocalDateTime created, String logdata, String sid, String script, String logLevel, String ipAddress, + String userAgent, Athlet athlet) { + super(); + this.created = created; + this.logdata = logdata; + this.sid = sid; + this.script = script; + this.logLevel = logLevel; + this.ipAddress = ipAddress; + this.userAgent = userAgent; + this.athlet = athlet; + } + + + + public Log(String logdata, String sid, String script, Athlet athlet) { + this(); + this.logdata = logdata; + this.sid = sid; + this.script = script; + this.athlet = athlet; + } + + public Log(String logdata, String sid, String script, String logLevel, Athlet athlet) { + this(logdata, sid, script, athlet); + this.logLevel = logLevel; + } + + public Log(String logdata, String sid, String script, String logLevel, String ipAddress, String userAgent, Athlet athlet) { + this(logdata, sid, script, logLevel, athlet); + this.ipAddress = ipAddress; + this.userAgent = userAgent; + } + + // Pre-Persist Callback + @PrePersist + protected void onCreate() { + if (created == null) { + created = LocalDateTime.now(); + } + } + + /** + * @return the id + */ + public Long getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(Long id) { + this.id = id; + } + + /** + * @return the created + */ + public LocalDateTime getCreated() { + return created; + } + + /** + * @param created the created to set + */ + public void setCreated(LocalDateTime created) { + this.created = created; + } + + /** + * @return the logdata + */ + public String getLogdata() { + return logdata; + } + + /** + * @param logdata the logdata to set + */ + public void setLogdata(String logdata) { + this.logdata = logdata; + } + + /** + * @return the sid + */ + public String getSid() { + return sid; + } + + /** + * @param sid the sid to set + */ + public void setSid(String sid) { + this.sid = sid; + } + + /** + * @return the script + */ + public String getScript() { + return script; + } + + /** + * @param script the script to set + */ + public void setScript(String script) { + this.script = script; + } + + /** + * @return the logLevel + */ + public String getLogLevel() { + return logLevel; + } + + /** + * @param logLevel the logLevel to set + */ + public void setLogLevel(String logLevel) { + this.logLevel = logLevel; + } + + /** + * @return the ipAddress + */ + public String getIpAddress() { + return ipAddress; + } + + /** + * @param ipAddress the ipAddress to set + */ + public void setIpAddress(String ipAddress) { + this.ipAddress = ipAddress; + } + + /** + * @return the userAgent + */ + public String getUserAgent() { + return userAgent; + } + + /** + * @param userAgent the userAgent to set + */ + public void setUserAgent(String userAgent) { + this.userAgent = userAgent; + } + + /** + * @return the athlet + */ + public Athlet getAthlet() { + return athlet; + } + + /** + * @param athlet the athlet to set + */ + public void setAthlet(Athlet athlet) { + this.athlet = athlet; + } + + + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((athlet == null) ? 0 : athlet.hashCode()); + result = prime * result + ((created == null) ? 0 : created.hashCode()); + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((ipAddress == null) ? 0 : ipAddress.hashCode()); + result = prime * result + ((logLevel == null) ? 0 : logLevel.hashCode()); + result = prime * result + ((logdata == null) ? 0 : logdata.hashCode()); + result = prime * result + ((script == null) ? 0 : script.hashCode()); + result = prime * result + ((sid == null) ? 0 : sid.hashCode()); + result = prime * result + ((userAgent == null) ? 0 : userAgent.hashCode()); + return result; + } + + + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Log other = (Log) obj; + if (athlet == null) { + if (other.athlet != null) + return false; + } else if (!athlet.equals(other.athlet)) + return false; + if (created == null) { + if (other.created != null) + return false; + } else if (!created.equals(other.created)) + return false; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (ipAddress == null) { + if (other.ipAddress != null) + return false; + } else if (!ipAddress.equals(other.ipAddress)) + return false; + if (logLevel == null) { + if (other.logLevel != null) + return false; + } else if (!logLevel.equals(other.logLevel)) + return false; + if (logdata == null) { + if (other.logdata != null) + return false; + } else if (!logdata.equals(other.logdata)) + return false; + if (script == null) { + if (other.script != null) + return false; + } else if (!script.equals(other.script)) + return false; + if (sid == null) { + if (other.sid != null) + return false; + } else if (!sid.equals(other.sid)) + return false; + if (userAgent == null) { + if (other.userAgent != null) + return false; + } else if (!userAgent.equals(other.userAgent)) + return false; + return true; + } + + + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Log [id="); + builder.append(id); + builder.append(", created="); + builder.append(created); + builder.append(", logdata="); + builder.append(logdata); + builder.append(", sid="); + builder.append(sid); + builder.append(", script="); + builder.append(script); + builder.append(", logLevel="); + builder.append(logLevel); + builder.append(", ipAddress="); + builder.append(ipAddress); + builder.append(", userAgent="); + builder.append(userAgent); + builder.append(", athlet="); + builder.append(athlet); + builder.append("]"); + return builder.toString(); + } + + +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Muscle.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Muscle.java new file mode 100644 index 0000000..ea215d7 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Muscle.java @@ -0,0 +1,289 @@ +package com.triathlon_coaching.product.athletik.backend.model; + +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.ManyToMany; +import javax.persistence.Table; + +@Entity +@Table(name = "muscle", schema = "athletik") +public class Muscle { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "muscle_name_latin", nullable = false) + private String muscleNameLatin; + + @Column(name = "muscle_name_english") + private String muscleNameEnglish; + + @Column(name = "muscle_name_german") + private String muscleNameGerman; + + @Column(name = "movement_english", nullable = false) + private String movementEnglish; + + @Column(name = "movement_german", nullable = false) + private String movementGerman; + + @Column(name = "musclegroup_name_english") + private String musclegroupNameEnglish; + + @Column(name = "musclegroup_name_german") + private String musclegroupNameGerman; + + @ManyToMany(mappedBy = "muscles") + private Set exercises = new HashSet<>(); + + public Muscle() { + super(); + // TODO Auto-generated constructor stub + } + + public Muscle(String muscleNameLatin, String muscleNameEnglish, String muscleNameGerman, String movementEnglish, + String movementGerman, String musclegroupNameEnglish, String musclegroupNameGerman, + Set exercises) { + super(); + this.muscleNameLatin = muscleNameLatin; + this.muscleNameEnglish = muscleNameEnglish; + this.muscleNameGerman = muscleNameGerman; + this.movementEnglish = movementEnglish; + this.movementGerman = movementGerman; + this.musclegroupNameEnglish = musclegroupNameEnglish; + this.musclegroupNameGerman = musclegroupNameGerman; + this.exercises = exercises; + } + + /** + * @return the id + */ + public Long getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(Long id) { + this.id = id; + } + + /** + * @return the muscleNameLatin + */ + public String getMuscleNameLatin() { + return muscleNameLatin; + } + + /** + * @param muscleNameLatin the muscleNameLatin to set + */ + public void setMuscleNameLatin(String muscleNameLatin) { + this.muscleNameLatin = muscleNameLatin; + } + + /** + * @return the muscleNameEnglish + */ + public String getMuscleNameEnglish() { + return muscleNameEnglish; + } + + /** + * @param muscleNameEnglish the muscleNameEnglish to set + */ + public void setMuscleNameEnglish(String muscleNameEnglish) { + this.muscleNameEnglish = muscleNameEnglish; + } + + /** + * @return the muscleNameGerman + */ + public String getMuscleNameGerman() { + return muscleNameGerman; + } + + /** + * @param muscleNameGerman the muscleNameGerman to set + */ + public void setMuscleNameGerman(String muscleNameGerman) { + this.muscleNameGerman = muscleNameGerman; + } + + /** + * @return the movementEnglish + */ + public String getMovementEnglish() { + return movementEnglish; + } + + /** + * @param movementEnglish the movementEnglish to set + */ + public void setMovementEnglish(String movementEnglish) { + this.movementEnglish = movementEnglish; + } + + /** + * @return the movementGerman + */ + public String getMovementGerman() { + return movementGerman; + } + + /** + * @param movementGerman the movementGerman to set + */ + public void setMovementGerman(String movementGerman) { + this.movementGerman = movementGerman; + } + + /** + * @return the musclegroupNameEnglish + */ + public String getMusclegroupNameEnglish() { + return musclegroupNameEnglish; + } + + /** + * @param musclegroupNameEnglish the musclegroupNameEnglish to set + */ + public void setMusclegroupNameEnglish(String musclegroupNameEnglish) { + this.musclegroupNameEnglish = musclegroupNameEnglish; + } + + /** + * @return the musclegroupNameGerman + */ + public String getMusclegroupNameGerman() { + return musclegroupNameGerman; + } + + /** + * @param musclegroupNameGerman the musclegroupNameGerman to set + */ + public void setMusclegroupNameGerman(String musclegroupNameGerman) { + this.musclegroupNameGerman = musclegroupNameGerman; + } + + /** + * @return the exercises + */ + public Set getExercises() { + return exercises; + } + + /** + * @param exercises the exercises to set + */ + public void setExercises(Set exercises) { + this.exercises = exercises; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((exercises == null) ? 0 : exercises.hashCode()); + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((movementEnglish == null) ? 0 : movementEnglish.hashCode()); + result = prime * result + ((movementGerman == null) ? 0 : movementGerman.hashCode()); + result = prime * result + ((muscleNameEnglish == null) ? 0 : muscleNameEnglish.hashCode()); + result = prime * result + ((muscleNameGerman == null) ? 0 : muscleNameGerman.hashCode()); + result = prime * result + ((muscleNameLatin == null) ? 0 : muscleNameLatin.hashCode()); + result = prime * result + ((musclegroupNameEnglish == null) ? 0 : musclegroupNameEnglish.hashCode()); + result = prime * result + ((musclegroupNameGerman == null) ? 0 : musclegroupNameGerman.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Muscle other = (Muscle) obj; + if (exercises == null) { + if (other.exercises != null) + return false; + } else if (!exercises.equals(other.exercises)) + return false; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (movementEnglish == null) { + if (other.movementEnglish != null) + return false; + } else if (!movementEnglish.equals(other.movementEnglish)) + return false; + if (movementGerman == null) { + if (other.movementGerman != null) + return false; + } else if (!movementGerman.equals(other.movementGerman)) + return false; + if (muscleNameEnglish == null) { + if (other.muscleNameEnglish != null) + return false; + } else if (!muscleNameEnglish.equals(other.muscleNameEnglish)) + return false; + if (muscleNameGerman == null) { + if (other.muscleNameGerman != null) + return false; + } else if (!muscleNameGerman.equals(other.muscleNameGerman)) + return false; + if (muscleNameLatin == null) { + if (other.muscleNameLatin != null) + return false; + } else if (!muscleNameLatin.equals(other.muscleNameLatin)) + return false; + if (musclegroupNameEnglish == null) { + if (other.musclegroupNameEnglish != null) + return false; + } else if (!musclegroupNameEnglish.equals(other.musclegroupNameEnglish)) + return false; + if (musclegroupNameGerman == null) { + if (other.musclegroupNameGerman != null) + return false; + } else if (!musclegroupNameGerman.equals(other.musclegroupNameGerman)) + return false; + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Muscle [id="); + builder.append(id); + builder.append(", muscleNameLatin="); + builder.append(muscleNameLatin); + builder.append(", muscleNameEnglish="); + builder.append(muscleNameEnglish); + builder.append(", muscleNameGerman="); + builder.append(muscleNameGerman); + builder.append(", movementEnglish="); + builder.append(movementEnglish); + builder.append(", movementGerman="); + builder.append(movementGerman); + builder.append(", musclegroupNameEnglish="); + builder.append(musclegroupNameEnglish); + builder.append(", musclegroupNameGerman="); + builder.append(musclegroupNameGerman); + builder.append(", exercises="); + builder.append(exercises); + builder.append("]"); + return builder.toString(); + } + +} diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Protokoll.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Protokoll.java new file mode 100644 index 0000000..969e985 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Protokoll.java @@ -0,0 +1,398 @@ +package com.triathlon_coaching.product.athletik.backend.model; + +import java.time.LocalDateTime; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +@Entity +@Table(name = "protokoll", schema = "athletik") +public class Protokoll { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "trainingdate", nullable = false) + private LocalDateTime trainingDate; + + @Column(name = "number_of_set", nullable = false) + private Integer numberOfSet; + + @Column(name = "repetitions", nullable = false) + private Integer repetitions; + + @Column(name = "weight", precision = 5, scale = 2) + private Double weight; + + @Column(name = "is_test", nullable = false) + private Boolean isTest = false; + + @Column(name = "volume") + private Double volume; + + @Column(name = "one_rep_max") + private Double oneRepMax; + + @Column(name = "notes", length = 500) + private String notes; + + @Column(name = "rpe") // Rate of Perceived Exertion + private Integer rpe; + + @Column(name = "rest_time") // in seconds + private Integer restTime; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "fk_athlet", nullable = false) + private Athlet athlet; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "fk_exercise", nullable = false) + private Exercise exercise; + + public Protokoll() { + super(); + // TODO Auto-generated constructor stub + } + + public Protokoll(LocalDateTime trainingDate, Integer numberOfSet, Integer repetitions, Double weight, + Boolean isTest, Double volume, Double oneRepMax, String notes, Integer rpe, Integer restTime, Athlet athlet, + Exercise exercise) { + super(); + this.trainingDate = trainingDate; + this.numberOfSet = numberOfSet; + this.repetitions = repetitions; + this.weight = weight; + this.isTest = isTest; + this.volume = volume; + this.oneRepMax = oneRepMax; + this.notes = notes; + this.rpe = rpe; + this.restTime = restTime; + this.athlet = athlet; + this.exercise = exercise; + } + + /** + * @return the id + */ + public Long getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(Long id) { + this.id = id; + } + + /** + * @return the trainingDate + */ + public LocalDateTime getTrainingDate() { + return trainingDate; + } + + /** + * @param trainingDate the trainingDate to set + */ + public void setTrainingDate(LocalDateTime trainingDate) { + this.trainingDate = trainingDate; + } + + /** + * @return the numberOfSet + */ + public Integer getNumberOfSet() { + return numberOfSet; + } + + /** + * @param numberOfSet the numberOfSet to set + */ + public void setNumberOfSet(Integer numberOfSet) { + this.numberOfSet = numberOfSet; + } + + /** + * @return the repetitions + */ + public Integer getRepetitions() { + return repetitions; + } + + /** + * @param repetitions the repetitions to set + */ + public void setRepetitions(Integer repetitions) { + this.repetitions = repetitions; + } + + /** + * @return the weight + */ + public Double getWeight() { + return weight; + } + + /** + * @param weight the weight to set + */ + public void setWeight(Double weight) { + this.weight = weight; + } + + /** + * @return the isTest + */ + public Boolean getIsTest() { + return isTest; + } + + /** + * @param isTest the isTest to set + */ + public void setIsTest(Boolean isTest) { + this.isTest = isTest; + } + + /** + * @return the volume + */ + public Double getVolume() { + return volume; + } + + /** + * @param volume the volume to set + */ + public void setVolume(Double volume) { + this.volume = volume; + } + + /** + * @return the oneRepMax + */ + public Double getOneRepMax() { + return oneRepMax; + } + + /** + * @param oneRepMax the oneRepMax to set + */ + public void setOneRepMax(Double oneRepMax) { + this.oneRepMax = oneRepMax; + } + + /** + * @return the notes + */ + public String getNotes() { + return notes; + } + + /** + * @param notes the notes to set + */ + public void setNotes(String notes) { + this.notes = notes; + } + + /** + * @return the rpe + */ + public Integer getRpe() { + return rpe; + } + + /** + * @param rpe the rpe to set + */ + public void setRpe(Integer rpe) { + this.rpe = rpe; + } + + /** + * @return the restTime + */ + public Integer getRestTime() { + return restTime; + } + + /** + * @param restTime the restTime to set + */ + public void setRestTime(Integer restTime) { + this.restTime = restTime; + } + + /** + * @return the athlet + */ + public Athlet getAthlet() { + return athlet; + } + + /** + * @param athlet the athlet to set + */ + public void setAthlet(Athlet athlet) { + this.athlet = athlet; + } + + /** + * @return the exercise + */ + public Exercise getExercise() { + return exercise; + } + + /** + * @param exercise the exercise to set + */ + public void setExercise(Exercise exercise) { + this.exercise = exercise; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((athlet == null) ? 0 : athlet.hashCode()); + result = prime * result + ((exercise == null) ? 0 : exercise.hashCode()); + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((isTest == null) ? 0 : isTest.hashCode()); + result = prime * result + ((notes == null) ? 0 : notes.hashCode()); + result = prime * result + ((numberOfSet == null) ? 0 : numberOfSet.hashCode()); + result = prime * result + ((oneRepMax == null) ? 0 : oneRepMax.hashCode()); + result = prime * result + ((repetitions == null) ? 0 : repetitions.hashCode()); + result = prime * result + ((restTime == null) ? 0 : restTime.hashCode()); + result = prime * result + ((rpe == null) ? 0 : rpe.hashCode()); + result = prime * result + ((trainingDate == null) ? 0 : trainingDate.hashCode()); + result = prime * result + ((volume == null) ? 0 : volume.hashCode()); + result = prime * result + ((weight == null) ? 0 : weight.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Protokoll other = (Protokoll) obj; + if (athlet == null) { + if (other.athlet != null) + return false; + } else if (!athlet.equals(other.athlet)) + return false; + if (exercise == null) { + if (other.exercise != null) + return false; + } else if (!exercise.equals(other.exercise)) + return false; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (isTest == null) { + if (other.isTest != null) + return false; + } else if (!isTest.equals(other.isTest)) + return false; + if (notes == null) { + if (other.notes != null) + return false; + } else if (!notes.equals(other.notes)) + return false; + if (numberOfSet == null) { + if (other.numberOfSet != null) + return false; + } else if (!numberOfSet.equals(other.numberOfSet)) + return false; + if (oneRepMax == null) { + if (other.oneRepMax != null) + return false; + } else if (!oneRepMax.equals(other.oneRepMax)) + return false; + if (repetitions == null) { + if (other.repetitions != null) + return false; + } else if (!repetitions.equals(other.repetitions)) + return false; + if (restTime == null) { + if (other.restTime != null) + return false; + } else if (!restTime.equals(other.restTime)) + return false; + if (rpe == null) { + if (other.rpe != null) + return false; + } else if (!rpe.equals(other.rpe)) + return false; + if (trainingDate == null) { + if (other.trainingDate != null) + return false; + } else if (!trainingDate.equals(other.trainingDate)) + return false; + if (volume == null) { + if (other.volume != null) + return false; + } else if (!volume.equals(other.volume)) + return false; + if (weight == null) { + if (other.weight != null) + return false; + } else if (!weight.equals(other.weight)) + return false; + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Protokoll [id="); + builder.append(id); + builder.append(", trainingDate="); + builder.append(trainingDate); + builder.append(", numberOfSet="); + builder.append(numberOfSet); + builder.append(", repetitions="); + builder.append(repetitions); + builder.append(", weight="); + builder.append(weight); + builder.append(", isTest="); + builder.append(isTest); + builder.append(", volume="); + builder.append(volume); + builder.append(", oneRepMax="); + builder.append(oneRepMax); + builder.append(", notes="); + builder.append(notes); + builder.append(", rpe="); + builder.append(rpe); + builder.append(", restTime="); + builder.append(restTime); + builder.append(", athlet="); + builder.append(athlet); + builder.append(", exercise="); + builder.append(exercise); + builder.append("]"); + return builder.toString(); + } + + +} + diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Tool.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Tool.java new file mode 100644 index 0000000..7f4e2a6 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Tool.java @@ -0,0 +1,235 @@ +package com.triathlon_coaching.product.athletik.backend.model; + +import java.math.BigDecimal; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "tools", schema = "athletik") +public class Tool { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "toolname_english", nullable = false) + private String toolnameEnglish; + + @Column(name = "toolname_german", nullable = false) + private String toolnameGerman; + + @Column(name = "min_weight", precision = 5, scale = 2) + private BigDecimal minWeight = BigDecimal.ZERO; + + @Column(name = "steps_weight", precision = 5, scale = 2) + private BigDecimal stepsWeight = BigDecimal.ZERO; + + @Column(name = "max_weight", precision = 5, scale = 2) + private BigDecimal maxWeight = BigDecimal.ZERO; + + @Column(name = "description") + private String description; + + public Tool() { + super(); + // TODO Auto-generated constructor stub + } + + public Tool(String toolnameEnglish, String toolnameGerman, BigDecimal minWeight, BigDecimal stepsWeight, + BigDecimal maxWeight, String description) { + super(); + this.toolnameEnglish = toolnameEnglish; + this.toolnameGerman = toolnameGerman; + this.minWeight = minWeight; + this.stepsWeight = stepsWeight; + this.maxWeight = maxWeight; + this.description = description; + } + + /** + * @return the id + */ + public Long getId() { + return id; + } + + /** + * @param id the id to set + */ + public void setId(Long id) { + this.id = id; + } + + /** + * @return the toolnameEnglish + */ + public String getToolnameEnglish() { + return toolnameEnglish; + } + + /** + * @param toolnameEnglish the toolnameEnglish to set + */ + public void setToolnameEnglish(String toolnameEnglish) { + this.toolnameEnglish = toolnameEnglish; + } + + /** + * @return the toolnameGerman + */ + public String getToolnameGerman() { + return toolnameGerman; + } + + /** + * @param toolnameGerman the toolnameGerman to set + */ + public void setToolnameGerman(String toolnameGerman) { + this.toolnameGerman = toolnameGerman; + } + + /** + * @return the minWeight + */ + public BigDecimal getMinWeight() { + return minWeight; + } + + /** + * @param minWeight the minWeight to set + */ + public void setMinWeight(BigDecimal minWeight) { + this.minWeight = minWeight; + } + + /** + * @return the stepsWeight + */ + public BigDecimal getStepsWeight() { + return stepsWeight; + } + + /** + * @param stepsWeight the stepsWeight to set + */ + public void setStepsWeight(BigDecimal stepsWeight) { + this.stepsWeight = stepsWeight; + } + + /** + * @return the maxWeight + */ + public BigDecimal getMaxWeight() { + return maxWeight; + } + + /** + * @param maxWeight the maxWeight to set + */ + public void setMaxWeight(BigDecimal maxWeight) { + this.maxWeight = maxWeight; + } + + /** + * @return the description + */ + public String getDescription() { + return description; + } + + /** + * @param description the description to set + */ + public void setDescription(String description) { + this.description = description; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((maxWeight == null) ? 0 : maxWeight.hashCode()); + result = prime * result + ((minWeight == null) ? 0 : minWeight.hashCode()); + result = prime * result + ((stepsWeight == null) ? 0 : stepsWeight.hashCode()); + result = prime * result + ((toolnameEnglish == null) ? 0 : toolnameEnglish.hashCode()); + result = prime * result + ((toolnameGerman == null) ? 0 : toolnameGerman.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Tool other = (Tool) obj; + if (description == null) { + if (other.description != null) + return false; + } else if (!description.equals(other.description)) + return false; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (maxWeight == null) { + if (other.maxWeight != null) + return false; + } else if (!maxWeight.equals(other.maxWeight)) + return false; + if (minWeight == null) { + if (other.minWeight != null) + return false; + } else if (!minWeight.equals(other.minWeight)) + return false; + if (stepsWeight == null) { + if (other.stepsWeight != null) + return false; + } else if (!stepsWeight.equals(other.stepsWeight)) + return false; + if (toolnameEnglish == null) { + if (other.toolnameEnglish != null) + return false; + } else if (!toolnameEnglish.equals(other.toolnameEnglish)) + return false; + if (toolnameGerman == null) { + if (other.toolnameGerman != null) + return false; + } else if (!toolnameGerman.equals(other.toolnameGerman)) + return false; + return true; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Tools [id="); + builder.append(id); + builder.append(", toolnameEnglish="); + builder.append(toolnameEnglish); + builder.append(", toolnameGerman="); + builder.append(toolnameGerman); + builder.append(", minWeight="); + builder.append(minWeight); + builder.append(", stepsWeight="); + builder.append(stepsWeight); + builder.append(", maxWeight="); + builder.append(maxWeight); + builder.append(", description="); + builder.append(description); + builder.append("]"); + return builder.toString(); + } + + + +} diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Training.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Training.java new file mode 100644 index 0000000..f6853a6 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/Training.java @@ -0,0 +1,442 @@ +package com.triathlon_coaching.product.athletik.backend.model; + +import java.time.LocalDateTime; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.PrePersist; +import javax.persistence.Table; + +@Entity +@Table(name = "training", schema = "athletik") +public class Training { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "title", nullable = false, length = 200) + private String title; + + @Column(name = "description", columnDefinition = "TEXT") + private String description; + + @Column(name = "repetitions_of_set") + private Integer repetitionsOfSet; + + @Column(name = "repetitions") + private Integer repetitions; + + @Column(name = "factor_of_fmax", precision = 5, scale = 2) + private Double factorOfFmax; + + @Column(name = "created", nullable = false, updatable = false) + private LocalDateTime created; + + @Column(name = "valid_since", nullable = false) + private LocalDateTime validSince; + + @Column(name = "valid_until") + private LocalDateTime validUntil; + + @Column(name = "is_active") + private Boolean isActive = true; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "fk_goal", nullable = false) + private Goal goal; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "fk_athlet", nullable = false) + private Athlet athlet; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "fk_exercise", nullable = false) + private Exercise exercise; + + public Training() { + super(); + // TODO Auto-generated constructor stub + } + + + public Training(String title, String description, Integer repetitionsOfSet, Integer repetitions, + Double factorOfFmax, LocalDateTime created, LocalDateTime validSince, LocalDateTime validUntil, + Boolean isActive, Goal goal, Athlet athlet, Exercise exercise) { + super(); + this.title = title; + this.description = description; + this.repetitionsOfSet = repetitionsOfSet; + this.repetitions = repetitions; + this.factorOfFmax = factorOfFmax; + this.created = created; + this.validSince = validSince; + this.validUntil = validUntil; + this.isActive = isActive; + this.goal = goal; + this.athlet = athlet; + this.exercise = exercise; + } + + + + // Pre-Persist Callback + @PrePersist + protected void onCreate() { + if (created == null) { + created = LocalDateTime.now(); + } + if (validSince == null) { + validSince = LocalDateTime.now(); + } + } + + + /** + * @return the id + */ + public Long getId() { + return id; + } + + + /** + * @param id the id to set + */ + public void setId(Long id) { + this.id = id; + } + + + /** + * @return the title + */ + public String getTitle() { + return title; + } + + + /** + * @param title the title to set + */ + public void setTitle(String title) { + this.title = title; + } + + + /** + * @return the description + */ + public String getDescription() { + return description; + } + + + /** + * @param description the description to set + */ + public void setDescription(String description) { + this.description = description; + } + + + /** + * @return the repetitionsOfSet + */ + public Integer getRepetitionsOfSet() { + return repetitionsOfSet; + } + + + /** + * @param repetitionsOfSet the repetitionsOfSet to set + */ + public void setRepetitionsOfSet(Integer repetitionsOfSet) { + this.repetitionsOfSet = repetitionsOfSet; + } + + + /** + * @return the repetitions + */ + public Integer getRepetitions() { + return repetitions; + } + + + /** + * @param repetitions the repetitions to set + */ + public void setRepetitions(Integer repetitions) { + this.repetitions = repetitions; + } + + + /** + * @return the factorOfFmax + */ + public Double getFactorOfFmax() { + return factorOfFmax; + } + + + /** + * @param factorOfFmax the factorOfFmax to set + */ + public void setFactorOfFmax(Double factorOfFmax) { + this.factorOfFmax = factorOfFmax; + } + + + /** + * @return the created + */ + public LocalDateTime getCreated() { + return created; + } + + + /** + * @param created the created to set + */ + public void setCreated(LocalDateTime created) { + this.created = created; + } + + + /** + * @return the validSince + */ + public LocalDateTime getValidSince() { + return validSince; + } + + + /** + * @param validSince the validSince to set + */ + public void setValidSince(LocalDateTime validSince) { + this.validSince = validSince; + } + + + /** + * @return the validUntil + */ + public LocalDateTime getValidUntil() { + return validUntil; + } + + + /** + * @param validUntil the validUntil to set + */ + public void setValidUntil(LocalDateTime validUntil) { + this.validUntil = validUntil; + } + + + /** + * @return the isActive + */ + public Boolean getIsActive() { + return isActive; + } + + + /** + * @param isActive the isActive to set + */ + public void setIsActive(Boolean isActive) { + this.isActive = isActive; + } + + + /** + * @return the goal + */ + public Goal getGoal() { + return goal; + } + + + /** + * @param goal the goal to set + */ + public void setGoal(Goal goal) { + this.goal = goal; + } + + + /** + * @return the athlet + */ + public Athlet getAthlet() { + return athlet; + } + + + /** + * @param athlet the athlet to set + */ + public void setAthlet(Athlet athlet) { + this.athlet = athlet; + } + + + /** + * @return the exercise + */ + public Exercise getExercise() { + return exercise; + } + + + /** + * @param exercise the exercise to set + */ + public void setExercise(Exercise exercise) { + this.exercise = exercise; + } + + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((athlet == null) ? 0 : athlet.hashCode()); + result = prime * result + ((created == null) ? 0 : created.hashCode()); + result = prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + ((exercise == null) ? 0 : exercise.hashCode()); + result = prime * result + ((factorOfFmax == null) ? 0 : factorOfFmax.hashCode()); + result = prime * result + ((goal == null) ? 0 : goal.hashCode()); + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((isActive == null) ? 0 : isActive.hashCode()); + result = prime * result + ((repetitions == null) ? 0 : repetitions.hashCode()); + result = prime * result + ((repetitionsOfSet == null) ? 0 : repetitionsOfSet.hashCode()); + result = prime * result + ((title == null) ? 0 : title.hashCode()); + result = prime * result + ((validSince == null) ? 0 : validSince.hashCode()); + result = prime * result + ((validUntil == null) ? 0 : validUntil.hashCode()); + return result; + } + + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Training other = (Training) obj; + if (athlet == null) { + if (other.athlet != null) + return false; + } else if (!athlet.equals(other.athlet)) + return false; + if (created == null) { + if (other.created != null) + return false; + } else if (!created.equals(other.created)) + return false; + if (description == null) { + if (other.description != null) + return false; + } else if (!description.equals(other.description)) + return false; + if (exercise == null) { + if (other.exercise != null) + return false; + } else if (!exercise.equals(other.exercise)) + return false; + if (factorOfFmax == null) { + if (other.factorOfFmax != null) + return false; + } else if (!factorOfFmax.equals(other.factorOfFmax)) + return false; + if (goal == null) { + if (other.goal != null) + return false; + } else if (!goal.equals(other.goal)) + return false; + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (isActive == null) { + if (other.isActive != null) + return false; + } else if (!isActive.equals(other.isActive)) + return false; + if (repetitions == null) { + if (other.repetitions != null) + return false; + } else if (!repetitions.equals(other.repetitions)) + return false; + if (repetitionsOfSet == null) { + if (other.repetitionsOfSet != null) + return false; + } else if (!repetitionsOfSet.equals(other.repetitionsOfSet)) + return false; + if (title == null) { + if (other.title != null) + return false; + } else if (!title.equals(other.title)) + return false; + if (validSince == null) { + if (other.validSince != null) + return false; + } else if (!validSince.equals(other.validSince)) + return false; + if (validUntil == null) { + if (other.validUntil != null) + return false; + } else if (!validUntil.equals(other.validUntil)) + return false; + return true; + } + + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Training [id="); + builder.append(id); + builder.append(", title="); + builder.append(title); + builder.append(", description="); + builder.append(description); + builder.append(", repetitionsOfSet="); + builder.append(repetitionsOfSet); + builder.append(", repetitions="); + builder.append(repetitions); + builder.append(", factorOfFmax="); + builder.append(factorOfFmax); + builder.append(", created="); + builder.append(created); + builder.append(", validSince="); + builder.append(validSince); + builder.append(", validUntil="); + builder.append(validUntil); + builder.append(", isActive="); + builder.append(isActive); + builder.append(", goal="); + builder.append(goal); + builder.append(", athlet="); + builder.append(athlet); + builder.append(", exercise="); + builder.append(exercise); + builder.append("]"); + return builder.toString(); + } + + +} diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/ViewAllExercises.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/ViewAllExercises.java new file mode 100644 index 0000000..e3a38e7 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/ViewAllExercises.java @@ -0,0 +1,26 @@ +package com.triathlon_coaching.product.athletik.backend.model; + +import java.math.BigDecimal; + +public interface ViewAllExercises { + Long getIdExercise(); + String getNameEnglish(); + String getDescriptionEnglish(); + String getNameGerman(); + String getDescriptionGerman(); + String getUrlVideo(); + Long getIdTool(); + String getToolnameEnglish(); + String getToolnameGerman(); + BigDecimal getMinWeight(); + BigDecimal getMaxWeight(); + BigDecimal getStepsWeight(); + String getDescription(); + Long getId(); + String getNameLatin(); + String getMuscleNameEnglish(); + String getMuscleNameGerman(); + String getMovementEnglish(); + String getMovementGerman(); + Long getFkMusclegroup(); +} diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/ViewMusclegroups.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/ViewMusclegroups.java new file mode 100644 index 0000000..9502d41 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/ViewMusclegroups.java @@ -0,0 +1,7 @@ +package com.triathlon_coaching.product.athletik.backend.model; + +public interface ViewMusclegroups { + Long getId(); + String getNameEnglish(); + String getNameGerman(); +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/ViewMuscles.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/ViewMuscles.java new file mode 100644 index 0000000..0f95df5 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/ViewMuscles.java @@ -0,0 +1,11 @@ +package com.triathlon_coaching.product.athletik.backend.model; + +public interface ViewMuscles { + Long getId(); + String getNameLatin(); + String getNameEnglish(); + String getNameGerman(); + String getMovementEnglish(); + String getMovementGerman(); + Long getFkMusclegroup(); +} diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/ViewProtokollSetsOfToday.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/ViewProtokollSetsOfToday.java new file mode 100644 index 0000000..3f66e54 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/ViewProtokollSetsOfToday.java @@ -0,0 +1,10 @@ +package com.triathlon_coaching.product.athletik.backend.model; + +import java.time.LocalDateTime; + +public interface ViewProtokollSetsOfToday { + Long getFkUser(); + Long getFkExercise(); + LocalDateTime getTrainingdate(); + Integer getNumberOfSet(); +} diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/ViewTools.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/ViewTools.java new file mode 100644 index 0000000..706bd15 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/ViewTools.java @@ -0,0 +1,13 @@ +package com.triathlon_coaching.product.athletik.backend.model; + +import java.math.BigDecimal; + +public interface ViewTools { + Long getId(); + String getToolnameEnglish(); + String getToolnameGerman(); + BigDecimal getMinWeight(); + BigDecimal getStepsWeight(); + BigDecimal getMaxWeight(); + String getDescription(); +} diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/ViewToolweights.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/ViewToolweights.java new file mode 100644 index 0000000..6b03299 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/ViewToolweights.java @@ -0,0 +1,10 @@ +package com.triathlon_coaching.product.athletik.backend.model; + +import java.math.BigDecimal; + +public interface ViewToolweights { + Long getId(); + BigDecimal getMinWeight(); + BigDecimal getStepsWeight(); + BigDecimal getMaxWeight(); +} diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/ViewUsers.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/ViewUsers.java new file mode 100644 index 0000000..e249319 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/model/ViewUsers.java @@ -0,0 +1,9 @@ +package com.triathlon_coaching.product.athletik.backend.model; + +public interface ViewUsers { + Long getId(); + String getUsername(); + String getNameUser(); + String getEmail(); + String getPass(); +} diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/AthletRepository.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/AthletRepository.java new file mode 100644 index 0000000..3302dcb --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/AthletRepository.java @@ -0,0 +1,44 @@ +package com.triathlon_coaching.product.athletik.backend.repo; + +import com.triathlon_coaching.product.athletik.backend.model.Athlet; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.util.Optional; + +@Repository +public interface AthletRepository extends JpaRepository { + + Optional findByUsername(String username); + + Optional findByEmail(String email); + + Boolean existsByUsername(String username); + + Boolean existsByEmail(String email); + + @Query("SELECT a FROM Athlet a JOIN a.gyms g WHERE g.id = :gymId") + java.util.List findByGymId(@Param("gymId") Long gymId); + + java.util.List findByIsActive(Boolean isActive); + + java.util.List findByFullnameContainingIgnoreCase(String name); + + @Query("SELECT a FROM Athlet a WHERE a.lastLogin < :date") + java.util.List findInactiveSince(@Param("date") LocalDateTime date); + + @Transactional + @Modifying + @Query("UPDATE Athlet a SET a.lastLogin = :lastLogin WHERE a.id = :id") + void updateLastLogin(@Param("id") Long id, @Param("lastLogin") LocalDateTime lastLogin); + + @Transactional + @Modifying + @Query("UPDATE Athlet a SET a.isActive = :isActive WHERE a.id = :id") + void updateActiveStatus(@Param("id") Long id, @Param("isActive") Boolean isActive); +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/ExerciseRepository.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/ExerciseRepository.java new file mode 100644 index 0000000..2b5daa7 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/ExerciseRepository.java @@ -0,0 +1,18 @@ +package com.triathlon_coaching.product.athletik.backend.repo; + +import com.triathlon_coaching.product.athletik.backend.model.Exercise; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface ExerciseRepository extends JpaRepository { + @Query("SELECT e FROM Exercise e JOIN e.muscles m WHERE m.musclegroupNameEnglish = :muscleGroup") + List findByMuscleGroup(@Param("muscleGroup") String muscleGroup); + + @Query("SELECT e FROM Exercise e JOIN e.muscles m WHERE m.id = :muscleId") + List findByMuscleId(@Param("muscleId") Long muscleId); +} diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/GoalRepository.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/GoalRepository.java new file mode 100644 index 0000000..aaa4803 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/GoalRepository.java @@ -0,0 +1,29 @@ +package com.triathlon_coaching.product.athletik.backend.repo; + +import com.triathlon_coaching.product.athletik.backend.model.Goal; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Optional; + +@Repository +public interface GoalRepository extends JpaRepository { + + Optional findByGoalname(String goalname); + + List findByGoalnameContainingIgnoreCase(String goalname); + + List findByDescriptionContainingIgnoreCase(String description); + + @Query("SELECT g FROM Goal g JOIN g.trainings t WHERE t.athlet.id = :athletId") + List findByAthletId(@Param("athletId") Long athletId); + + @Query("SELECT g FROM Goal g JOIN g.trainings t WHERE t.exercise.id = :exerciseId") + List findByExerciseId(@Param("exerciseId") Long exerciseId); + + @Query("SELECT DISTINCT g FROM Goal g WHERE g.id NOT IN (SELECT t.goal.id FROM Training t WHERE t.athlet.id = :athletId)") + List findAvailableForAthlet(@Param("athletId") Long athletId); +} diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/GymRepository.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/GymRepository.java new file mode 100644 index 0000000..2143a5f --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/GymRepository.java @@ -0,0 +1,21 @@ +package com.triathlon_coaching.product.athletik.backend.repo; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import com.triathlon_coaching.product.athletik.backend.model.Gym; + +@Repository +public interface GymRepository extends JpaRepository { + + @Query("SELECT g FROM Gym g JOIN g.athleten a WHERE a.id = :athletId") + List findByAthletenId(@Param("athletId") Long athletId); + + List findByGymnameContainingIgnoreCase(String name); + + List findByGymlocationContainingIgnoreCase(String location); +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/LogRepository.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/LogRepository.java new file mode 100644 index 0000000..b83465e --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/LogRepository.java @@ -0,0 +1,58 @@ +package com.triathlon_coaching.product.athletik.backend.repo; + +import com.triathlon_coaching.product.athletik.backend.model.Log; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import java.time.LocalDateTime; +import java.util.List; + +@Repository +public interface LogRepository extends JpaRepository { + + List findByAthletIdOrderByCreatedDesc(Long athletId); + + Page findByAthletIdOrderByCreatedDesc(Long athletId, Pageable pageable); + + List findBySid(String sid); + + List findByScriptContainingIgnoreCase(String script); + + List findByLogLevel(String logLevel); + + List findByLogdataContainingIgnoreCase(String logdata); + + List findByCreatedBetween(LocalDateTime start, LocalDateTime end); + + List findByCreatedBefore(LocalDateTime date); + + @Query("SELECT l FROM Log l WHERE l.athlet.id = :athletId AND l.created BETWEEN :start AND :end ORDER BY l.created DESC") + List findByAthletIdAndCreatedBetween(@Param("athletId") Long athletId, + @Param("start") LocalDateTime start, + @Param("end") LocalDateTime end); + + @Query("SELECT l FROM Log l WHERE l.athlet.id = :athletId AND l.logLevel = :logLevel ORDER BY l.created DESC") + List findByAthletIdAndLogLevel(@Param("athletId") Long athletId, + @Param("logLevel") String logLevel); + + @Query("SELECT l FROM Log l WHERE l.athlet.id = :athletId AND LOWER(l.logdata) LIKE LOWER(CONCAT('%', :searchTerm, '%')) ORDER BY l.created DESC") + List findByAthletIdAndLogdataContaining(@Param("athletId") Long athletId, + @Param("searchTerm") String searchTerm); + + @Query("SELECT COUNT(l) FROM Log l WHERE l.athlet.id = :athletId AND l.created >= :since") + Long countByAthletIdSince(@Param("athletId") Long athletId, + @Param("since") LocalDateTime since); + + @Query("SELECT DISTINCT l.script FROM Log l WHERE l.athlet.id = :athletId") + List findDistinctScriptsByAthletId(@Param("athletId") Long athletId); + + @Query("SELECT DISTINCT l.logLevel FROM Log l WHERE l.athlet.id = :athletId") + List findDistinctLogLevelsByAthletId(@Param("athletId") Long athletId); + + @Query("SELECT l FROM Log l WHERE l.athlet.id = :athletId AND l.created = (SELECT MAX(l2.created) FROM Log l2 WHERE l2.athlet.id = :athletId)") + Log findLatestByAthletId(@Param("athletId") Long athletId); +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/MuscleRepository.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/MuscleRepository.java new file mode 100644 index 0000000..c6ffa3f --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/MuscleRepository.java @@ -0,0 +1,34 @@ +package com.triathlon_coaching.product.athletik.backend.repo; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import com.triathlon_coaching.product.athletik.backend.model.Muscle; + +@Repository +public interface MuscleRepository extends JpaRepository { + + @Query("SELECT DISTINCT m.musclegroupNameEnglish FROM Muscle m WHERE m.musclegroupNameEnglish IS NOT NULL") + List findAllMuscleGroups(); + + @Query("SELECT m FROM Muscle m WHERE m.musclegroupNameEnglish = :group OR m.musclegroupNameGerman = :group") + List findByMuscleGroup(@Param("group") String group); + + @Query("SELECT m FROM Muscle m JOIN m.exercises e WHERE e.id = :exerciseId") + List findByExercisesId(@Param("exerciseId") Long exerciseId); + + List findByMuscleNameLatinContainingIgnoreCase(String name); + + List findByMuscleNameEnglishContainingIgnoreCase(String name); + + List findByMuscleNameGermanContainingIgnoreCase(String name); + + @Query("SELECT m FROM Muscle m WHERE LOWER(m.movementEnglish) LIKE LOWER(CONCAT('%', :movement, '%')) OR LOWER(m.movementGerman) LIKE LOWER(CONCAT('%', :movement, '%'))") + List findByMovementContainingIgnoreCase(@Param("movement") String movement); + + List findByMusclegroupNameEnglishOrMusclegroupNameGerman(String muscleGroup, String muscleGroup2); +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/ProtokollRepository.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/ProtokollRepository.java new file mode 100644 index 0000000..74a58fd --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/ProtokollRepository.java @@ -0,0 +1,55 @@ +package com.triathlon_coaching.product.athletik.backend.repo; + +import com.triathlon_coaching.product.athletik.backend.model.Protokoll; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import java.time.LocalDateTime; +import java.util.List; + +@Repository +public interface ProtokollRepository extends JpaRepository { + + List findByAthletIdOrderByTrainingDateDesc(Long athletId); + + List findByAthletIdAndExerciseIdOrderByTrainingDateDesc(Long athletId, Long exerciseId); + + List findByAthletIdAndTrainingDateBetween(Long athletId, LocalDateTime start, LocalDateTime end); + + List findByAthletIdAndIsTest(Long athletId, Boolean isTest); + + List findByAthletIdAndExerciseIdAndIsTest(Long athletId, Long exerciseId, Boolean isTest); + + @Query("SELECT p FROM Protokoll p WHERE p.athlet.id = :athletId AND DATE(p.trainingDate) = CURRENT_DATE") + List findTodaySessionsByAthletId(@Param("athletId") Long athletId); + + @Query("SELECT MAX(p.numberOfSet) FROM Protokoll p WHERE p.athlet.id = :athletId AND p.exercise.id = :exerciseId AND DATE(p.trainingDate) = CURRENT_DATE") + Integer findMaxSetNumberForToday(@Param("athletId") Long athletId, @Param("exerciseId") Long exerciseId); + + @Query("SELECT p FROM Protokoll p WHERE p.athlet.id = :athletId AND p.exercise.id = :exerciseId AND p.isTest = true ORDER BY p.trainingDate DESC") + List findLatestTestsByAthletAndExercise(@Param("athletId") Long athletId, @Param("exerciseId") Long exerciseId); + + @Query("SELECT p FROM Protokoll p WHERE p.athlet.id = :athletId AND p.exercise.id = :exerciseId AND p.isTest = false ORDER BY p.trainingDate DESC") + List findLatestTrainingsByAthletAndExercise(@Param("athletId") Long athletId, @Param("exerciseId") Long exerciseId); + + @Query("SELECT p FROM Protokoll p WHERE p.athlet.id = :athletId AND p.trainingDate = (SELECT MAX(p2.trainingDate) FROM Protokoll p2 WHERE p2.athlet.id = :athletId AND p2.exercise.id = p.exercise.id AND p2.isTest = true)") + List findLatestTestForEachExercise(@Param("athletId") Long athletId); + + @Query("SELECT p FROM Protokoll p WHERE p.athlet.id = :athletId AND p.exercise.id = :exerciseId ORDER BY p.trainingDate DESC, p.numberOfSet DESC") + Page findByAthletIdAndExerciseIdPaged(@Param("athletId") Long athletId, @Param("exerciseId") Long exerciseId, Pageable pageable); + + @Query("SELECT SUM(p.volume) FROM Protokoll p WHERE p.athlet.id = :athletId AND p.trainingDate BETWEEN :start AND :end") + Double findTotalVolumeByAthletIdAndDateRange(@Param("athletId") Long athletId, @Param("start") LocalDateTime start, @Param("end") LocalDateTime end); + + @Query("SELECT p FROM Protokoll p WHERE p.athlet.id = :athletId AND p.weight >= :minWeight") + List findByAthletIdAndMinWeight(@Param("athletId") Long athletId, @Param("minWeight") Double minWeight); + + @Query("SELECT p FROM Protokoll p WHERE p.athlet.id = :athletId AND p.oneRepMax IS NOT NULL ORDER BY p.oneRepMax DESC") + List findPersonalRecords(@Param("athletId") Long athletId); + + Long countByAthletIdAndTrainingDateAfter(Long athletId, LocalDateTime date); +} diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/ToolRepository.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/ToolRepository.java new file mode 100644 index 0000000..28d4e2f --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/ToolRepository.java @@ -0,0 +1,37 @@ +package com.triathlon_coaching.product.athletik.backend.repo; + +import com.triathlon_coaching.product.athletik.backend.model.Tool; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + + +import com.triathlon_coaching.product.athletik.backend.model.Tool; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface ToolRepository extends JpaRepository { + + @Query("SELECT t FROM Tool t JOIN t.gyms g WHERE g.id = :gymId") + List findByGymsId(@Param("gymId") Long gymId); + + List findByToolnameEnglishContainingIgnoreCase(String name); + + List findByToolnameGermanContainingIgnoreCase(String name); + + @Query("SELECT t FROM Tool t WHERE t.minWeight <= :weight AND t.maxWeight >= :weight") + List findByWeightRange(@Param("weight") Double weight); + + @Query("SELECT t FROM Tool t WHERE t.minWeight <= :weight AND t.maxWeight >= :weight AND :weight % t.stepsWeight = 0") + List findByWeightAndStep(@Param("weight") Double weight); + + List findByMinWeightGreaterThanEqual(Double minWeight); + + List findByMaxWeightLessThanEqual(Double maxWeight); + + List findByMinWeightLessThanEqualAndMaxWeightGreaterThanEqual(Double minWeight, Double maxWeight); +} diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/TrainingRepository.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/TrainingRepository.java new file mode 100644 index 0000000..3d352ef --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/repo/TrainingRepository.java @@ -0,0 +1,43 @@ +package com.triathlon_coaching.product.athletik.backend.repo; + +import com.triathlon_coaching.product.athletik.backend.model.Training; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; + +@Repository +public interface TrainingRepository extends JpaRepository { + + List findByAthletIdOrderByCreatedDesc(Long athletId); + + List findByAthletIdAndIsActiveTrue(Long athletId); + + List findByExerciseId(Long exerciseId); + + List findByGoalId(Long goalId); + + @Query("SELECT t FROM Training t WHERE t.athlet.id = :athletId AND t.isActive = true AND " + + "(t.validSince IS NULL OR t.validSince <= :now) AND " + + "(t.validUntil IS NULL OR t.validUntil >= :now)") + List findActiveByAthletId(@Param("athletId") Long athletId, @Param("now") LocalDateTime now); + + @Query("SELECT t FROM Training t WHERE t.athlet.id = :athletId AND t.exercise.id = :exerciseId AND t.isActive = true") + List findByAthletIdAndExerciseId(@Param("athletId") Long athletId, @Param("exerciseId") Long exerciseId); + + @Query("SELECT t FROM Training t WHERE t.athlet.id = :athletId AND t.goal.id = :goalId AND t.isActive = true") + List findByAthletIdAndGoalId(@Param("athletId") Long athletId, @Param("goalId") Long goalId); + + @Query("SELECT t FROM Training t WHERE t.created BETWEEN :start AND :end") + List findByCreatedBetween(@Param("start") LocalDateTime start, @Param("end") LocalDateTime end); + + @Query("SELECT t FROM Training t WHERE t.validSince <= :date AND (t.validUntil IS NULL OR t.validUntil >= :date)") + List findValidAt(@Param("date") LocalDateTime date); + + Optional findByAthletIdAndExerciseIdAndRepetitionsOfSetAndRepetitionsAndFactorOfFmax( + Long athletId, Long exerciseId, Integer repetitionsOfSet, Integer repetitions, Double factorOfFmax); +} diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/AthletService.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/AthletService.java new file mode 100644 index 0000000..97d1c3e --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/AthletService.java @@ -0,0 +1,120 @@ +package com.triathlon_coaching.product.athletik.backend.service; + +import com.triathlon_coaching.product.athletik.backend.model.Athlet; +import com.triathlon_coaching.product.athletik.backend.repo.AthletRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; + +@Service +public class AthletService { + + @Autowired + private AthletRepository athletRepository; + + @Autowired + private PasswordEncoder passwordEncoder; + + @Autowired + private EmailService emailService; + + public List findAllAthleten() { + return athletRepository.findAll(); + } + + public Optional findAthletById(Long id) { + return athletRepository.findById(id); + } + + public Optional findAthletByUsername(String username) { + return athletRepository.findByUsername(username); + } + + public Optional findAthletByEmail(String email) { + return athletRepository.findByEmail(email); + } + + public List findAthletenByGymId(Long gymId) { + return athletRepository.findByGymId(gymId); + } + + public boolean existsByUsername(String username) { + return athletRepository.existsByUsername(username); + } + + public boolean existsByEmail(String email) { + return athletRepository.existsByEmail(email); + } + + public Athlet saveAthlet(Athlet athlet) { + return athletRepository.save(athlet); + } + + @Transactional + public Athlet registerAthlet(Athlet athlet) { + // Passwort hashen + athlet.setPass(passwordEncoder.encode(athlet.getPass())); + Athlet savedAthlet = athletRepository.save(athlet); + + // Willkommens-E-Mail senden + emailService.sendWelcomeEmail(savedAthlet); + + return savedAthlet; + } + + public Optional authenticate(String username, String password) { + Optional athletOptional = athletRepository.findByUsername(username); + if (athletOptional.isPresent()) { + Athlet athlet = athletOptional.get(); + if (passwordEncoder.matches(password, athlet.getPass())) { + // Last Login aktualisieren + athlet.setLastLogin(LocalDateTime.now()); + athletRepository.save(athlet); + return Optional.of(athlet); + } + } + return Optional.empty(); + } + + @Transactional + public boolean updatePassword(Long id, String currentPassword, String newPassword) { + Optional athletOptional = athletRepository.findById(id); + if (athletOptional.isPresent()) { + Athlet athlet = athletOptional.get(); + if (passwordEncoder.matches(currentPassword, athlet.getPass())) { + athlet.setPass(passwordEncoder.encode(newPassword)); + athletRepository.save(athlet); + return true; + } + } + return false; + } + + public void deleteAthlet(Long id) { + athletRepository.deleteById(id); + } + + @Transactional + public void deactivateAthlet(Long id) { + athletRepository.updateActiveStatus(id, false); + } + + @Transactional + public void activateAthlet(Long id) { + athletRepository.updateActiveStatus(id, true); + } + + @Transactional + public void updateLastLogin(Long id) { + athletRepository.updateLastLogin(id, LocalDateTime.now()); + } + + public List findInactiveAthletenSince(LocalDateTime date) { + return athletRepository.findInactiveSince(date); + } +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/EmailService.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/EmailService.java new file mode 100644 index 0000000..e7b3efb --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/EmailService.java @@ -0,0 +1,119 @@ +package com.triathlon_coaching.product.athletik.backend.service; + +import com.triathlon_coaching.product.athletik.backend.model.Athlet; +import com.triathlon_coaching.product.athletik.backend.model.Protokoll; +import com.triathlon_coaching.product.athletik.backend.repo.AthletRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.mail.javamail.MimeMessageHelper; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import org.thymeleaf.TemplateEngine; +import org.thymeleaf.context.Context; + +import javax.mail.MessagingException; +import javax.mail.internet.MimeMessage; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.Locale; +import java.util.Optional; + +@Service +public class EmailService { + + @Autowired + private JavaMailSender mailSender; + + @Autowired + private TemplateEngine templateEngine; + + @Autowired + private AthletRepository athletRepository; + + @Async + public void sendTrainingSummary(Long athletId, List trainingData) { + Optional athletOptional = athletRepository.findById(athletId); + if (!athletOptional.isPresent()) { + return; + } + + Athlet athlet = athletOptional.get(); + String emailContent = generateTrainingSummaryEmail(athlet, trainingData); + + try { + MimeMessage message = mailSender.createMimeMessage(); + MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8"); + + helper.setTo(athlet.getEmail()); + helper.setSubject("Ihr Training vom " + LocalDate.now().format(DateTimeFormatter.ofPattern("dd.MM.yyyy"))); + helper.setText(emailContent, true); + + mailSender.send(message); + } catch (MessagingException e) { + // Logging des Fehlers + System.err.println("Fehler beim Senden der E-Mail: " + e.getMessage()); + } + } + + private String generateTrainingSummaryEmail(Athlet athlet, List trainingData) { + Context context = new Context(Locale.GERMAN); + context.setVariable("athlet", athlet); + context.setVariable("trainingData", trainingData); + context.setVariable("trainingDate", LocalDate.now()); + // context.setVariable("totalVolume", calculateTotalVolume(trainingData)); + context.setVariable("totalSets", trainingData.size()); + + return templateEngine.process("email/training-summary", context); + } + + /* + private double calculateTotalVolume(List trainingData) { + return trainingData.stream() + .mapToDouble(p -> p.getWeight() * p.getRepetitions()) + .sum(); + } + */ + @Async + public void sendWelcomeEmail(Athlet athlet) { + Context context = new Context(Locale.GERMAN); + context.setVariable("athlet", athlet); + + String emailContent = templateEngine.process("email/welcome", context); + + try { + MimeMessage message = mailSender.createMimeMessage(); + MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8"); + + helper.setTo(athlet.getEmail()); + helper.setSubject("Willkommen bei Athletik Training!"); + helper.setText(emailContent, true); + + mailSender.send(message); + } catch (MessagingException e) { + System.err.println("Fehler beim Senden der Willkommens-E-Mail: " + e.getMessage()); + } + } + + @Async + public void sendPasswordResetEmail(Athlet athlet, String resetToken) { + Context context = new Context(Locale.GERMAN); + context.setVariable("athlet", athlet); + context.setVariable("resetToken", resetToken); + + String emailContent = templateEngine.process("email/password-reset", context); + + try { + MimeMessage message = mailSender.createMimeMessage(); + MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8"); + + helper.setTo(athlet.getEmail()); + helper.setSubject("Passwort zurücksetzen - Athletik Training"); + helper.setText(emailContent, true); + + mailSender.send(message); + } catch (MessagingException e) { + System.err.println("Fehler beim Senden der Passwort-Reset-E-Mail: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/ExerciseService.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/ExerciseService.java new file mode 100644 index 0000000..e55389e --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/ExerciseService.java @@ -0,0 +1,89 @@ +package com.triathlon_coaching.product.athletik.backend.service; + +import com.triathlon_coaching.product.athletik.backend.model.Exercise; +import com.triathlon_coaching.product.athletik.backend.model.Muscle; +import com.triathlon_coaching.product.athletik.backend.repo.ExerciseRepository; +import com.triathlon_coaching.product.athletik.backend.repo.MuscleRepository; +import com.triathlon_coaching.product.athletik.backend.repo.ToolRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.stream.Collectors; + +@Service +public class ExerciseService { + + @Autowired + private ExerciseRepository exerciseRepository; + + @Autowired + private MuscleRepository muscleRepository; + + @Autowired + private ToolRepository toolRepository; + + public List findAllExercises() { + return exerciseRepository.findAll(); + } + + public Optional findExerciseById(Long id) { + return exerciseRepository.findById(id); + } + + public List findExercisesByMuscleGroup(String muscleGroup) { + return exerciseRepository.findByMuscleGroup(muscleGroup); + } + + public List findExercisesByMuscleId(Long muscleId) { + return exerciseRepository.findByMuscleId(muscleId); + } + + public List findAllMuscleGroups() { + return muscleRepository.findAllMuscleGroups(); + } + + public List findAllMuscles() { + return muscleRepository.findAll(); + } + + public List findMusclesByGroup(String muscleGroup) { + return muscleRepository.findByMusclegroupNameEnglishOrMusclegroupNameGerman(muscleGroup, muscleGroup); + } + + public List getWeightsForTool(Long toolId) { + return toolRepository.findById(toolId) + .map(tool -> { + List weights = new ArrayList<>(); + double current = tool.getMinWeight(); + while (current <= tool.getMaxWeight()) { + weights.add(current); + current += tool.getStepsWeight(); + } + return weights; + }) + .orElse(Collections.emptyList()); + } + + public Map getExerciseSummary() { + Map summary = new HashMap<>(); + + List muscleGroups = findAllMuscleGroups(); + summary.put("muscleGroups", muscleGroups); + + Map> musclesByGroup = new HashMap<>(); + for (String group : muscleGroups) { + musclesByGroup.put(group, findMusclesByGroup(group)); + } + summary.put("musclesByGroup", musclesByGroup); + + Map> exercisesByMuscle = new HashMap<>(); + List allMuscles = findAllMuscles(); + for (Muscle muscle : allMuscles) { + exercisesByMuscle.put(muscle.getId(), findExercisesByMuscleId(muscle.getId())); + } + summary.put("exercisesByMuscle", exercisesByMuscle); + + return summary; + } +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/GoalService.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/GoalService.java new file mode 100644 index 0000000..3b30d93 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/GoalService.java @@ -0,0 +1,64 @@ +package com.triathlon_coaching.product.athletik.backend.service; + +import com.triathlon_coaching.product.athletik.backend.model.Goal; +import com.triathlon_coaching.product.athletik.backend.repo.GoalRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +@Service +public class GoalService { + + @Autowired + private GoalRepository goalRepository; + + public List findAllGoals() { + return goalRepository.findAll(); + } + + public Optional findGoalById(Long id) { + return goalRepository.findById(id); + } + + public Optional findGoalByName(String goalname) { + return goalRepository.findByGoalname(goalname); + } + + public List findGoalsByAthletId(Long athletId) { + return goalRepository.findByAthletId(athletId); + } + + public List findGoalsByExerciseId(Long exerciseId) { + return goalRepository.findByExerciseId(exerciseId); + } + + public List findAvailableGoalsForAthlet(Long athletId) { + return goalRepository.findAvailableForAthlet(athletId); + } + + public List searchGoals(String searchTerm) { + List byName = goalRepository.findByGoalnameContainingIgnoreCase(searchTerm); + List byDescription = goalRepository.findByDescriptionContainingIgnoreCase(searchTerm); + + // Duplikate entfernen und kombinieren + byName.addAll(byDescription.stream() + .filter(goal -> !byName.contains(goal)) + .toList()); + + return byName; + } + + public Goal saveGoal(Goal goal) { + return goalRepository.save(goal); + } + + public void deleteGoal(Long id) { + goalRepository.deleteById(id); + } + + public boolean existsByName(String goalname) { + return goalRepository.findByGoalname(goalname).isPresent(); + } +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/GymService.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/GymService.java new file mode 100644 index 0000000..f5c12aa --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/GymService.java @@ -0,0 +1,37 @@ +package com.triathlon_coaching.product.athletik.backend.service; + +import java.util.List; +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.triathlon_coaching.product.athletik.backend.model.Gym; +import com.triathlon_coaching.product.athletik.backend.repo.GymRepository; + +@Service +public class GymService { + + @Autowired + private GymRepository gymRepository; + + public List findAllGyms() { + return gymRepository.findAll(); + } + + public Optional findGymById(Long id) { + return gymRepository.findById(id); + } + + public List findGymsByAthletId(Long athletId) { + return gymRepository.findByAthletenId(athletId); + } + + public Gym saveGym(Gym gym) { + return gymRepository.save(gym); + } + + public void deleteGym(Long id) { + gymRepository.deleteById(id); + } +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/LogService.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/LogService.java new file mode 100644 index 0000000..c8be356 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/LogService.java @@ -0,0 +1,132 @@ +package com.triathlon_coaching.product.athletik.backend.service; + +import java.time.LocalDateTime; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import com.triathlon_coaching.product.athletik.backend.model.Log; +import com.triathlon_coaching.product.athletik.backend.repo.LogRepository; + +@Service +public class LogService { + + @Autowired + private LogRepository logRepository; + + @Autowired + private AthletService athletService; + + public List findAllLogs() { + return logRepository.findAll(); + } + + public List findByAthletId(Long athletId) { + return logRepository.findByAthletIdOrderByCreatedDesc(athletId); + } + + public Page findByAthletId(Long athletId, Pageable pageable) { + return logRepository.findByAthletIdOrderByCreatedDesc(athletId, pageable); + } + + public List findByAthletIdAndDateRange(Long athletId, LocalDateTime start, LocalDateTime end) { + return logRepository.findByAthletIdAndCreatedBetween(athletId, start, end); + } + + public List findByAthletIdAndLogLevel(Long athletId, String logLevel) { + return logRepository.findByAthletIdAndLogLevel(athletId, logLevel); + } + + public List searchByAthletIdAndLogdata(Long athletId, String searchTerm) { + return logRepository.findByAthletIdAndLogdataContaining(athletId, searchTerm); + } + + public Log saveLog(Log log) { + return logRepository.save(log); + } + + public void deleteLog(Long id) { + logRepository.deleteById(id); + } + + public void deleteOldLogs(LocalDateTime before) { + List oldLogs = logRepository.findByCreatedBefore(before); + logRepository.deleteAll(oldLogs); + } + + // Hilfsmethoden für das Logging + public void logInfo(Long athletId, String logdata, String script, HttpServletRequest request) { + createLog(athletId, logdata, "INFO", script, request); + } + + public void logWarning(Long athletId, String logdata, String script, HttpServletRequest request) { + createLog(athletId, logdata, "WARNING", script, request); + } + + public void logError(Long athletId, String logdata, String script, HttpServletRequest request) { + createLog(athletId, logdata, "ERROR", script, request); + } + + public void logDebug(Long athletId, String logdata, String script, HttpServletRequest request) { + createLog(athletId, logdata, "DEBUG", script, request); + } + + private void createLog(Long athletId, String logdata, String logLevel, String script, HttpServletRequest request) { + athletService.findAthletById(athletId).ifPresent(athlet -> { + Log log = new Log(); + log.setLogdata(logdata); + log.setLogLevel(logLevel); + log.setScript(script); + log.setAthlet(athlet); + + if (request != null) { + log.setSid(request.getSession().getId()); + log.setIpAddress(getClientIpAddress(request)); + log.setUserAgent(request.getHeader("User-Agent")); + } + + logRepository.save(log); + }); + } + + private String getClientIpAddress(HttpServletRequest request) { + String ip = request.getHeader("X-Forwarded-For"); + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_CLIENT_IP"); + } + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_X_FORWARDED_FOR"); + } + if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + return ip; + } + + public Long getLogCountSince(Long athletId, LocalDateTime since) { + return logRepository.countByAthletIdSince(athletId, since); + } + + public List getDistinctScripts(Long athletId) { + return logRepository.findDistinctScriptsByAthletId(athletId); + } + + public List getDistinctLogLevels(Long athletId) { + return logRepository.findDistinctLogLevelsByAthletId(athletId); + } + + public Log getLatestLog(Long athletId) { + return logRepository.findLatestByAthletId(athletId); + } +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/MuscleService.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/MuscleService.java new file mode 100644 index 0000000..274e969 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/MuscleService.java @@ -0,0 +1,50 @@ +package com.triathlon_coaching.product.athletik.backend.service; + +import com.triathlon_coaching.product.athletik.backend.model.Muscle; +import com.triathlon_coaching.product.athletik.backend.repo.MuscleRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +@Service +public class MuscleService { + + @Autowired + private MuscleRepository muscleRepository; + + public List findAllMuscles() { + return muscleRepository.findAll(); + } + + public Optional findMuscleById(Long id) { + return muscleRepository.findById(id); + } + + public List findMusclesByGroup(String muscleGroup) { + return muscleRepository.findByMuscleGroup(muscleGroup); + } + + public List findAllMuscleGroups() { + return muscleRepository.findAllMuscleGroups(); + } + + public List findMusclesByExerciseId(Long exerciseId) { + return muscleRepository.findByExercisesId(exerciseId); + } + + public List findPrimaryMusclesByExerciseId(Long exerciseId) { + // Hier müsste die Logik für isprimary implementiert werden + // Vereinfacht geben wir alle Muskeln der Übung zurück + return muscleRepository.findByExercisesId(exerciseId); + } + + public Muscle saveMuscle(Muscle muscle) { + return muscleRepository.save(muscle); + } + + public void deleteMuscle(Long id) { + muscleRepository.deleteById(id); + } +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/ProtokollService.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/ProtokollService.java new file mode 100644 index 0000000..b66fce1 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/ProtokollService.java @@ -0,0 +1,111 @@ +package com.triathlon_coaching.product.athletik.backend.service; + +import com.triathlon_coaching.product.athletik.backend.model.Protokoll; +import com.triathlon_coaching.product.athletik.backend.repo.ProtokollRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; + +@Service +public class ProtokollService { + + @Autowired + private ProtokollRepository protokollRepository; + + @Autowired + private EmailService emailService; + + public List findAllProtokolls() { + return protokollRepository.findAll(); + } + + public Optional findProtokollById(Long id) { + return protokollRepository.findById(id); + } + + public List findByAthletId(Long athletId) { + return protokollRepository.findByAthletIdOrderByTrainingDateDesc(athletId); + } + + public List findByAthletIdAndExerciseId(Long athletId, Long exerciseId) { + return protokollRepository.findByAthletIdAndExerciseIdOrderByTrainingDateDesc(athletId, exerciseId); + } + + public List findTodaySessionsByAthletId(Long athletId) { + return protokollRepository.findTodaySessionsByAthletId(athletId); + } + + public List findByAthletIdAndDateRange(Long athletId, LocalDateTime start, LocalDateTime end) { + return protokollRepository.findByAthletIdAndTrainingDateBetween(athletId, start, end); + } + + public List findTestsByAthletId(Long athletId) { + return protokollRepository.findByAthletIdAndIsTest(athletId, true); + } + + public List findTrainingsByAthletId(Long athletId) { + return protokollRepository.findByAthletIdAndIsTest(athletId, false); + } + + public List findLatestTestsByAthletAndExercise(Long athletId, Long exerciseId) { + return protokollRepository.findLatestTestsByAthletAndExercise(athletId, exerciseId); + } + + public List findLatestTestForEachExercise(Long athletId) { + return protokollRepository.findLatestTestForEachExercise(athletId); + } + + public Integer findMaxSetNumberForToday(Long athletId, Long exerciseId) { + Integer maxSet = protokollRepository.findMaxSetNumberForToday(athletId, exerciseId); + return maxSet != null ? maxSet : 0; + } + + public Protokoll saveProtokoll(Protokoll protokoll) { + return protokollRepository.save(protokoll); + } + + public void deleteProtokoll(Long id) { + protokollRepository.deleteById(id); + } + + public Double calculateTotalVolume(Long athletId, LocalDateTime start, LocalDateTime end) { + Double totalVolume = protokollRepository.findTotalVolumeByAthletIdAndDateRange(athletId, start, end); + return totalVolume != null ? totalVolume : 0.0; + } + + public Double calculateDailyVolume(Long athletId) { + LocalDateTime startOfDay = LocalDate.now().atStartOfDay(); + LocalDateTime endOfDay = startOfDay.plusDays(1); + return calculateTotalVolume(athletId, startOfDay, endOfDay); + } + + public Double calculateWeeklyVolume(Long athletId) { + LocalDateTime startOfWeek = LocalDateTime.now().minusDays(7); + LocalDateTime now = LocalDateTime.now(); + return calculateTotalVolume(athletId, startOfWeek, now); + } + + public List findPersonalRecords(Long athletId) { + return protokollRepository.findPersonalRecords(athletId); + } + + public Page findByAthletIdAndExerciseIdPaged(Long athletId, Long exerciseId, Pageable pageable) { + return protokollRepository.findByAthletIdAndExerciseIdPaged(athletId, exerciseId, pageable); + } + + public Long getTrainingCountSince(Long athletId, LocalDateTime since) { + return protokollRepository.countByAthletIdAndTrainingDateAfter(athletId, since); + } + + public void sendTrainingSummaryEmail(Long athletId) { + List todayTraining = findTodaySessionsByAthletId(athletId); + emailService.sendTrainingSummary(athletId, todayTraining); + } + +} diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/ToolService.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/ToolService.java new file mode 100644 index 0000000..e719f28 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/ToolService.java @@ -0,0 +1,48 @@ +package com.triathlon_coaching.product.athletik.backend.service; + +import com.triathlon_coaching.product.athletik.backend.model.Tool; +import com.triathlon_coaching.product.athletik.backend.repo.ToolRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +@Service +public class ToolService { + + @Autowired + private ToolRepository toolRepository; + + public List findAllTools() { + return toolRepository.findAll(); + } + + public Optional findToolById(Long id) { + return toolRepository.findById(id); + } + + public List findToolsByGymId(Long gymId) { + return toolRepository.findByGymsId(gymId); + } + + public List findByToolnameEnglishContainingIgnoreCase(String name) { + return toolRepository.findByToolnameEnglishContainingIgnoreCase(name); + } + + public List findByToolnameGermanContainingIgnoreCase(String name) { + return toolRepository.findByToolnameGermanContainingIgnoreCase(name); + } + + public Tool saveTool(Tool tool) { + return toolRepository.save(tool); + } + + public void deleteTool(Long id) { + toolRepository.deleteById(id); + } + + public boolean existsById(Long id) { + return toolRepository.existsById(id); + } +} diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/TrainingService.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/TrainingService.java new file mode 100644 index 0000000..879a856 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/service/TrainingService.java @@ -0,0 +1,94 @@ +package com.triathlon_coaching.product.athletik.backend.service; + +import com.triathlon_coaching.product.athletik.backend.model.Training; +import com.triathlon_coaching.product.athletik.backend.repo.TrainingRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; + +@Service +public class TrainingService { + + @Autowired + private TrainingRepository trainingRepository; + + public List findAllTrainings() { + return trainingRepository.findAll(); + } + + public Optional findTrainingById(Long id) { + return trainingRepository.findById(id); + } + + public List findTrainingsByAthletId(Long athletId) { + return trainingRepository.findByAthletIdOrderByCreatedDesc(athletId); + } + + public List findActiveTrainingsByAthletId(Long athletId) { + return trainingRepository.findByAthletIdAndIsActiveTrue(athletId); + } + + public List findCurrentlyValidTrainingsByAthletId(Long athletId) { + return trainingRepository.findActiveByAthletId(athletId, LocalDateTime.now()); + } + + public List findTrainingsByExerciseId(Long exerciseId) { + return trainingRepository.findByExerciseId(exerciseId); + } + + public List findTrainingsByGoalId(Long goalId) { + return trainingRepository.findByGoalId(goalId); + } + + public List findTrainingsByAthletIdAndExerciseId(Long athletId, Long exerciseId) { + return trainingRepository.findByAthletIdAndExerciseId(athletId, exerciseId); + } + + + public void deleteTraining(Long id) { + trainingRepository.deleteById(id); + } + + public void deactivateTraining(Long id) { + trainingRepository.findById(id).ifPresent(training -> { + training.setIsActive(false); + trainingRepository.save(training); + }); + } + + public void activateTraining(Long id) { + trainingRepository.findById(id).ifPresent(training -> { + training.setIsActive(true); + trainingRepository.save(training); + }); + } + + public boolean trainingExists(Long athletId, Long exerciseId, Integer repetitionsOfSet, + Integer repetitions, Double factorOfFmax) { + return trainingRepository + .findByAthletIdAndExerciseIdAndRepetitionsOfSetAndRepetitionsAndFactorOfFmax( + athletId, exerciseId, repetitionsOfSet, repetitions, factorOfFmax) + .isPresent(); + } + + public List findTrainingsCreatedBetween(LocalDateTime start, LocalDateTime end) { + return trainingRepository.findByCreatedBetween(start, end); + } + + public List findValidTrainingsAt(LocalDateTime date) { + return trainingRepository.findValidAt(date); + } + + public void sendTrainingSummaryEmail(Long id) { + // TODO Auto-generated method stub + + } + + public double calculateOneRepMax(double weight, int repetitions) { + // TODO Auto-generated method stub + return 0; + } +} \ No newline at end of file diff --git a/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/util/AthletikConstants.java b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/util/AthletikConstants.java new file mode 100644 index 0000000..33a66c1 --- /dev/null +++ b/athletik-service/src/main/java/com/triathlon_coaching/product/athletik/backend/util/AthletikConstants.java @@ -0,0 +1,7 @@ +package com.triathlon_coaching.product.athletik.backend.util; + +public class AthletikConstants { + + public static final String NOREPLYEMAIL = "noreply@triathlon-coaching.com"; + +} diff --git a/athletik-service/src/main/resources/application.yaml b/athletik-service/src/main/resources/application.yaml new file mode 100644 index 0000000..d963823 --- /dev/null +++ b/athletik-service/src/main/resources/application.yaml @@ -0,0 +1,55 @@ + +spring: + datasource: + url: jdbc:postgresql://localhost:5432/sport +# username: laktatnebel +# password: njThR3G&c9?B7ZpQ + username: oleb + password: wpj_9+L6ukX+SN2- + driver-class-name: org.postgresql.Driver + jpa: + hibernate: + ddl-auto: validate + properties: + hibernate: + dialect: org.hibernate.dialect.PostgreSQLDialect + default_schema: athletik + show_sql: true + format_sql: true + mail: + host: localhost + port: 25 + protocol: smtp + properties: + mail: + smtp: + auth: false + starttls: + enable: false + servlet: + multipart: + max-file-size: 10MB + max-request-size: 10MB + thymeleaf: + cache: false + prefix: classpath:/templates/ + suffix: .html + +server: + port: 8080 + servlet: + context-path: /athletik + +app: + base-url: http://localhost:8080 + +logging: + level: + com.triathlon_coaching.product.athletik: DEBUG + +# Sicherheitskonfiguration +security: + password: + encoder: sha512 + + \ No newline at end of file diff --git a/athletik-service/src/main/webapp/training-summary.html b/athletik-service/src/main/webapp/training-summary.html new file mode 100644 index 0000000..c3437e6 --- /dev/null +++ b/athletik-service/src/main/webapp/training-summary.html @@ -0,0 +1,58 @@ + + + + + Training Zusammenfassung + + + +
+

Dein Training vom

+
+ +
+

Aloha ,

+ +

hier ist Deine Trainings-Zusammenfassung vom :

+ + + + + + + + + + + + + + + + + + + + +
ÜbungSätzeWiederholungenGewicht (kg)Volumen (kg)
ÜbungsnameSätzeWiederholungenGewichtVolumen
+ +
+

Zusammenfassung

+

Gesamtvolumen: kg

+

Anzahl Sätze:

+
+ +

Weiter so! Bleib dran für optimale Trainingserfolge.

+ +

Mit sportlichen Grüßen
triathlon-coaching.com

+
+ + diff --git a/athletik-web/pom.xml b/athletik-web/pom.xml index b151804..ad7bdfe 100644 --- a/athletik-web/pom.xml +++ b/athletik-web/pom.xml @@ -1,18 +1,16 @@ 4.0.0 - com.triathlon-coaching.product - athletik.athletik-web - 0.0.1-SNAPSHOT + athletik.web pom - ${product.artifactId} + ${project.artifactId} Athletik Training WebUI - de.laktatnebel.maven - laktatnebelscript - 2.1.9 + com.triathlon-coaching.product + athletik + 0.0.1-SNAPSHOT diff --git a/athletik-web/src/athletik_glob_vars.php b/athletik-web/src/athletik_glob_vars.php new file mode 100644 index 0000000..f7c88f4 --- /dev/null +++ b/athletik-web/src/athletik_glob_vars.php @@ -0,0 +1,15 @@ + diff --git a/athletik-web/src/roadtokona_glob_vars.php b/athletik-web/src/roadtokona_glob_vars.php deleted file mode 100644 index f7c88f4..0000000 --- a/athletik-web/src/roadtokona_glob_vars.php +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/athletik-web/src/webui/img/Big_Ben_London_closeup.jpg b/athletik-web/src/webui/img/Big_Ben_London_closeup.jpg new file mode 100644 index 0000000..c494e47 Binary files /dev/null and b/athletik-web/src/webui/img/Big_Ben_London_closeup.jpg differ diff --git a/athletik-web/src/webui/img/Reichstag_Berlin.jpg b/athletik-web/src/webui/img/Reichstag_Berlin.jpg new file mode 100644 index 0000000..250d271 Binary files /dev/null and b/athletik-web/src/webui/img/Reichstag_Berlin.jpg differ diff --git a/athletik-web/src/webui/js/athletik.js b/athletik-web/src/webui/js/athletik.js new file mode 100644 index 0000000..ebcbebb --- /dev/null +++ b/athletik-web/src/webui/js/athletik.js @@ -0,0 +1,58 @@ +/** + * + */ + +document.addEventListener('DOMContentLoaded', function() { + const forms = document.querySelectorAll('.ajax-form'); + + forms.forEach(form => { + form.addEventListener('submit', async function(e) { + e.preventDefault(); + + const formData = new FormData(this); + const submitButton = this.querySelector('button[type="submit"]'); + // Loading-State + submitButton.disabled = true; + submitButton.textContent = 'saving ...'; + + try { + const response = await fetch('save-data.php', { + method: 'POST', + body: formData, + credentials: 'include', // Cookies mitsenden + headers: { + 'X-Requested-With': 'XMLHttpRequest' + } + }); + + const result = await response.json(); + + if (result.success) { + showMessage('Data saved successfully!', 'success'); + this.reset(); // Formular zurücksetzen + } else { + showMessage('Error: ' + result.message, 'error'); + } + + } catch (error) { + showMessage('Network error: ' + error.message, 'error'); + } finally { + // Button zurücksetzen + submitButton.disabled = false; + submitButton.textContent = 'Save'; + } + }); + }); + + function showMessage(text, type) { + const messageDiv = document.getElementById('responseMessage'); + messageDiv.textContent = text; + messageDiv.className = type; + messageDiv.style.display = 'block'; + + // Nachricht nach 5 Sekunden ausblenden + setTimeout(() => { + messageDiv.style.display = 'none'; + }, 5000); + } +}); \ No newline at end of file diff --git a/athletik-web/src/webui/lib/database_functions.php b/athletik-web/src/webui/lib/database_functions.php new file mode 100644 index 0000000..8f9d99e --- /dev/null +++ b/athletik-web/src/webui/lib/database_functions.php @@ -0,0 +1,27 @@ + \ No newline at end of file diff --git a/athletik-web/src/webui/lib/db/database_functions_insert.php b/athletik-web/src/webui/lib/db/database_functions_insert.php new file mode 100644 index 0000000..2dd4fa1 --- /dev/null +++ b/athletik-web/src/webui/lib/db/database_functions_insert.php @@ -0,0 +1,55 @@ + \ No newline at end of file diff --git a/athletik-web/src/webui/lib/db/database_functions_pgsql.php b/athletik-web/src/webui/lib/db/database_functions_pgsql.php new file mode 100644 index 0000000..7d3ca8e --- /dev/null +++ b/athletik-web/src/webui/lib/db/database_functions_pgsql.php @@ -0,0 +1,104 @@ +".$res_sql_result; + $return_bool_value = true; + } else { + return "Datenbankabfrage fehlgeschlagen!"; + } + + return $return_bool_value; +} + + +// SQL an DB absetzen +// Parameter: Tablle, Feld(er), Wert(e) +// Rückgabewert: Array +function getData ($dbms_connection, $db_query) { + $return_arr_data = array(); // Rückgabewert als Array + //echo "\n

SQL:
".$ref_str_db_query."

"; + + // DB Abfage starten + //echo $db_query; + $res_sql_result = pg_query ($dbms_connection, $db_query); + // Gültigkeit der DB Abfage testen + if ($res_sql_result) { + //echo "

".$res_sql_result."

"; + while ($arr_sql_data = pg_fetch_row($res_sql_result)) { + //echo debugPrint($arr_sql_data); + array_push ($return_arr_data, $arr_sql_data); + } + //var_dump( $return_arr_data); + } else { + return "Datenbankabfrage fehlgeschlagen!"; + } + + return $return_arr_data; +} + + +// SQL an DB absetzen +// Parameter: Tablle, Feld(er), Wert(e) +// Rückgabewert: Array +function getDataReturnID ($dbms_connection, $db_query) { + $return_arr_data = array(); // Rückgabewert als Array + //echo "\n

SQL:
".$ref_str_db_query."

"; + + // DB Abfage starten + //echo $db_query; + $res_sql_result = pg_query ($dbms_connection, $db_query); + // Gültigkeit der DB Abfage testen + if ($res_sql_result) { + //echo "

".$res_sql_result."

"; + while ($arr_sql_data = pg_fetch_row($res_sql_result)) { + //echo debugPrint($arr_sql_data); + array_push ($return_arr_data, $arr_sql_data); + } + //var_dump( $return_arr_data); + } else { + return "Datenbankabfrage fehlgeschlagen!"; + } + + return $return_arr_data[0][0]; +} + + +?> \ No newline at end of file diff --git a/athletik-web/src/webui/lib/db/database_functions_select.php b/athletik-web/src/webui/lib/db/database_functions_select.php new file mode 100644 index 0000000..fa8e18a --- /dev/null +++ b/athletik-web/src/webui/lib/db/database_functions_select.php @@ -0,0 +1,78 @@ + \ No newline at end of file diff --git a/athletik-web/src/webui/lib/gui/gui_functions_button.php b/athletik-web/src/webui/lib/gui/gui_functions_button.php new file mode 100644 index 0000000..20ae213 --- /dev/null +++ b/athletik-web/src/webui/lib/gui/gui_functions_button.php @@ -0,0 +1,64 @@ + + * $ref_value_button Daten; null möglich + * $ref_html_button HTML zwischen ; null möglich + * $ref_id Id des \n"; + + if ($ref_p_flag) { + echo $intend; + echo "

\n"; + } +} + + +?> \ No newline at end of file diff --git a/athletik-web/src/webui/lib/gui/gui_functions_input.php b/athletik-web/src/webui/lib/gui/gui_functions_input.php new file mode 100644 index 0000000..0777c68 --- /dev/null +++ b/athletik-web/src/webui/lib/gui/gui_functions_input.php @@ -0,0 +1,95 @@ + + * $ref_value_input Daten; null möglich + * $ref_id Id des + * $ref_class Class des ; null möglich + * $ref_tabindex Tabindex in der + + * $ref_type -type (hidden, password, text ...) + * $ref_size Größe des Feldes + * $ref_maxlength Max. Größe der Eingabe + * $ref_javascript Javascript; null möglich + + * $ref_mandantory Pflichtfeldmarkierung; null möglich + * $ref_labeltitle