Merge pull request 'tibor' (#10) from tibor into master

Reviewed-on: https://git.workouttest.org/bossanyit/aitrainer_server/pulls/10
This commit is contained in:
bossanyit 2023-02-25 11:46:59 +00:00
commit b45e283f7f
86 changed files with 3581 additions and 81 deletions

View File

@ -11,7 +11,7 @@ plugins {
} }
group = "com.aitrainer" group = "com.aitrainer"
version = "1.1.0" version = "1.2.0"
java.sourceCompatibility = JavaVersion.VERSION_17 java.sourceCompatibility = JavaVersion.VERSION_17
repositories { repositories {
@ -34,7 +34,7 @@ dependencies {
implementation("org.apache.logging.log4j:log4j-core:2.19.0") implementation("org.apache.logging.log4j:log4j-core:2.19.0")
implementation("org.apache.logging.log4j:log4j-api:2.19.0") implementation("org.apache.logging.log4j:log4j-api:2.19.0")
implementation("org.slf4j:slf4j-api:2.0.6") implementation("org.slf4j:slf4j-api:2.0.6")
//implementation("org.jetbrains.kotlinx:kotlinx-serialization-runtime:1.0-M1-1.4.0-rc") // JVM dependency
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.4.1") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.4.1")
implementation("io.jsonwebtoken:jjwt:0.9.1") implementation("io.jsonwebtoken:jjwt:0.9.1")
@ -48,6 +48,9 @@ dependencies {
implementation("jakarta.mail:jakarta.mail-api:2.1.1") implementation("jakarta.mail:jakarta.mail-api:2.1.1")
implementation("org.eclipse.angus:angus-mail:2.0.1") implementation("org.eclipse.angus:angus-mail:2.0.1")
implementation ("com.aallam.openai:openai-client:2.1.3")
implementation("io.ktor:ktor-client-java:2.2.3")
runtimeOnly("mysql:mysql-connector-java") runtimeOnly("mysql:mysql-connector-java")
testImplementation("org.springframework.boot:spring-boot-starter-test") { testImplementation("org.springframework.boot:spring-boot-starter-test") {
exclude(group = "org.junit.vintage", module = "junit-vintage-engine") exclude(group = "org.junit.vintage", module = "junit-vintage-engine")

444
data/db/diet4you.sql Normal file
View File

@ -0,0 +1,444 @@
-- --------------------------------------------------------
-- Hoszt: 127.0.0.1
-- Szerver verzió: 10.4.11-MariaDB - mariadb.org binary distribution
-- Szerver OS: Win64
-- HeidiSQL Verzió: 12.3.0.6589
-- --------------------------------------------------------
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET NAMES utf8 */;
/*!50503 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
-- Struktúra mentése tábla aitrainer2. app_text
CREATE TABLE IF NOT EXISTS `app_text` (
`text_id` int(13) NOT NULL AUTO_INCREMENT,
`text_key` mediumtext DEFAULT NULL,
`screenshot_url` char(200) DEFAULT NULL,
`checked` tinyint(1) DEFAULT 0,
PRIMARY KEY (`text_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- Az adatok exportálása nem lett kiválasztva.
-- Struktúra mentése tábla aitrainer2. app_text_translation
CREATE TABLE IF NOT EXISTS `app_text_translation` (
`translation_id` int(13) NOT NULL AUTO_INCREMENT,
`text_id` int(11) NOT NULL,
`language_code` char(2) NOT NULL DEFAULT 'en',
`translation` char(50) DEFAULT NULL,
PRIMARY KEY (`translation_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- Az adatok exportálása nem lett kiválasztva.
-- Az adatok exportálása nem lett kiválasztva.
-- Struktúra mentése tábla aitrainer2. configuration
CREATE TABLE IF NOT EXISTS `configuration` (
`configuration_id` int(11) NOT NULL AUTO_INCREMENT,
`config_key` char(50) COLLATE utf8_hungarian_ci DEFAULT NULL,
`config_value` char(50) COLLATE utf8_hungarian_ci DEFAULT NULL,
`date_add` datetime DEFAULT NULL,
`date_change` datetime DEFAULT NULL,
PRIMARY KEY (`configuration_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
-- Az adatok exportálása nem lett kiválasztva.
-- Struktúra mentése tábla aitrainer2. customer
CREATE TABLE IF NOT EXISTS `customer` (
`customer_id` int(11) NOT NULL AUTO_INCREMENT,
`name` char(100) COLLATE utf8_hungarian_ci NOT NULL,
`firstname` char(100) COLLATE utf8_hungarian_ci NOT NULL,
`email` char(100) COLLATE utf8_hungarian_ci DEFAULT NULL,
`password` char(100) COLLATE utf8_hungarian_ci DEFAULT NULL,
`sex` enum('m','w') COLLATE utf8_hungarian_ci DEFAULT 'm',
`age` tinyint(4) DEFAULT NULL,
`active` enum('Y','N','D','S') COLLATE utf8_hungarian_ci DEFAULT 'N',
`date_add` datetime DEFAULT NULL,
`date_change` datetime DEFAULT NULL,
`data_policy_allowed` tinyint(4) DEFAULT 1,
`admin` tinyint(4) DEFAULT 0,
`trainer` tinyint(4) DEFAULT 0,
`trainer_id` int(11) DEFAULT 0,
`birth_year` int(4) DEFAULT 0,
`weight` int(3) DEFAULT 0,
`goal` char(250) COLLATE utf8_hungarian_ci DEFAULT '',
`fitness_level` enum('beginner','intermediate','advanced','professional') COLLATE utf8_hungarian_ci NOT NULL DEFAULT 'beginner',
`body_type` enum('ectomorph','mesomorph','endomorph') COLLATE utf8_hungarian_ci DEFAULT NULL,
`firebase_uid` char(200) COLLATE utf8_hungarian_ci DEFAULT NULL,
`sport_id` int(13) DEFAULT NULL,
`email_subscription` tinyint(1) DEFAULT NULL,
`synced_date` datetime DEFAULT NULL,
`trial_date` datetime DEFAULT NULL,
`firebase_reg_token` text COLLATE utf8_hungarian_ci DEFAULT NULL,
`lang` char(5) COLLATE utf8_hungarian_ci DEFAULT NULL,
`phone` char(50) COLLATE utf8_hungarian_ci DEFAULT NULL,
`life_long` tinyint(4) DEFAULT NULL,
`lang_sync` datetime DEFAULT NULL,
PRIMARY KEY (`customer_id`),
UNIQUE KEY `firebase_uid` (`firebase_uid`),
KEY `firebase_reg_token` (`firebase_reg_token`(1024)),
KEY `sport_id` (`sport_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
-- Struktúra mentése tábla aitrainer2. customer_conversation
CREATE TABLE IF NOT EXISTS `customer_conversation` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`customer_id` int(11) NOT NULL DEFAULT 0,
`conversation_date` datetime DEFAULT NULL,
`question` text COLLATE utf8_hungarian_ci DEFAULT NULL,
`answer` text COLLATE utf8_hungarian_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
-- Az adatok exportálása nem lett kiválasztva.
-- Struktúra mentése tábla aitrainer2. customer_membership
CREATE TABLE IF NOT EXISTS `customer_membership` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`customer_id` int(11) NOT NULL DEFAULT 0,
`membership_id` int(11) NOT NULL DEFAULT 0,
`start_date` datetime DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
KEY `customer_id` (`customer_id`) USING BTREE,
KEY `membership_id` (`membership_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- Az adatok exportálása nem lett kiválasztva.
-- Struktúra mentése tábla aitrainer2. customer_property
CREATE TABLE IF NOT EXISTS `customer_property` (
`customer_property_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`customer_id` int(10) unsigned NOT NULL DEFAULT 0,
`property_id` int(10) unsigned NOT NULL DEFAULT 0,
`property_value` double unsigned NOT NULL DEFAULT 0,
`date_add` datetime DEFAULT NULL,
`goal` tinyint(4) DEFAULT 0,
`goal_date` date DEFAULT NULL,
PRIMARY KEY (`customer_property_id`),
KEY `property_id` (`property_id`),
KEY `customer_id` (`customer_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
-- Az adatok exportálása nem lett kiválasztva.
-- Struktúra mentése tábla aitrainer2. diet
CREATE TABLE IF NOT EXISTS `diet` (
`diet_id` int(11) NOT NULL AUTO_INCREMENT,
`diet_user_id` int(11) NOT NULL DEFAULT 0,
`diet_text` text COLLATE utf8_hungarian_ci DEFAULT NULL,
PRIMARY KEY (`diet_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
-- Az adatok exportálása nem lett kiválasztva.
-- Struktúra mentése tábla aitrainer2. diet_meal
CREATE TABLE IF NOT EXISTS `diet_meal` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`diet_id` int(11) DEFAULT NULL,
`meal_name` char(100) COLLATE utf8_hungarian_ci NOT NULL DEFAULT '0' COMMENT 'i.e. monday|breakfast',
`meal` char(250) COLLATE utf8_hungarian_ci NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `meal_name` (`meal_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
-- Az adatok exportálása nem lett kiválasztva.
-- Struktúra mentése tábla aitrainer2. diet_raw_material
CREATE TABLE IF NOT EXISTS `diet_raw_material` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`diet_meal_id` int(11) NOT NULL DEFAULT 0,
`raw_material_id` int(11) DEFAULT 0,
`kcal_min` int(11) DEFAULT 0,
`kcal_max` int(11) DEFAULT 0,
`protein_min` int(11) DEFAULT 0,
`protein_max` int(11) DEFAULT 0,
`ch_min` int(11) DEFAULT 0,
`ch_max` int(11) DEFAULT 0,
`fat_min` int(11) DEFAULT 0,
`fat_max` int(11) DEFAULT 0,
`sugar` int(11) DEFAULT 0,
`name` char(50) COLLATE utf8_hungarian_ci DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
-- Az adatok exportálása nem lett kiválasztva.
-- Struktúra mentése tábla aitrainer2. diet_sensitivity
CREATE TABLE IF NOT EXISTS `diet_sensitivity` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` char(100) COLLATE utf8_hungarian_ci NOT NULL DEFAULT '0',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
-- Az adatok exportálása nem lett kiválasztva.
-- Struktúra mentése tábla aitrainer2. diet_user
CREATE TABLE IF NOT EXISTS `diet_user` (
`diet_user_id` int(11) NOT NULL AUTO_INCREMENT,
`customer_id` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`diet_user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
-- Az adatok exportálása nem lett kiválasztva.
-- Struktúra mentése tábla aitrainer2. diet_user_consumption
CREATE TABLE IF NOT EXISTS `diet_user_consumption` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`diet_user_id` int(11) NOT NULL,
`raw_material_id` int(11) NOT NULL DEFAULT 0,
`date_consumption` datetime NOT NULL,
`name` char(100) COLLATE utf8_hungarian_ci DEFAULT NULL,
`quantity` double NOT NULL DEFAULT 0,
`quantity_unit` char(10) COLLATE utf8_hungarian_ci DEFAULT NULL,
`cal` int(11) DEFAULT NULL,
`protein` double DEFAULT NULL,
`fat` double DEFAULT NULL,
`ch` double DEFAULT NULL,
`sugar` double DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `diet_user_id` (`diet_user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
-- Az adatok exportálása nem lett kiválasztva.
-- Struktúra mentése tábla aitrainer2. diet_user_preference
CREATE TABLE IF NOT EXISTS `diet_user_preference` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`diet_user_id` int(11) NOT NULL DEFAULT 0,
`raw_material_id` int(11) NOT NULL DEFAULT 0,
`temperature` decimal(1,0) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`) USING BTREE,
KEY `diet_user_id` (`diet_user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
-- Az adatok exportálása nem lett kiválasztva.
-- Struktúra mentése tábla aitrainer2. diet_user_sensitivity
CREATE TABLE IF NOT EXISTS `diet_user_sensitivity` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`sensitivity_id` int(11) NOT NULL DEFAULT 0,
`diet_user_id` int(11) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
KEY `diet_user_id` (`diet_user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
-- Az adatok exportálása nem lett kiválasztva.
-- Struktúra mentése tábla aitrainer2. faq
CREATE TABLE IF NOT EXISTS `faq` (
`faq_id` int(11) NOT NULL AUTO_INCREMENT,
`name` char(200) COLLATE utf8_hungarian_ci NOT NULL,
`description` text COLLATE utf8_hungarian_ci DEFAULT NULL,
`sort` int(11) DEFAULT NULL,
PRIMARY KEY (`faq_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
-- Az adatok exportálása nem lett kiválasztva.
-- Struktúra mentése tábla aitrainer2. faq_translation
CREATE TABLE IF NOT EXISTS `faq_translation` (
`translation_id` int(11) NOT NULL AUTO_INCREMENT,
`faq_id` int(11) NOT NULL DEFAULT 0,
`name_translation` char(200) COLLATE utf8_hungarian_ci NOT NULL DEFAULT '0',
`description_translation` text COLLATE utf8_hungarian_ci DEFAULT NULL,
`language_code` char(2) COLLATE utf8_hungarian_ci DEFAULT 'en',
PRIMARY KEY (`translation_id`) USING BTREE,
KEY `faq_id` (`faq_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
-- Struktúra mentése tábla aitrainer2. membership
CREATE TABLE IF NOT EXISTS `membership` (
`membership_id` int(11) NOT NULL AUTO_INCREMENT,
`name` char(100) CHARACTER SET utf8mb4 NOT NULL,
`description` char(200) CHARACTER SET utf8mb4 DEFAULT NULL,
`duration` int(11) DEFAULT NULL,
`duration_type` enum('free','subscription','lifetime','limited') CHARACTER SET utf8mb4 DEFAULT NULL,
`duration_unit` enum('day','week','month','year') COLLATE utf8_hungarian_ci DEFAULT NULL,
`training_plan_id` int(11) DEFAULT 0,
`training_plan_day_ids` char(50) COLLATE utf8_hungarian_ci DEFAULT NULL,
PRIMARY KEY (`membership_id`) USING BTREE,
KEY `training_plan_id` (`training_plan_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
-- Az adatok exportálása nem lett kiválasztva.
-- Struktúra mentése tábla aitrainer2. notification
CREATE TABLE IF NOT EXISTS `notification` (
`notification_id` int(11) NOT NULL AUTO_INCREMENT,
`internal_name` char(50) COLLATE utf8_hungarian_ci DEFAULT NULL,
`internal_description` mediumtext COLLATE utf8_hungarian_ci DEFAULT NULL,
`message_title` char(50) COLLATE utf8_hungarian_ci NOT NULL DEFAULT '',
`message_body` char(100) COLLATE utf8_hungarian_ci NOT NULL DEFAULT '',
`image_url` char(100) COLLATE utf8_hungarian_ci DEFAULT '',
`schedule_date` datetime DEFAULT NULL,
`schedule_hook` char(100) COLLATE utf8_hungarian_ci DEFAULT NULL,
`schedule_sql` mediumtext COLLATE utf8_hungarian_ci DEFAULT NULL,
`active` tinyint(1) DEFAULT 0,
PRIMARY KEY (`notification_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
-- Az adatok exportálása nem lett kiválasztva.
-- Struktúra mentése tábla aitrainer2. notification_history
CREATE TABLE IF NOT EXISTS `notification_history` (
`notification_history_id` int(11) NOT NULL AUTO_INCREMENT,
`notification_id` int(11) NOT NULL,
`customer_id` int(11) NOT NULL,
`response` char(255) COLLATE utf8_hungarian_ci DEFAULT NULL,
`notification_date` datetime DEFAULT NULL,
PRIMARY KEY (`notification_history_id`),
KEY `notification_id` (`notification_id`),
KEY `customer_id` (`customer_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
-- Az adatok exportálása nem lett kiválasztva.
-- Struktúra mentése tábla aitrainer2. product
CREATE TABLE IF NOT EXISTS `product` (
`product_id` int(11) NOT NULL AUTO_INCREMENT,
`name` char(50) NOT NULL,
`description` mediumtext DEFAULT NULL,
`app_version` char(50) NOT NULL,
`product_set` int(5) NOT NULL,
`sort` int(5) NOT NULL,
`type` enum('subscription','in-app-currency') NOT NULL DEFAULT 'subscription',
`valid_from` date DEFAULT NULL,
`valid_to` date DEFAULT NULL,
`product_id_ios` char(50) DEFAULT NULL,
`product_id_android` char(50) DEFAULT NULL,
`price_ios` float DEFAULT NULL,
`price_android` float DEFAULT NULL,
PRIMARY KEY (`product_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- Struktúra mentése tábla aitrainer2. property
CREATE TABLE IF NOT EXISTS `property` (
`property_id` int(11) NOT NULL AUTO_INCREMENT,
`property_name` char(50) COLLATE utf8_hungarian_ci DEFAULT NULL,
`property_unit` char(50) COLLATE utf8_hungarian_ci DEFAULT NULL,
PRIMARY KEY (`property_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
-- Az adatok exportálása nem lett kiválasztva.
-- Struktúra mentése tábla aitrainer2. property_translation
CREATE TABLE IF NOT EXISTS `property_translation` (
`translation_id` int(13) NOT NULL AUTO_INCREMENT,
`language_code` char(2) NOT NULL DEFAULT 'en',
`property_id` int(13) NOT NULL DEFAULT 0,
`property_name` char(50) DEFAULT NULL,
PRIMARY KEY (`translation_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- Az adatok exportálása nem lett kiválasztva.
-- Struktúra mentése tábla aitrainer2. purchase
CREATE TABLE IF NOT EXISTS `purchase` (
`purchase_id` int(11) NOT NULL AUTO_INCREMENT,
`customer_id` int(11) NOT NULL DEFAULT 0,
`product_id` int(11) NOT NULL DEFAULT 0,
`date_add` datetime DEFAULT NULL,
`purchase_sum` double(22,0) DEFAULT NULL,
`currency` char(3) DEFAULT NULL,
`expiring` datetime DEFAULT NULL,
PRIMARY KEY (`purchase_id`) USING BTREE,
KEY `customer_id` (`customer_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- Az adatok exportálása nem lett kiválasztva.
-- Struktúra mentése tábla aitrainer2. raw_material
CREATE TABLE IF NOT EXISTS `raw_material` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` char(100) COLLATE utf8_hungarian_ci NOT NULL,
`description` text COLLATE utf8_hungarian_ci DEFAULT NULL,
`kcal_min` int(11) DEFAULT 0,
`kcal_max` int(11) DEFAULT 0,
`protein_min` int(11) DEFAULT 0,
`protein_max` int(11) DEFAULT 0,
`ch_min` int(11) DEFAULT 0,
`ch_max` int(11) DEFAULT 0,
`fat_min` int(11) DEFAULT 0,
`fat_max` int(11) DEFAULT 0,
`sugar` int(11) DEFAULT 0,
`store_id` int(11) DEFAULT 0,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci ROW_FORMAT=DYNAMIC;
-- Az adatok exportálása nem lett kiválasztva.
-- Struktúra mentése tábla aitrainer2. recipe
CREATE TABLE IF NOT EXISTS `recipe` (
`recipe_id` int(11) NOT NULL AUTO_INCREMENT,
`name` char(250) COLLATE utf8_hungarian_ci NOT NULL DEFAULT '',
`description` text COLLATE utf8_hungarian_ci DEFAULT NULL,
`cal` int(11) DEFAULT NULL,
`protein` double DEFAULT NULL,
`fat` double DEFAULT NULL,
`ch` double DEFAULT NULL,
`diet_user_id` int(11) DEFAULT 0,
PRIMARY KEY (`recipe_id`) USING BTREE,
KEY `name` (`name`),
KEY `diet_user_id` (`diet_user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
-- Az adatok exportálása nem lett kiválasztva.
-- Struktúra mentése tábla aitrainer2. recipe_raw_material
CREATE TABLE IF NOT EXISTS `recipe_raw_material` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`raw_material_id` int(11) NOT NULL DEFAULT 0,
`recipe_id` int(11) NOT NULL DEFAULT 0,
`quantity` int(11) DEFAULT 0,
`quantity_unit` char(10) COLLATE utf8_hungarian_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
-- Az adatok exportálása nem lett kiválasztva.
-- Struktúra mentése tábla aitrainer2. store
CREATE TABLE IF NOT EXISTS `store` (
`store_id` int(11) NOT NULL AUTO_INCREMENT,
`store_name` char(50) COLLATE utf8_hungarian_ci NOT NULL DEFAULT '',
`country` char(4) COLLATE utf8_hungarian_ci NOT NULL DEFAULT '',
PRIMARY KEY (`store_id`),
KEY `store_name` (`store_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
-- Az adatok exportálása nem lett kiválasztva.
-- Struktúra mentése tábla aitrainer2. tracking
CREATE TABLE IF NOT EXISTS `tracking` (
`tracking_id` int(20) NOT NULL AUTO_INCREMENT,
`customer_id` int(20) NOT NULL DEFAULT 0,
`date_add` datetime NOT NULL,
`event` char(100) COLLATE utf8_hungarian_ci DEFAULT NULL,
`event_value` text COLLATE utf8_hungarian_ci DEFAULT NULL,
`area` char(100) COLLATE utf8_hungarian_ci DEFAULT NULL,
`platform` char(20) COLLATE utf8_hungarian_ci DEFAULT NULL,
`version` char(20) COLLATE utf8_hungarian_ci DEFAULT NULL,
PRIMARY KEY (`tracking_id`) USING BTREE,
KEY `customer_id` (`customer_id`),
KEY `event` (`event`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci;
INSERT INTO `customer` VALUES (54, 'Dummy User', '', 'bosi', '$2a$10$thOc8jS750c7xe9U9Qq3GuSPs/H0Pt2Ads05yzUlyzQBIj.Rk9QCy', 'm', 0, 'N', NULL, NULL, 1, 1, 0, 0, 0, 0, '', 'beginner', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
/*!40103 SET TIME_ZONE=IFNULL(@OLD_TIME_ZONE, 'system') */;
/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
/*!40014 SET FOREIGN_KEY_CHECKS=IFNULL(@OLD_FOREIGN_KEY_CHECKS, 1) */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40111 SET SQL_NOTES=IFNULL(@OLD_SQL_NOTES, 1) */;

View File

@ -9,8 +9,8 @@ CREATE TABLE `membership` (
`duration_unit` ENUM('day','week','month','year') NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci', `duration_unit` ENUM('day','week','month','year') NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
`training_plan_id` INT(11) NULL DEFAULT '0', `training_plan_id` INT(11) NULL DEFAULT '0',
`training_plan_day_ids` CHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci', `training_plan_day_ids` CHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
PRIMARY KEY (`membership_id`) USING BTREE PRIMARY KEY (`membership_id`) USING BTREE,
INDEX `training_plan_id` (`training_plan_id`) USING BTREE, INDEX `training_plan_id` (`training_plan_id`) USING BTREE
) )
ENGINE=InnoDB ENGINE=InnoDB
; ;

187
data/db/update_1_2_0.sql Normal file
View File

@ -0,0 +1,187 @@
START TRANSACTION;
CREATE TABLE `customer_conversation` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`customer_id` INT(11) NOT NULL DEFAULT '0',
`conversation_date` DATETIME NULL DEFAULT NULL,
`question` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
`answer` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
PRIMARY KEY (`id`) USING BTREE
)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
;
CREATE TABLE `diet_user` (
`diet_user_id` INT(11) NOT NULL AUTO_INCREMENT,
`customer_id` INT(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`diet_user_id`) USING BTREE
)
ENGINE=InnoDB
;
CREATE TABLE `diet` (
`diet_id` INT(11) NOT NULL AUTO_INCREMENT,
`diet_user_id` INT(11) NOT NULL DEFAULT '0',
`diet_text` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
`start_date` DATE NULL DEFAULT NULL,
PRIMARY KEY (`diet_id`) USING BTREE
)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
;
CREATE TABLE `diet_meal` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`diet_id` INT(11) NULL DEFAULT NULL,
`meal_name` CHAR(100) NOT NULL DEFAULT '0' COMMENT 'i.e. monday|breakfast' COLLATE 'utf8mb4_general_ci',
`meal` CHAR(250) NOT NULL DEFAULT '0' COLLATE 'utf8mb4_general_ci',
PRIMARY KEY (`id`) USING BTREE,
INDEX `meal_name` (`meal_name`) USING BTREE
)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
;
CREATE TABLE `diet_raw_material` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`diet_meal_id` INT(11) NOT NULL DEFAULT '0',
`raw_material_id` INT(11) NULL DEFAULT '0',
`kcal_min` INT(11) NULL DEFAULT '0',
`kcal_max` INT(11) NULL DEFAULT '0',
`protein_min` INT(11) NULL DEFAULT '0',
`protein_max` INT(11) NULL DEFAULT '0',
`ch_min` INT(11) NULL DEFAULT '0',
`ch_max` INT(11) NULL DEFAULT '0',
`fat_min` INT(11) NULL DEFAULT '0',
`fat_max` INT(11) NULL DEFAULT '0',
`sugar` INT(11) NULL DEFAULT '0',
`name` CHAR(50) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
PRIMARY KEY (`id`) USING BTREE
)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
;
CREATE TABLE `diet_sensitivity` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` CHAR(100) NOT NULL DEFAULT '0' COLLATE 'utf8mb4_general_ci',
PRIMARY KEY (`id`) USING BTREE
)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
;
CREATE TABLE `diet_user_consumption` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`diet_user_id` INT(11) NOT NULL,
`raw_material_id` INT(11) NOT NULL DEFAULT '0',
`date_consumption` DATETIME NOT NULL,
`name` CHAR(100) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
`quantity` DOUBLE NOT NULL DEFAULT '0',
`quantity_unit` CHAR(10) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
`cal` INT(11) NULL DEFAULT NULL,
`protein` DOUBLE NULL DEFAULT NULL,
`fat` DOUBLE NULL DEFAULT NULL,
`ch` DOUBLE NULL DEFAULT NULL,
`sugar` DOUBLE NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `diet_user_id` (`diet_user_id`) USING BTREE
)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
;
CREATE TABLE `diet_user_preference` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`diet_user_id` INT(11) NOT NULL DEFAULT '0',
`raw_material_id` INT(11) NOT NULL DEFAULT '0',
`temperature` DECIMAL(1,0) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`) USING BTREE,
INDEX `diet_user_id` (`diet_user_id`) USING BTREE
)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
;
CREATE TABLE `diet_user_sensitivity` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`sensitivity_id` INT(11) NOT NULL DEFAULT '0',
`diet_user_id` INT(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`) USING BTREE,
INDEX `diet_user_id` (`diet_user_id`) USING BTREE
)
COLLATE='utf8_hungarian_ci'
ENGINE=InnoDB
;
CREATE TABLE `raw_material` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` CHAR(100) NOT NULL COLLATE 'utf8mb4_general_ci',
`description` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
`kcal_min` INT(11) NULL DEFAULT '0',
`kcal_max` INT(11) NULL DEFAULT '0',
`protein_min` INT(11) NULL DEFAULT '0',
`protein_max` INT(11) NULL DEFAULT '0',
`ch_min` INT(11) NULL DEFAULT '0',
`ch_max` INT(11) NULL DEFAULT '0',
`fat_min` INT(11) NULL DEFAULT '0',
`fat_max` INT(11) NULL DEFAULT '0',
`sugar` INT(11) NULL DEFAULT '0',
`store_id` INT(11) NULL DEFAULT '0',
PRIMARY KEY (`id`) USING BTREE
)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
ROW_FORMAT=DYNAMIC
;
CREATE TABLE `recipe` (
`recipe_id` INT(11) NOT NULL AUTO_INCREMENT,
`name` CHAR(250) NOT NULL DEFAULT '' COLLATE 'utf8mb4_general_ci',
`description` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
`cal` INT(11) NULL DEFAULT NULL,
`protein` DOUBLE NULL DEFAULT NULL,
`fat` DOUBLE NULL DEFAULT NULL,
`ch` DOUBLE NULL DEFAULT NULL,
`diet_user_id` INT(11) NULL DEFAULT '0',
`meal_id` INT(11) NULL DEFAULT NULL,
PRIMARY KEY (`recipe_id`) USING BTREE,
INDEX `name` (`name`) USING BTREE,
INDEX `diet_user_id` (`diet_user_id`) USING BTREE
INDEX `meal_id` (`meal_id`) USING BTREE
)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
;
CREATE TABLE `store` (
`store_id` INT(11) NOT NULL AUTO_INCREMENT,
`store_name` CHAR(50) NOT NULL DEFAULT '' COLLATE 'utf8mb4_general_ci',
`country` CHAR(4) NOT NULL DEFAULT '' COLLATE 'utf8mb4_general_ci',
PRIMARY KEY (`store_id`) USING BTREE,
INDEX `store_name` (`store_name`) USING BTREE
)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
;
CREATE TABLE `recipe_raw_material` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`raw_material_id` INT(11) NOT NULL DEFAULT '0',
`recipe_id` INT(11) NOT NULL DEFAULT '0',
`quantity` INT(11) NULL DEFAULT '0',
`quantity_unit` CHAR(10) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
PRIMARY KEY (`id`) USING BTREE
)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB
;
UPDATE configuration set config_value = "1.2.0", date_change=CURRENT_DATE WHERE config_key = "db_version";
COMMIT;

View File

@ -1,7 +1,8 @@
#aitrainer server API v1.1 #aitrainer server API v1.2
connects the MYSQL Database connects the MYSQL Database
provide a RESTful API for the mobile app provide a RESTful API for the mobile app
Open AI API
Workout Test Club Workout Test Club
@ -28,5 +29,7 @@ Workout Test Club
* exercise_device_translation * exercise_device_translation
* exercise_type_device * exercise_type_device
* deactivate customer * deactivate customer
* diet tables
* openAI
with automatic database update with automatic database update

View File

@ -1,4 +1,4 @@
FROM openjdk:12 FROM openjdk:18
RUN mkdir aitrainer_server RUN mkdir aitrainer_server
RUN mkdir aitrainer_server/data RUN mkdir aitrainer_server/data
RUN mkdir aitrainer_server/data/db RUN mkdir aitrainer_server/data/db

View File

@ -9,6 +9,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.builder.SpringApplicationBuilder import org.springframework.boot.builder.SpringApplicationBuilder
import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Bean
@SpringBootApplication @SpringBootApplication
class ApiApplication { class ApiApplication {
@Bean(name = ["jasyptStringEncryptor"]) @Bean(name = ["jasyptStringEncryptor"])
@ -43,3 +44,5 @@ class ApiApplication {

View File

@ -1,12 +1,14 @@
package com.aitrainer.api.controller package com.aitrainer.api.controller
import org.springframework.beans.factory.annotation.Value import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Component
import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController import org.springframework.web.bind.annotation.RestController
@RestController @RestController
@RequestMapping @RequestMapping
@Component
class ApplicationProperties { class ApplicationProperties {
@Value("\${application.version}") @Value("\${application.version}")
@ -21,7 +23,8 @@ class ApplicationProperties {
@Value("\${spring.datasource.password}") @Value("\${spring.datasource.password}")
private lateinit var datasourcePassword: String private lateinit var datasourcePassword: String
@Value("\${openai.key}")
private lateinit var apiKey: String
@GetMapping("/version") @GetMapping("/version")
fun getVersion(): String { fun getVersion(): String {
@ -42,4 +45,11 @@ class ApplicationProperties {
fun getDatasourcePassword(): String { fun getDatasourcePassword(): String {
return this.datasourcePassword return this.datasourcePassword
} }
@GetMapping("/openAIKey")
fun getOpenAIKey(): String {
return this.apiKey
}
} }

View File

@ -8,17 +8,14 @@ import com.aitrainer.api.service.EmailTemplateService
import com.aitrainer.api.service.Firebase import com.aitrainer.api.service.Firebase
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.http.HttpHeaders import org.springframework.http.HttpHeaders
import org.springframework.http.ResponseEntity import org.springframework.http.ResponseEntity
import org.springframework.security.access.annotation.Secured import org.springframework.security.access.annotation.Secured
import org.springframework.web.bind.annotation.* import org.springframework.web.bind.annotation.*
import java.io.ByteArrayOutputStream
import java.nio.charset.StandardCharsets.UTF_8
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
import java.util.* import java.util.*
import java.util.zip.GZIPInputStream
import java.util.zip.GZIPOutputStream
import javax.validation.Valid import javax.validation.Valid
@ -157,16 +154,7 @@ class CustomerController ( private val customerRepository: CustomerRepository) {
} }
@PostMapping("/club_registration") @PostMapping("/club_registration")
fun clubRegistration(@Valid @RequestBody json: String): ResponseEntity<*> { fun clubRegistration(@Valid @RequestBody json: String, @Value("\${firebase.key}") apiKey: String): ResponseEntity<*> {
fun gzip(content: String): String {
val bos = ByteArrayOutputStream()
GZIPOutputStream(bos).bufferedWriter(UTF_8).use { it.write(content) }
return bos.toByteArray().toString()
}
fun unzip(content: ByteArray): String =
GZIPInputStream(content.inputStream()).bufferedReader(UTF_8).use { it.readText() }
val newUser: ClubUser = ClubUser().fromJson(json) val newUser: ClubUser = ClubUser().fromJson(json)
@ -186,7 +174,7 @@ class CustomerController ( private val customerRepository: CustomerRepository) {
val stringCharacters = ('0'..'z').toList().toTypedArray() val stringCharacters = ('0'..'z').toList().toTypedArray()
val genPassword = (1..10).map { stringCharacters.random() }.joinToString("") val genPassword = (1..10).map { stringCharacters.random() }.joinToString("")
val firebase = Firebase() val firebase = Firebase(apiKey)
val signupResponse = firebase.signUp(newUser.email, genPassword) val signupResponse = firebase.signUp(newUser.email, genPassword)
?: return ResponseEntity.badRequest().body("Firebase exception ${firebase.error}") ?: return ResponseEntity.badRequest().body("Firebase exception ${firebase.error}")
@ -252,7 +240,7 @@ class CustomerController ( private val customerRepository: CustomerRepository) {
if ( emailTemplateService == null ) { if ( emailTemplateService == null ) {
emailTemplateService = EmailTemplateService() emailTemplateService = EmailTemplateService()
} }
val html = emailTemplateService!!.getEmailBody(newUser.firstname, activationLink) val html = emailTemplateService!!.getEmailBody(newUser.firstname, activationLink, "registration_email")
val subject = emailTemplateService!!.getSubject() val subject = emailTemplateService!!.getSubject()
// send email // send email

View File

@ -0,0 +1,25 @@
package com.aitrainer.api.controller
import com.aitrainer.api.model.CustomerConversation
import com.aitrainer.api.repository.CustomerConversationRepository
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
@RestController
@RequestMapping("/api")
class CustomerConversationController (private val customerConversationRepository: CustomerConversationRepository
) {
@PostMapping("/customer_conversation")
fun insert(@RequestBody customerConversation: CustomerConversation): ResponseEntity<CustomerConversation> {
return ResponseEntity.ok().body(customerConversationRepository.save(customerConversation))
}
@GetMapping("/customer_conversation/{customerId}")
fun getByCustomerId(@PathVariable customerId: Long): ResponseEntity<List<CustomerConversation>> {
val list = customerConversationRepository.findByCustomerId(customerId)
return if (list.isEmpty()) ResponseEntity.notFound().build() else
ResponseEntity.ok().body(list)
}
}

View File

@ -2,7 +2,9 @@ package com.aitrainer.api.controller
import com.aitrainer.api.model.* import com.aitrainer.api.model.*
import com.aitrainer.api.model.CustomerMembership import com.aitrainer.api.model.CustomerMembership
import com.aitrainer.api.model.diet.*
import com.aitrainer.api.repository.* import com.aitrainer.api.repository.*
import com.aitrainer.api.repository.diet.*
import com.google.gson.GsonBuilder import com.google.gson.GsonBuilder
import org.springframework.http.ResponseEntity import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.GetMapping
@ -21,8 +23,69 @@ class CustomerPackageController( private val customerRepository: CustomerReposit
private val customerActivityRepository: CustomerActivityRepository, private val customerActivityRepository: CustomerActivityRepository,
private val customerTrainingPlanRepository: CustomerTrainingPlanRepository, private val customerTrainingPlanRepository: CustomerTrainingPlanRepository,
private val customerMembership: CustomerMembershipRepository, private val customerMembership: CustomerMembershipRepository,
private val dietRepository: DietRepository,
private val dietRawMaterialRepository: DietRawMaterialRepository,
private val dietUserConsumptionRepository: DietUserConsumptionRepository,
private val dietUserRepository: DietUserRepository,
private val dietUserPreferenceRepository: DietUserPreferenceRepository,
private val dietUserSensitivityRepository: DietUserSensitivityRepository,
private val customerConversationRepository: CustomerConversationRepository
) { ) {
@GetMapping("/diet_customer_package/{id}")
fun getDietCustomerPackageData(@PathVariable(value = "id") dietUserId: Long): ResponseEntity<String> {
if (dietUserId <= 0) {
return ResponseEntity.notFound().build()
}
val gson = GsonBuilder()
.excludeFieldsWithoutExposeAnnotation()
.setPrettyPrinting()
.create()
val dietUser: DietUser = dietUserRepository.findByDietUserId(dietUserId)
?: return ResponseEntity.notFound().build()
val customerId = dietUser.customerId
val customer: Customer = customerRepository.findByCustomerIdAndActive(customerId, "Y")
?: return ResponseEntity.notFound().build()
val customerJson: String = gson.toJson(customer)
val dietUserJson: String = gson.toJson(dietUser)
val listDiet = dietRepository.findByDietUserId(dietUserId)
val listDietJson = gson.toJson(listDiet)
val listDietRawMaterial = dietRawMaterialRepository.findByDietMealId(dietUserId)
val listDietRawMaterialJson = gson.toJson(listDietRawMaterial)
val listDietUserConsumption = dietUserConsumptionRepository.findByDietUserId(dietUserId)
val listDietUserConsumptionJson = gson.toJson(listDietUserConsumption)
val listDietUserPreference = dietUserPreferenceRepository.findByDietUserId(dietUserId)
val listDietUserPreferenceJson = gson.toJson(listDietUserPreference)
val listDietUserSensitivity = dietUserSensitivityRepository.findByDietUserId(dietUserId)
val listDietUserSensitivityJson = gson.toJson(listDietUserSensitivity)
val listCustomerConversation = customerConversationRepository.findByCustomerId(customerId)
val listCustomerConversationJson = gson.toJson(listCustomerConversation)
val packageJson: String =
getClassRecord(Customer::class.simpleName, customerJson) +
"|||" + getClassRecord(DietUser::class.simpleName, dietUserJson) +
"|||" + getClassRecord(Diet::class.simpleName, listDietJson) +
"|||" + getClassRecord(DietRawMaterial::class.simpleName, listDietRawMaterialJson) +
"|||" + getClassRecord(DietUserConsumption::class.simpleName, listDietUserConsumptionJson) +
"|||" + getClassRecord(DietUserPreference::class.simpleName, listDietUserPreferenceJson) +
"|||" + getClassRecord(DietUserSensitivity::class.simpleName, listDietUserSensitivityJson) +
"|||" + getClassRecord(CustomerConversation::class.simpleName, listCustomerConversationJson)
return if (packageJson.isEmpty()) ResponseEntity.notFound().build() else
ResponseEntity.ok().body(packageJson)
}
@GetMapping("/club_customer_package/{id}") @GetMapping("/club_customer_package/{id}")
fun getCustomerClubPackageData(@PathVariable(value = "id") customerId: Long): ResponseEntity<String> { fun getCustomerClubPackageData(@PathVariable(value = "id") customerId: Long): ResponseEntity<String> {
if (customerId <= 0) { if (customerId <= 0) {

View File

@ -1,10 +1,7 @@
package com.aitrainer.api.controller package com.aitrainer.api.controller
import com.aitrainer.api.model.Evaluation import com.aitrainer.api.model.Evaluation
import com.aitrainer.api.model.ExerciseTree
import com.aitrainer.api.repository.EvaluationRepository import com.aitrainer.api.repository.EvaluationRepository
import com.aitrainer.api.repository.ExerciseTreeParentsRepository
import com.aitrainer.api.repository.ExerciseTreeRepository
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import org.springframework.http.ResponseEntity import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.GetMapping

View File

@ -0,0 +1,59 @@
package com.aitrainer.api.controller
import com.aitrainer.api.model.OpenAI
import com.aitrainer.api.openai.OpenAIService
import kotlinx.coroutines.*
import org.slf4j.LoggerFactory
import org.springframework.web.bind.annotation.*
@RestController
@RequestMapping("/api")
class OpenAIController() {
private val logger = LoggerFactory.getLogger(javaClass)
@OptIn(DelicateCoroutinesApi::class)
@PostMapping("/openai/completion")
fun getOpenAIResponse(@RequestBody question: String) : String {
var result = ""
val openAIService = OpenAIService(null, null)
val deferred = GlobalScope.async {
openAIService.completion(question)
}
runBlocking {
result = deferred.await()
//println("Result: $result" )
}
return result
}
@OptIn(DelicateCoroutinesApi::class)
@PostMapping("/openai/completion_with_model")
fun getOpenAIResponseWithModel(@RequestBody openai: OpenAI) : String {
var result = ""
val openAIService = OpenAIService(openai.modelName, openai.temperature)
val deferred = GlobalScope.async {
openAIService.completion(openai.question)
}
runBlocking {
result = deferred.await()
//println("Result: $result" )
}
return result
}
@OptIn(DelicateCoroutinesApi::class)
@GetMapping("/openai/list_models")
fun getOpenAIModels(): MutableList<String> {
var result = mutableListOf<String>()
val openAIService = OpenAIService(null, null)
val deferred = GlobalScope.async {
openAIService.getModels()
}
runBlocking {
result = deferred.await()
//println("Result: $result" )
}
return result
}
}

View File

@ -1,7 +1,12 @@
package com.aitrainer.api.controller package com.aitrainer.api.controller
import com.aitrainer.api.model.* import com.aitrainer.api.model.*
import com.aitrainer.api.model.diet.DietSensitivity
import com.aitrainer.api.model.diet.RawMaterial
import com.aitrainer.api.model.diet.Recipe
import com.aitrainer.api.model.diet.Store
import com.aitrainer.api.repository.* import com.aitrainer.api.repository.*
import com.aitrainer.api.repository.diet.*
import org.springframework.http.ResponseEntity import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestMapping
@ -29,9 +34,50 @@ class PackageController(private val exerciseAbilityRepository: ExerciseAbilityRe
private val trainingPlanDayRepository: TrainingPlanDayRepository, private val trainingPlanDayRepository: TrainingPlanDayRepository,
private val appTextRepository: AppTextRepository, private val appTextRepository: AppTextRepository,
private val trainingProgramRepository: TrainingProgramRepository, private val trainingProgramRepository: TrainingProgramRepository,
private val membershipRepository: MembershipRepository private val membershipRepository: MembershipRepository,
private val storeRepository: StoreRepository,
private val recipeRepository: RecipeRepository,
private val rawMaterialRepository: RawMaterialRepository,
private val dietSensitivityRepository: DietSensitivityRepository
) { ) {
@GetMapping("/diet_package")
fun getDietPackageData(): ResponseEntity<String> {
val gson = GsonBuilder()
.excludeFieldsWithoutExposeAnnotation()
.setPrettyPrinting()
.create()
val listProperty:List<Property> = propertyRepository.getProperties()
val listPropertyJson: String = gson.toJson(listProperty)
val listMembership = membershipRepository.findAll()
val listMembershipJson = gson.toJson(listMembership)
val listStore = storeRepository.findAll()
val listStoreJson = gson.toJson(listStore)
val listRecipe = recipeRepository.findAll()
val listRecipeJson = gson.toJson(listRecipe)
val listRawMaterial = rawMaterialRepository.findAll()
val listRawMaterialJson = gson.toJson(listRawMaterial)
val listDietSensitivity = dietSensitivityRepository.findAll()
val listDietSensitivityJson = gson.toJson(listDietSensitivity)
val packageJson: String =
getClassRecord(Property::class.simpleName, listPropertyJson) +
"|||" + getClassRecord(Membership::class.simpleName, listMembershipJson) +
"|||" + getClassRecord(Store::class.simpleName, listStoreJson) +
"|||" + getClassRecord(Recipe::class.simpleName, listRecipeJson) +
"|||" + getClassRecord(RawMaterial::class.simpleName, listRawMaterialJson) +
"|||" + getClassRecord(DietSensitivity::class.simpleName, listDietSensitivityJson)
return if (packageJson.isEmpty()) ResponseEntity.notFound().build() else
ResponseEntity.ok().body(packageJson)
}
@GetMapping("/club_package") @GetMapping("/club_package")
fun getClubPackageData(): ResponseEntity<String> { fun getClubPackageData(): ResponseEntity<String> {

View File

@ -0,0 +1,41 @@
package com.aitrainer.api.controller.diet
import com.aitrainer.api.model.diet.Diet
import com.aitrainer.api.repository.diet.DietRepository
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import java.util.*
@RestController
@RequestMapping("/api")
class DietController(private val dietRepository: DietRepository) {
@PostMapping("/diet")
fun insert(@RequestBody diet: Diet): ResponseEntity<*> {
return ResponseEntity.ok().body(dietRepository.save(diet))
}
@PostMapping("/diet/{id}")
fun update(@PathVariable(value = "id") id: Long, @RequestBody diet: Diet): ResponseEntity<Diet> {
val existingDiet = dietRepository.findByDietId(id) ?: return ResponseEntity.notFound().build()
val updatedDiet: Diet = existingDiet.copy(
dietId = diet.dietId,
dietUserId = diet.dietUserId,
dietText = diet.dietText,
startDate = diet.startDate
)
diet.meals.forEach {
it.diet = diet
updatedDiet.meals.add(it)
}
return ResponseEntity.ok().body(dietRepository.save(updatedDiet))
}
@GetMapping("/diet/{dietUserId}")
fun getByDietUserId(@PathVariable dietUserId: Long): ResponseEntity<List<Diet>> {
val list = dietRepository.findByDietUserId(dietUserId)
return if (list.isEmpty()) ResponseEntity.notFound().build() else
ResponseEntity.ok().body(list)
}
}

View File

@ -0,0 +1,138 @@
package com.aitrainer.api.controller.diet
import com.aitrainer.api.model.Customer
import com.aitrainer.api.model.CustomerMembership
import com.aitrainer.api.model.CustomerPropertyProperty
import com.aitrainer.api.model.diet.DietCustomer
import com.aitrainer.api.model.diet.DietUser
import com.aitrainer.api.repository.CustomerRepository
import com.aitrainer.api.repository.diet.DietUserRepository
import com.aitrainer.api.service.Firebase
import com.aitrainer.api.service.ServiceBeans
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.util.*
@RestController
@RequestMapping("/api")
class DietCustomerController(private val dietUserRepository: DietUserRepository, private val customerRepository: CustomerRepository) {
@Autowired
var serviceBeans: ServiceBeans? = null
@PostMapping("/diet_registration")
fun insert(@RequestBody dietCustomerJson: String, @Value("\${firebase.key}") apiKey: String): ResponseEntity<*> {
val newDietCustomer: DietCustomer = DietCustomer().fromJson(dietCustomerJson)
if ( newDietCustomer.email.isEmpty()) {
return ResponseEntity.badRequest().body("No Email")
}
val current = LocalDateTime.now()
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")
val nowFormatted = current.format(formatter)
val stringCharacters = ('0'..'z').toList().toTypedArray()
val genPassword = (1..10).map { stringCharacters.random() }.joinToString("")
val idToken: String?
var existingCustomer: Customer? = customerRepository.findByEmailAndActive(newDietCustomer.email, "Y")
if (existingCustomer == null ) {
val firebase = Firebase(apiKey)
val signupResponse = firebase.signUp(newDietCustomer.email, genPassword)
?: return ResponseEntity.badRequest().body("Firebase exception ${firebase.error}")
idToken = signupResponse.idToken
val savingCustomer = Customer()
if ( serviceBeans == null ) {
serviceBeans = ServiceBeans()
}
with (savingCustomer) {
email = newDietCustomer.email
password = serviceBeans!!.passwordEncoder().encode(genPassword)
firebaseRegToken = signupResponse.idToken
firebaseUid = signupResponse.localId
dateAdd = nowFormatted
firstname = newDietCustomer.firstname
name = ""
goal = newDietCustomer.goal
fitnessLevel = newDietCustomer.fitnessLevel
birthYear = newDietCustomer.birthYear
sex = newDietCustomer.sex
}
val newCustomer = customerRepository.save(savingCustomer)
if ( newDietCustomer.weight != 0.0 ) {
val property = CustomerPropertyProperty()
with (property) {
propertyId = 1
propertyValue = newDietCustomer.weight
dateAdd= nowFormatted
goal = false
customer = newCustomer
}
newCustomer.properties.add(property)
}
if ( newDietCustomer.height != 0.0 ) {
val property = CustomerPropertyProperty()
with (property) {
propertyId = 2
propertyValue = newDietCustomer.height
dateAdd = nowFormatted
goal = false
customer = newCustomer
}
newCustomer.properties.add(property)
}
val newMembershipId = newDietCustomer.membershipId
if ( newMembershipId != 0L) {
val membership = CustomerMembership()
with(membership) {
customer = newCustomer
membershipId = newMembershipId
startDate = nowFormatted
}
newCustomer.memberships.add(membership)
}
customerRepository.save(newCustomer)
existingCustomer = newCustomer
} else {
val existingDietUser = dietUserRepository.findByCustomerId(existingCustomer.customerId)
if ( existingDietUser != null ) {
return ResponseEntity.badRequest().body("DietCustomer exists")
} else {
val newDietUser = DietUser(
customerId = existingCustomer.customerId
)
dietUserRepository.save(newDietUser)
}
idToken = existingCustomer.firebaseRegToken!!
}
// create email link
/*val activationLink = "https://diet4you.andio.hu/welcome/id=$idToken"
if ( emailTemplateService == null ) {
emailTemplateService = EmailTemplateService()
}
val html = emailTemplateService!!.getEmailBody(newDietCustomer.firstname, activationLink, "diet_registration_email")
val subject = emailTemplateService!!.getSubjectDiet()
// send email
val email = Email()
email.send(newDietCustomer.email, html, subject)*/
return ResponseEntity.ok().body(existingCustomer)
}
}

View File

@ -0,0 +1,24 @@
package com.aitrainer.api.controller.diet
import com.aitrainer.api.model.diet.DietRawMaterial
import com.aitrainer.api.repository.diet.DietRawMaterialRepository
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import java.util.*
@RestController
@RequestMapping("/api")
class DietRawMaterialController(private val dietRawMaterialRepository: DietRawMaterialRepository) {
@PostMapping("/diet_raw_material")
fun insert(@RequestBody dietRawMaterial: DietRawMaterial): ResponseEntity<*> {
return ResponseEntity.ok().body(dietRawMaterialRepository.save(dietRawMaterial))
}
@GetMapping("/diet_raw_material/{dietMealId}")
fun getByDietUserId(@PathVariable dietMealId: Long): ResponseEntity<List<DietRawMaterial>> {
val list = dietRawMaterialRepository.findByDietMealId(dietMealId)
return if (list.isEmpty()) ResponseEntity.notFound().build() else
ResponseEntity.ok().body(list)
}
}

View File

@ -0,0 +1,24 @@
package com.aitrainer.api.controller.diet
import com.aitrainer.api.model.diet.DietSensitivity
import com.aitrainer.api.repository.diet.DietSensitivityRepository
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
@RestController
@RequestMapping("api")
class DietSensitivityController(private val dietSensitivityRepository: DietSensitivityRepository) {
@PostMapping ("/diet_sensitivity")
fun insert(@RequestBody dietSensitivity: DietSensitivity): ResponseEntity<DietSensitivity> {
val newDietSensitivity = dietSensitivityRepository.save(dietSensitivity)
return ResponseEntity.ok().body(newDietSensitivity)
}
@GetMapping("/diet_sensitivity")
fun getAll(): ResponseEntity<List<DietSensitivity>> {
val list = dietSensitivityRepository.findAll()
return if (list.isEmpty()) ResponseEntity.notFound().build() else
ResponseEntity.ok().body(list)
}
}

View File

@ -0,0 +1,43 @@
package com.aitrainer.api.controller.diet
import com.aitrainer.api.model.diet.DietUserConsumption
import com.aitrainer.api.repository.diet.DietUserConsumptionRepository
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import java.util.*
@RestController
@RequestMapping("/api")
class DietUserConsumptionController(private val dietUserConsumptionRepository: DietUserConsumptionRepository) {
@PostMapping("/diet_user_consumption")
fun insert(@RequestBody dietUserConsumption: DietUserConsumption): ResponseEntity<*> {
return ResponseEntity.ok().body(dietUserConsumptionRepository.save(dietUserConsumption))
}
@PostMapping("/diet_user_consumption/{id}")
fun update(@PathVariable(value = "id") id: Long, @RequestBody dietUserConsumption: DietUserConsumption): ResponseEntity<*> {
return dietUserConsumptionRepository.findById(id).map { existingConsumption ->
val updatedConsumption: DietUserConsumption = existingConsumption.copy(
rawMaterialId = dietUserConsumption.rawMaterialId,
dateConsumption = dietUserConsumption.dateConsumption,
name = dietUserConsumption.name,
quantity = dietUserConsumption.quantity,
quantityUnit = dietUserConsumption.quantityUnit,
cal = dietUserConsumption.cal,
protein = dietUserConsumption.protein,
fat = dietUserConsumption.fat,
ch = dietUserConsumption.ch,
sugar = dietUserConsumption.sugar
)
ResponseEntity.ok().body(dietUserConsumptionRepository.save(updatedConsumption))
}.orElse(ResponseEntity.notFound().build())
}
@GetMapping("/diet_user_consumption/{dietUserId}")
fun getByDietUserId(@PathVariable dietUserId: Long): ResponseEntity<List<DietUserConsumption>> {
val list = dietUserConsumptionRepository.findByDietUserId(dietUserId)
return if (list.isEmpty()) ResponseEntity.notFound().build() else
ResponseEntity.ok().body(list)
}
}

View File

@ -0,0 +1,24 @@
package com.aitrainer.api.controller.diet
import com.aitrainer.api.model.diet.DietUser
import com.aitrainer.api.repository.diet.DietUserRepository
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
@RestController
@RequestMapping("api")
class DietUserController(private val dietUserRepository: DietUserRepository) {
@PostMapping ("/diet_user")
fun insert(@RequestBody dietUser: DietUser): ResponseEntity<DietUser> {
val newDietUser = dietUserRepository.save(dietUser)
return ResponseEntity.ok().body(newDietUser)
}
@GetMapping("/diet_user/{customerId}")
fun getByCustomerId(@PathVariable customerId: Long): ResponseEntity<DietUser> {
val dietUser = dietUserRepository.findByCustomerId(customerId)
return if (dietUser == null) ResponseEntity.notFound().build() else
ResponseEntity.ok().body(dietUser)
}
}

View File

@ -0,0 +1,24 @@
package com.aitrainer.api.controller.diet
import com.aitrainer.api.model.diet.DietUserPreference
import com.aitrainer.api.repository.diet.DietUserPreferenceRepository
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import java.util.*
@RestController
@RequestMapping("/api")
class DietUserPreferenceController(private val dietUserPreferenceRepository: DietUserPreferenceRepository) {
@PostMapping("/diet_user_preference")
fun insert(@RequestBody dietUserPreference: DietUserPreference): ResponseEntity<*> {
return ResponseEntity.ok().body(dietUserPreferenceRepository.save(dietUserPreference))
}
@GetMapping("/diet_user_preference/{dietUserId}")
fun getByDietUserId(@PathVariable dietUserId: Long): ResponseEntity<List<DietUserPreference>> {
val list = dietUserPreferenceRepository.findByDietUserId(dietUserId)
return if (list.isEmpty()) ResponseEntity.notFound().build() else
ResponseEntity.ok().body(list)
}
}

View File

@ -0,0 +1,24 @@
package com.aitrainer.api.controller.diet
import com.aitrainer.api.model.diet.DietUserSensitivity
import com.aitrainer.api.repository.diet.DietUserSensitivityRepository
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import java.util.*
@RestController
@RequestMapping("/api")
class DietUserSensitivityController(private val dietUserSensitivityRepository: DietUserSensitivityRepository) {
@PostMapping("/diet_user_sensitivity")
fun insert(@RequestBody dietUserSensitivity: DietUserSensitivity): ResponseEntity<*> {
return ResponseEntity.ok().body(dietUserSensitivityRepository.save(dietUserSensitivity))
}
@GetMapping("/diet_user_sensitivity/{dietUserId}")
fun getByDietUserId(@PathVariable dietUserId: Long): ResponseEntity<List<DietUserSensitivity>> {
val list = dietUserSensitivityRepository.findByDietUserId(dietUserId)
return if (list.isEmpty()) ResponseEntity.notFound().build() else
ResponseEntity.ok().body(list)
}
}

View File

@ -0,0 +1,31 @@
package com.aitrainer.api.controller.diet
import com.aitrainer.api.model.diet.RawMaterial
import com.aitrainer.api.repository.diet.RawMaterialRepository
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
@RestController
@RequestMapping("api")
class RawMaterialController(private val rawMaterialRepository: RawMaterialRepository) {
@PostMapping ("/raw_material")
fun insert(@RequestBody rawMaterial: RawMaterial): ResponseEntity<RawMaterial> {
val newRawMaterial = rawMaterialRepository.save(rawMaterial)
return ResponseEntity.ok().body(newRawMaterial)
}
@GetMapping("/raw_material")
fun getAll(): ResponseEntity<List<RawMaterial>> {
val list = rawMaterialRepository.findAll()
return if (list.isEmpty()) ResponseEntity.notFound().build() else
ResponseEntity.ok().body(list)
}
@GetMapping("/raw_material/{id}")
fun getByRawMaterialId(@PathVariable id: Long): ResponseEntity<RawMaterial> {
val rawMaterial = rawMaterialRepository.findByRawMaterialId(id)
return if (rawMaterial == null) ResponseEntity.notFound().build() else
ResponseEntity.ok().body(rawMaterial)
}
}

View File

@ -0,0 +1,66 @@
package com.aitrainer.api.controller.diet
import com.aitrainer.api.model.diet.Recipe
import com.aitrainer.api.repository.diet.RecipeRepository
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
@RestController
@RequestMapping("api")
class RecipeController(private val recipeRepository: RecipeRepository) {
@PostMapping ("/recipe")
fun insert(@RequestBody recipe: Recipe): ResponseEntity<Recipe> {
val newRecipe = recipeRepository.save(recipe)
return ResponseEntity.ok().body(newRecipe)
}
@PostMapping("/recipe/{id}")
fun update(@PathVariable(value = "id") id: Long, @RequestBody recipe: Recipe): ResponseEntity<Recipe> {
val existingRecipe = recipeRepository.findByRecipeId(id) ?: return ResponseEntity.notFound().build()
val updatedRecipe: Recipe = existingRecipe.copy(
name = recipe.name,
description = recipe.description,
cal = recipe.cal,
ch = recipe.ch,
fat = recipe.fat,
protein = recipe.protein,
dietUserId = recipe.dietUserId,
mealId = recipe.mealId
)
recipe.rawMaterials.forEach {
it.recipe = recipe
updatedRecipe.rawMaterials.add(it)
}
return ResponseEntity.ok().body(recipeRepository.save(updatedRecipe))
}
@GetMapping("/recipe")
fun getAll(): ResponseEntity<List<Recipe>> {
val list = recipeRepository.findAll()
return if (list.isEmpty()) ResponseEntity.notFound().build() else
ResponseEntity.ok().body(list)
}
@GetMapping("/recipe/user/{dietUserId}")
fun getByDietUserId(@PathVariable dietUserId: Long): ResponseEntity<List<Recipe>> {
val list = recipeRepository.findByDietUserId(dietUserId)
return if (list == null) ResponseEntity.notFound().build() else
ResponseEntity.ok().body(list)
}
@GetMapping("/recipe/meal/{mealId}")
fun getByMealId(@PathVariable mealId: Long): ResponseEntity<List<Recipe>> {
val list = recipeRepository.findByMealId(mealId)
return if (list == null) ResponseEntity.notFound().build() else
ResponseEntity.ok().body(list)
}
@GetMapping("/recipe/name/{name}")
fun getByName(@PathVariable name: String): ResponseEntity<List<Recipe>> {
val list = recipeRepository.findByName(name)
return if (list == null) ResponseEntity.notFound().build() else
ResponseEntity.ok().body(list)
}
}

View File

@ -0,0 +1,17 @@
package com.aitrainer.api.controller.diet
import com.aitrainer.api.model.diet.RecipeRawMaterial
import com.aitrainer.api.repository.diet.RecipeRawMaterialRepository
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
@RestController
@RequestMapping("api")
class RecipeRawMaterialController(private val recipeRawMaterialRepository: RecipeRawMaterialRepository) {
@PostMapping ("/recipe_raw_material")
fun insert(@RequestBody recipeRawMaterial: RecipeRawMaterial): ResponseEntity<RecipeRawMaterial> {
val newRecipe = recipeRawMaterialRepository.save(recipeRawMaterial)
return ResponseEntity.ok().body(recipeRawMaterial)
}
}

View File

@ -0,0 +1,32 @@
package com.aitrainer.api.controller.diet
import com.aitrainer.api.model.diet.Store
import com.aitrainer.api.repository.diet.StoreRepository
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
@RestController
@RequestMapping("api")
class StoreController(private val storeRepository: StoreRepository) {
@PostMapping ("/store")
fun insert(@RequestBody store: Store): ResponseEntity<Store> {
val newStore = storeRepository.save(store)
return ResponseEntity.ok().body(newStore)
}
@GetMapping("/store")
fun getAll(): ResponseEntity<List<Store>> {
val list = storeRepository.findAll()
return if (list.isEmpty()) ResponseEntity.notFound().build() else
ResponseEntity.ok().body(list)
}
@GetMapping("/store/{name}/{country}")
fun getByNameAndCountry(@PathVariable name: String, @PathVariable country: String ): ResponseEntity<Store> {
val store = storeRepository.findByNameAndCountry(name, country)
return if (store == null) ResponseEntity.notFound().build() else
ResponseEntity.ok().body(store)
}
}

View File

@ -0,0 +1,17 @@
package com.aitrainer.api.model
import com.google.gson.annotations.Expose
import jakarta.persistence.Entity
import jakarta.persistence.GeneratedValue
import jakarta.persistence.GenerationType
import jakarta.persistence.Id
import javax.validation.constraints.NotNull
@Entity
data class CustomerConversation(
@Expose @Id @GeneratedValue(strategy = GenerationType.IDENTITY) var id: Long = 0,
@Expose @get: NotNull val customerId: Long,
@Expose @get: NotNull val conversationDate: String = "",
@Expose @get: NotNull val question: String = "",
@Expose @get: NotNull val answer: String = ""
)

View File

@ -0,0 +1,13 @@
package com.aitrainer.api.model
import com.google.gson.annotations.Expose
import jakarta.persistence.*
import org.springframework.lang.NonNull
@Entity
data class OpenAI (
@Expose @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @get: NonNull var id: Long = 0,
@Expose @get: NonNull var question: String,
@Expose @get: NonNull var modelName: String? = null,
@Expose @get: NonNull var temperature: Double? = null,
)

View File

@ -0,0 +1,19 @@
package com.aitrainer.api.model.diet
import com.google.gson.annotations.Expose
import jakarta.persistence.*
import org.hibernate.annotations.Fetch
import org.hibernate.annotations.FetchMode
import org.jetbrains.annotations.NotNull
@Entity
data class Diet (
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Expose val dietId: Long = 0,
@Expose @get: NotNull val dietUserId: Long = 0,
@Expose @get: NotNull val dietText: String = "",
@Expose @get: NotNull val startDate: String = "",
) {
@OneToMany(cascade = [(CascadeType.ALL)], fetch = FetchType.EAGER, mappedBy = "diet")
@Fetch(value = FetchMode.SUBSELECT)
@Expose val meals: MutableList<DietMeal> = mutableListOf()
}

View File

@ -0,0 +1,23 @@
package com.aitrainer.api.model.diet
import com.google.gson.annotations.Expose
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
@Serializable
data class DietCustomer(
@Expose var firstname: String = "",
@Expose var email: String = "",
@Expose var sex: String = "m",
@Expose var goal: String = "",
@Expose var fitnessLevel: String = "beginner",
@Expose var birthYear: Int = 0,
@Expose var weight: Double = 0.0,
@Expose var height: Double = 0.0,
@Expose var membershipId: Long = 0,
){
fun fromJson(json: String): DietCustomer {
return Json.decodeFromString(serializer(), json)
}
}

View File

@ -0,0 +1,19 @@
package com.aitrainer.api.model.diet
import com.fasterxml.jackson.annotation.JsonIgnore
import com.google.gson.annotations.Expose
import jakarta.persistence.*
import org.jetbrains.annotations.NotNull
@Entity
data class DietMeal (
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Expose val id: Long = 0,
//@Expose @get: NotNull val dietId: Long = 0,
@Expose @get: NotNull val mealName: String = "",
@Expose @get: NotNull val meal: String = "",
) {
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "dietId", nullable = false)
@JsonIgnore
var diet: Diet? = null
}

View File

@ -0,0 +1,22 @@
package com.aitrainer.api.model.diet
import com.google.gson.annotations.Expose
import jakarta.persistence.*
import org.jetbrains.annotations.NotNull
@Entity
data class DietRawMaterial (
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Expose val id: Long = 0,
@Expose @get: NotNull val dietMealId: Long = 0,
@Expose @get: NotNull val rawMaterialId: Long = 0,
@Expose @get: NotNull val name: String = "",
@Expose @get: NotNull val kcalMin: Int = 0,
@Expose @get: NotNull val kcalMax: Int = 0,
@Expose @get: NotNull val proteinMin: Int = 0,
@Expose @get: NotNull val proteinMax: Int = 0,
@Expose @get: NotNull val fatMin: Int = 0,
@Expose @get: NotNull val fatMax: Int = 0,
@Expose @get: NotNull val chMin: Int = 0,
@Expose @get: NotNull val chMax: Int = 0,
@Expose @get: NotNull val sugar: Int = 0,
)

View File

@ -0,0 +1,14 @@
package com.aitrainer.api.model.diet
import com.google.gson.annotations.Expose
import jakarta.persistence.Entity
import jakarta.persistence.GeneratedValue
import jakarta.persistence.GenerationType
import jakarta.persistence.Id
import javax.validation.constraints.NotNull
@Entity
data class DietSensitivity(
@Expose @Id @GeneratedValue(strategy = GenerationType.IDENTITY) var id: Long = 0,
@Expose @get: NotNull val name: String = "",
)

View File

@ -0,0 +1,14 @@
package com.aitrainer.api.model.diet
import com.google.gson.annotations.Expose
import jakarta.persistence.Entity
import jakarta.persistence.GeneratedValue
import jakarta.persistence.GenerationType
import jakarta.persistence.Id
import javax.validation.constraints.NotNull
@Entity
data class DietUser(
@Expose @Id @GeneratedValue(strategy = GenerationType.IDENTITY) var dietUserId: Long = 0,
@Expose @get: NotNull val customerId: Long
)

View File

@ -0,0 +1,24 @@
package com.aitrainer.api.model.diet
import com.google.gson.annotations.Expose
import jakarta.persistence.*
import org.jetbrains.annotations.NotNull
import org.springframework.lang.NonNull
@Entity
data class DietUserConsumption(
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Expose val id: Long = 0,
@Expose @get: NotNull val dietUserId: Long = 0,
@Expose @get: NotNull val rawMaterialId: Long = 0,
@Expose @get: NotNull val name: String = "",
@Expose @get: NonNull var dateConsumption: String = "",
@Expose @get: NotNull val quantity: Double = 0.0,
@Expose @get: NotNull val quantityUnit: String = "",
@Expose @get: NotNull val cal: Int = 0,
@Expose @get: NotNull val protein: Double = 0.0,
@Expose @get: NotNull val fat: Double = 0.0,
@Expose @get: NotNull val ch: Double = 0.0,
@Expose @get: NotNull val sugar: Double = 0.0,
)

View File

@ -0,0 +1,16 @@
package com.aitrainer.api.model.diet
import com.google.gson.annotations.Expose
import jakarta.persistence.Entity
import jakarta.persistence.GeneratedValue
import jakarta.persistence.GenerationType
import jakarta.persistence.Id
import javax.validation.constraints.NotNull
@Entity
data class DietUserPreference(
@Expose @Id @GeneratedValue(strategy = GenerationType.IDENTITY) var id: Long = 0,
@Expose @get: NotNull val dietUserId: Long = 0,
@Expose @get: NotNull val rawMaterialId: Long = 0,
@Expose @get: NotNull val temperature: Byte = 0,
)

View File

@ -0,0 +1,15 @@
package com.aitrainer.api.model.diet
import com.google.gson.annotations.Expose
import jakarta.persistence.Entity
import jakarta.persistence.GeneratedValue
import jakarta.persistence.GenerationType
import jakarta.persistence.Id
import javax.validation.constraints.NotNull
@Entity
data class DietUserSensitivity(
@Expose @Id @GeneratedValue(strategy = GenerationType.IDENTITY) var id: Long = 0,
@Expose @get: NotNull val dietUserId: Long = 0,
@Expose @get: NotNull val sensitivityId: Long = 0,
)

View File

@ -0,0 +1,22 @@
package com.aitrainer.api.model.diet
import com.google.gson.annotations.Expose
import jakarta.persistence.*
import org.jetbrains.annotations.NotNull
@Entity
data class RawMaterial (
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Expose val id: Long = 0,
@Expose @get: NotNull val name: String = "",
@Expose @get: NotNull val description: String = "",
@Expose @get: NotNull val kcalMin: Int = 0,
@Expose @get: NotNull val kcalMax: Int = 0,
@Expose @get: NotNull val proteinMin: Int = 0,
@Expose @get: NotNull val proteinMax: Int = 0,
@Expose @get: NotNull val fatMin: Int = 0,
@Expose @get: NotNull val fatMax: Int = 0,
@Expose @get: NotNull val chMin: Int = 0,
@Expose @get: NotNull val chMax: Int = 0,
@Expose @get: NotNull val sugar: Int = 0,
@Expose @get: NotNull val storeId: Long = 0,
)

View File

@ -0,0 +1,27 @@
package com.aitrainer.api.model.diet
import com.google.gson.annotations.Expose
import jakarta.persistence.*
import org.hibernate.annotations.Fetch
import org.hibernate.annotations.FetchMode
import org.jetbrains.annotations.NotNull
@Entity
data class Recipe (
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Expose val recipeId: Long = 0,
@Expose @get: NotNull val name: String = "",
@Expose @get: NotNull val description: String = "",
@Expose @get: NotNull val cal: Int = 0,
@Expose @get: NotNull val protein: Double = 0.0,
@Expose @get: NotNull val fat: Double = 0.0,
@Expose @get: NotNull val ch: Double = 0.0,
@Expose @get: NotNull val dietUserId: Long = 0,
@Expose @get: NotNull val mealId: Long = 0,
) {
@OneToMany(cascade = [(CascadeType.ALL)], fetch = FetchType.EAGER, mappedBy = "recipe")
@Fetch(value = FetchMode.SUBSELECT)
@Expose val rawMaterials: MutableList<RecipeRawMaterial> = mutableListOf()
}

View File

@ -0,0 +1,20 @@
package com.aitrainer.api.model.diet
import com.fasterxml.jackson.annotation.JsonIgnore
import com.google.gson.annotations.Expose
import jakarta.persistence.*
import org.jetbrains.annotations.NotNull
@Entity
data class RecipeRawMaterial (
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Expose val id: Long = 0,
@Expose @get: NotNull var rawMaterialId: Int = 0,
@Expose @get: NotNull var quantity: Int = 0,
@Expose @get: NotNull var quantityUnit: String = "",
) {
@ManyToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "recipeId", nullable = false)
@JsonIgnore
var recipe: Recipe? = null
}

View File

@ -0,0 +1,13 @@
package com.aitrainer.api.model.diet
import com.google.gson.annotations.Expose
import jakarta.persistence.*
import org.jetbrains.annotations.NotNull
@Entity
data class Store (
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Expose val storeId: Long = 0,
@Expose @get: NotNull val storeName: String = "",
@Expose @get: NotNull val country: String = "",
)

View File

@ -0,0 +1,83 @@
package com.aitrainer.api.openai
import com.aallam.openai.client.OpenAI
import com.aallam.openai.api.completion.CompletionRequest
import com.aallam.openai.api.completion.TextCompletion
import com.aallam.openai.api.logging.LogLevel
import com.aallam.openai.api.model.Model
import com.aallam.openai.api.model.ModelId
import com.aallam.openai.client.OpenAIConfig
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.util.Properties
class OpenAIService(private val modelName: String?, private val temperature: Double?) {
private var openAI: OpenAI? = null
var model: Model? = null
private val properties = Properties()
init {
val inputStream = ClassLoader.getSystemResourceAsStream("application.properties")
properties.load(inputStream)
inputStream?.close()
}
private var modelId: ModelId? = null
private suspend fun connect(modelName: String) {
val config = OpenAIConfig(
token = properties.getProperty("openai.key"),
logLevel = LogLevel.All
)
openAI = OpenAI(config)
modelId = ModelId(modelName)
model = openAI!!.model(modelId!!)
}
suspend fun completion(question: String): String {
return withContext(Dispatchers.IO) {
var realModelName = "text-davinci-003"
if ( modelName != null) {
realModelName = modelName
}
var realTemperature = 0.1
if ( temperature != null ) {
realTemperature = temperature
}
if (openAI == null) {
connect(realModelName)
}
println("OpenAI Question: $question")
val completionRequest = CompletionRequest(
model = modelId!!,
prompt = question,
//echo = true,
maxTokens = 2048 - question.length,
temperature=realTemperature,
)
val completion: TextCompletion = openAI!!.completion(completionRequest)
val result = completion.choices[0].text
result
}
}
suspend fun getModels(): MutableList<String> {
return withContext(Dispatchers.IO) {
if (openAI == null) {
openAI = OpenAI(token = properties.getProperty("openai.key"))
}
val list: MutableList<String> = mutableListOf()
openAI!!.models().forEach {
println(it)
list.add(it.id.id)
}
return@withContext list
}
}
}

View File

@ -0,0 +1,10 @@
package com.aitrainer.api.repository
import com.aitrainer.api.model.CustomerConversation
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository
@Repository
interface CustomerConversationRepository : JpaRepository<CustomerConversation, Long> {
fun findByCustomerId(customerId: Long): List<CustomerConversation>
}

View File

@ -0,0 +1,10 @@
package com.aitrainer.api.repository.diet
import com.aitrainer.api.model.diet.DietRawMaterial
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository
@Repository
interface DietRawMaterialRepository : JpaRepository<DietRawMaterial, Long> {
fun findByDietMealId(dietMealId: Long): List<DietRawMaterial>
}

View File

@ -0,0 +1,14 @@
package com.aitrainer.api.repository.diet
import com.aitrainer.api.model.diet.Diet
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query
import org.springframework.stereotype.Repository
@Repository
interface DietRepository : JpaRepository<Diet, Long> {
fun findByDietUserId(dietUserId: Long): List<Diet>
@Query(" FROM Diet WHERE dietId = :dietId")
fun findByDietId(dietId: Long): Diet?
}

View File

@ -0,0 +1,6 @@
package com.aitrainer.api.repository.diet
import com.aitrainer.api.model.diet.DietSensitivity
import org.springframework.data.jpa.repository.JpaRepository
interface DietSensitivityRepository : JpaRepository<DietSensitivity, Int>

View File

@ -0,0 +1,10 @@
package com.aitrainer.api.repository.diet
import com.aitrainer.api.model.diet.DietUserConsumption
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository
@Repository
interface DietUserConsumptionRepository : JpaRepository<DietUserConsumption, Long> {
fun findByDietUserId(dietUserId: Long): List<DietUserConsumption>
}

View File

@ -0,0 +1,10 @@
package com.aitrainer.api.repository.diet
import com.aitrainer.api.model.diet.DietUserPreference
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository
@Repository
interface DietUserPreferenceRepository : JpaRepository<DietUserPreference, Long> {
fun findByDietUserId(dietUserId: Long): List<DietUserPreference>
}

View File

@ -0,0 +1,10 @@
package com.aitrainer.api.repository.diet
import com.aitrainer.api.model.diet.DietUser
import org.springframework.data.jpa.repository.JpaRepository
interface DietUserRepository : JpaRepository<DietUser, Int> {
fun findByCustomerId(customerId: Long): DietUser?
fun findByDietUserId(dietUserId: Long): DietUser?
}

View File

@ -0,0 +1,10 @@
package com.aitrainer.api.repository.diet
import com.aitrainer.api.model.diet.DietUserSensitivity
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository
@Repository
interface DietUserSensitivityRepository : JpaRepository<DietUserSensitivity, Long> {
fun findByDietUserId(dietUserId: Long): List<DietUserSensitivity>
}

View File

@ -0,0 +1,12 @@
package com.aitrainer.api.repository.diet
import com.aitrainer.api.model.diet.RawMaterial
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query
interface RawMaterialRepository : JpaRepository<RawMaterial, Int> {
@Query(" FROM RawMaterial " +
" WHERE id = :id"
)
fun findByRawMaterialId(id: Long): RawMaterial?
}

View File

@ -0,0 +1,9 @@
package com.aitrainer.api.repository.diet
import com.aitrainer.api.model.diet.RecipeRawMaterial
import org.springframework.data.jpa.repository.JpaRepository
interface RecipeRawMaterialRepository : JpaRepository<RecipeRawMaterial, Int> {
fun findByRawMaterialId(rawMaterialId: Long): List<RecipeRawMaterial>?
}

View File

@ -0,0 +1,18 @@
package com.aitrainer.api.repository.diet
import com.aitrainer.api.model.diet.Recipe
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query
interface RecipeRepository : JpaRepository<Recipe, Int> {
@Query(" FROM Recipe WHERE name like %:name%")
fun findByName(name: String): List<Recipe>?
fun findByDietUserId(dietUserId: Long): List<Recipe>?
@Query(" FROM Recipe WHERE recipeId = :recipeId")
fun findByRecipeId(recipeId: Long): Recipe?
@Query(" FROM Recipe WHERE mealId = :mealId")
fun findByMealId(mealId: Long): List<Recipe>?
}

View File

@ -0,0 +1,11 @@
package com.aitrainer.api.repository.diet
import com.aitrainer.api.model.diet.Store
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query
interface StoreRepository : JpaRepository<Store, Int> {
@Query(" FROM Store WHERE storeName = :name and country = :country")
fun findByNameAndCountry(name: String, country: String ): Store?
}

View File

@ -3,9 +3,6 @@ package com.aitrainer.api.service
import java.util.Properties import java.util.Properties
import jakarta.mail.* import jakarta.mail.*
import jakarta.mail.internet.* import jakarta.mail.internet.*
import org.jasypt.encryption.StringEncryptor
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig
class Email { class Email {
@ -19,23 +16,9 @@ class Email {
put("mail.smtp.port", "587") put("mail.smtp.port", "587")
} }
fun getEncryptor(): StringEncryptor {
val encryptor = PooledPBEStringEncryptor()
val config = SimpleStringPBEConfig()
config.password = "workouttest"
config.algorithm = "PBEWithMD5AndDES"
config.setKeyObtentionIterations("1000")
config.setPoolSize("1")
config.providerName = "SunJCE"
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator")
config.stringOutputType = "base64"
encryptor.setConfig(config)
return encryptor
}
val session: Session = Session.getInstance(properties, object : Authenticator() { val session: Session = Session.getInstance(properties, object : Authenticator() {
override fun getPasswordAuthentication(): PasswordAuthentication { override fun getPasswordAuthentication(): PasswordAuthentication {
return PasswordAuthentication("service@workouttest.com", getEncryptor().decrypt(encodedPassword)) return PasswordAuthentication("service@workouttest.com", Encryptor.getEncryptor().decrypt(encodedPassword))
} }
}) })
@ -47,7 +30,7 @@ class Email {
} }
val bodyPart = MimeBodyPart().apply { val bodyPart = MimeBodyPart().apply {
setContent(emailBody, "text/html") setContent(emailBody, "text/html; charset=UTF-8")
} }
val multipart = MimeMultipart().apply { val multipart = MimeMultipart().apply {

View File

@ -10,14 +10,15 @@ class EmailTemplateService {
@Autowired @Autowired
private var templateEngine: TemplateEngine? = null private var templateEngine: TemplateEngine? = null
fun getEmailBody(firstname: String, activationLink: String): String { fun getEmailBody(firstname: String, activationLink: String, template: String): String {
val context = Context() val context = Context()
context.setVariable("firstname", firstname) context.setVariable("firstname", firstname)
context.setVariable("activationLink", activationLink) context.setVariable("activationLink", activationLink)
if ( templateEngine == null) { if ( templateEngine == null) {
templateEngine = TemplateEngine() templateEngine = TemplateEngine()
} }
return templateEngine!!.process("registration_email", context)
return templateEngine!!.process(template, context)
} }
fun getSubject(): String { fun getSubject(): String {
@ -27,5 +28,12 @@ class EmailTemplateService {
} }
return templateEngine!!.process("registration_subject", context) return templateEngine!!.process("registration_subject", context)
} }
fun getSubjectDiet(): String {
val context = Context()
if ( templateEngine == null) {
templateEngine = TemplateEngine()
}
return templateEngine!!.process("diet_registration_subject", context)
}
} }

View File

@ -0,0 +1,21 @@
package com.aitrainer.api.service
import org.jasypt.encryption.StringEncryptor
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig
object Encryptor {
fun getEncryptor(): StringEncryptor {
val encryptor = PooledPBEStringEncryptor()
val config = SimpleStringPBEConfig()
config.password = "workouttest"
config.algorithm = "PBEWithMD5AndDES"
config.setKeyObtentionIterations("1000")
config.setPoolSize("1")
config.providerName = "SunJCE"
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator")
config.stringOutputType = "base64"
encryptor.setConfig(config)
return encryptor
}
}

View File

@ -2,18 +2,22 @@ package com.aitrainer.api.service
import com.aitrainer.api.model.firebase_response.SignupResponse import com.aitrainer.api.model.firebase_response.SignupResponse
import com.google.gson.Gson import com.google.gson.Gson
import org.json.JSONObject
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Service
import java.net.URI import java.net.URI
import java.net.http.HttpClient import java.net.http.HttpClient
import java.net.http.HttpRequest import java.net.http.HttpRequest
import java.net.http.HttpResponse import java.net.http.HttpResponse
import java.nio.charset.StandardCharsets import java.nio.charset.StandardCharsets
import org.json.JSONObject import java.util.*
class Firebase { @Service
private val apiKey: String = "AIzaSyCUXBWV3_qzvV__ZWZA1siHftrrJpjDKh4" class Firebase(@Value("\${firebase.key}") private val apiKey: String) {
private val firebaseBaseUrl: String = "https://identitytoolkit.googleapis.com/v1/accounts" private val firebaseBaseUrl: String = "https://identitytoolkit.googleapis.com/v1/accounts"
var statusCode: Int = 0 var statusCode: Int = 0
var error: String = "" var error: String = ""
fun signUp(email: String, password: String): SignupResponse? { fun signUp(email: String, password: String): SignupResponse? {
val json = JSONObject() val json = JSONObject()
@ -42,6 +46,7 @@ class Firebase {
} }
private fun call(command: String, postData: String): String { private fun call(command: String, postData: String): String {
val apiKey = this.apiKey
val url = URI.create("$firebaseBaseUrl:$command?key=$apiKey") val url = URI.create("$firebaseBaseUrl:$command?key=$apiKey")
// Create the HTTP request object // Create the HTTP request object

View File

@ -0,0 +1,26 @@
#spring.config.activate.on-profile=dev,test,prod,prodtest
spring.config.use-legacy-processing = true
## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
#spring.datasource.url = jdbc:mysql://localhost:3306/aitrainer?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false
spring.datasource.url = jdbc:mysql://localhost:3306/diet4you?serverTimezone=CET&useSSL=false&characterEncoding=UTF-8&allowMultiQueries=true
spring.datasource.username = aitrainer
spring.datasource.password = ENC(WZplPYr8WmrLHshesY4T6oXplK3MlUVJ)
## Hibernate Properties
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect
logging.config=classpath:logback-spring.xml
logging.file=logs
# if the database structure has been changed, increment this version number
application.version=1.2.0
jwt.secret=aitrainer
openai.key=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
firebase.key=AIzaSyBLn7Bz73Z1hB-OhqphBDsskOyGmpI7J8E
spring.mail.properties.mail.mime.charset=UTF-8

View File

@ -0,0 +1,22 @@
spring.config.activate.on-profile=dietprod
spring.config.use-legacy-processing = true
## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.url = jdbc:mysql://mariadb-shared.db.svc.cluster.local:3306/diet4you?serverTimezone=CET&useSSL=true&characterEncoding=UTF-8&allowPublicKeyRetrieval=true&allowMultiQueries=true
spring.datasource.username = aitrainer
spring.datasource.password = ENC(WZplPYr8WmrLHshesY4T6oXplK3MlUVJ)
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect
logging.config=classpath:logback-spring.xml
logging.file=logs
# if the database structue has been changed, increment this version number
application.version=1.2.0
jwt.secret=aitrainer
firebase.key=AIzaSyCUXBWV3_qzvV__ZWZA1siHftrrJpjDKh4
openai.key=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

View File

@ -14,6 +14,9 @@ logging.config=classpath:logback-spring.xml
logging.file=logs logging.file=logs
# if the database structue has been changed, increment this version number # if the database structue has been changed, increment this version number
application.version=1.1.0 application.version=1.2.0
jwt.secret=aitrainer jwt.secret=aitrainer
firebase.key=AIzaSyCUXBWV3_qzvV__ZWZA1siHftrrJpjDKh4
openai.key=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

View File

@ -17,6 +17,10 @@ logging.config=classpath:logback-spring.xml
logging.file=logs logging.file=logs
# if the database structure has been changed, increment this version number # if the database structure has been changed, increment this version number
application.version=1.1.0 application.version=1.2.0
jwt.secret=aitrainer jwt.secret=aitrainer
openai.key=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
spring.mail.properties.mail.mime.charset=UTF-8
firebase.key=AIzaSyCUXBWV3_qzvV__ZWZA1siHftrrJpjDKh4

View File

@ -0,0 +1,25 @@
<html lang="hu" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Registration</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p th:text="'Szia ' + ${firstname} + '!'">Szia [firstname]!</p>
<p>
Üdvözlünk a Diet 4 You (Diéta Neked) tagjai között! Örülünk, hogy velünk vagy. Az étrended a Diet4You zárt felületén tudod elérni. A belépéshez használd ezt a linket:<br/><br/>
<a th:href="${activationLink}" th:text="${activationLink}">${activationLink}</a>
</p>
<p>
Kérlek, kattints a linkre a fiókod aktiválásához. Ha bármilyen problémád van, ne habozz velünk kapcsolatba lépni.
</p>
<p>
Köszönjük, hogy velünk dolgozol.
</p>
<p>
Üdvözlettel,<br>
Diéta Neked Csapata<br/>
Diet 4 You Team<br/>
mailto: diet4you@andio.hu<br/>
</p>
</body>
</html>

View File

@ -0,0 +1 @@
[Diet4You] Üdv a céltudatosok között!

View File

@ -1,6 +1,10 @@
<html lang="hu" xmlns:th="http://www.thymeleaf.org"> <html lang="hu" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Registration</title>
<meta charset="utf-8" />
</head>
<body> <body>
<p th:text="'Szia ' + ${firstname}">Szia [firstname]!</p> <p th:text="'Szia ' + ${firstname} + '!'">Szia [firstname]!</p>
<p> <p>
Üdvözlünk a Workout Test Club tagjai között! Örülünk, hogy velünk vagy. A Workout Test Club-ba való belépéshez használad ezt a linket:<br/><br/> Üdvözlünk a Workout Test Club tagjai között! Örülünk, hogy velünk vagy. A Workout Test Club-ba való belépéshez használad ezt a linket:<br/><br/>
<a th:href="${activationLink}" th:text="${activationLink}">${activationLink}</a> <a th:href="${activationLink}" th:text="${activationLink}">${activationLink}</a>

View File

@ -2,7 +2,9 @@ package com.aitrainer.api.test
import com.aitrainer.api.controller.CustomerPackageController import com.aitrainer.api.controller.CustomerPackageController
import com.aitrainer.api.model.* import com.aitrainer.api.model.*
import com.aitrainer.api.model.diet.*
import com.aitrainer.api.repository.* import com.aitrainer.api.repository.*
import com.aitrainer.api.repository.diet.*
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
@ -45,6 +47,113 @@ class AppCustomerPackageTest {
@Autowired @Autowired
private lateinit var customerMembershipRepository: CustomerMembershipRepository private lateinit var customerMembershipRepository: CustomerMembershipRepository
@Autowired
private lateinit var dietRepository: DietRepository
@Autowired
private lateinit var dietRawMaterialRepository: DietRawMaterialRepository
@Autowired
private lateinit var dietUserConsumptionRepository: DietUserConsumptionRepository
@Autowired
private lateinit var dietUserRepository: DietUserRepository
@Autowired
private lateinit var dietUserPreferenceRepository: DietUserPreferenceRepository
@Autowired
private lateinit var dietUserSensitivityRepository: DietUserSensitivityRepository
@Autowired
private lateinit var customerConversationRepository: CustomerConversationRepository
@Test
fun dietCustomerPackageTest() {
val gson = Gson()
val controller = CustomerPackageController(
customerRepository,
customerExerciseDeviceRepository,
exercisesRepository,
purchaseRepository,
customerPropertyRepository,
exerciseResultRepository,
customerActivityRepository,
customerTrainingPlanRepository,
customerMembershipRepository,
dietRepository,
dietRawMaterialRepository,
dietUserConsumptionRepository,
dietUserRepository,
dietUserPreferenceRepository,
dietUserSensitivityRepository,
customerConversationRepository
)
val response = controller.getDietCustomerPackageData(2)
assertEquals(response.statusCode, HttpStatus.OK)
val dietCustomerPackageJson: String = response.body as String
assertTrue(dietCustomerPackageJson.isNotEmpty())
val packages = dietCustomerPackageJson.split("|||").toTypedArray()
packages.forEach {
val record = it.split("***")
print(record[0] + "\n")
when {
record[0] == Diet::class.simpleName -> {
val dietJson: String = record[1]
val type = object : TypeToken<List<Diet?>?>() {}.type
val list: List<Diet> = gson.fromJson(dietJson, type)
assertEquals(list[0].dietText, "Test diet text")
assertEquals(list[0].meals[0].mealName, "monday|breakfast")
}
record[0] == DietRawMaterial::class.simpleName -> {
val dietRawMaterialJson: String = record[1]
val type = object : TypeToken<List<DietRawMaterial?>?>() {}.type
val list: List<DietRawMaterial> = gson.fromJson(dietRawMaterialJson, type)
assertEquals(list[0].name, "Tükörtojás")
assertEquals(list[0].kcalMin, 70)
}
record[0] == DietUserConsumption::class.simpleName -> {
val dietUserConsumptionJson: String = record[1]
val type = object : TypeToken<List<DietUserConsumption?>?>() {}.type
val list: List<DietUserConsumption> = gson.fromJson(dietUserConsumptionJson, type)
assertEquals(list[0].name, "Tükörtojás")
assertEquals(list[0].quantity, 120.0)
assertEquals(list[0].ch, 1.0)
}
record[0] == DietUser::class.simpleName -> {
val dietUserJson: String = record[1]
val type = object : TypeToken<DietUser?>() {}.type
val list: DietUser = gson.fromJson(dietUserJson, type)
assertEquals(list.customerId, 764)
}
record[0] == DietUserPreference::class.simpleName -> {
val dietUserPreferenceJson: String = record[1]
val type = object : TypeToken<List<DietUserPreference?>?>() {}.type
val list: List<DietUserPreference> = gson.fromJson(dietUserPreferenceJson, type)
assertEquals(list[0].dietUserId, 5)
assertEquals(list[0].temperature, -1)
}
record[0] == DietUserSensitivity::class.simpleName -> {
val dietUserSensitivityJson: String = record[1]
val type = object : TypeToken<List<DietUserSensitivity?>?>() {}.type
val list: List<DietUserSensitivity> = gson.fromJson(dietUserSensitivityJson, type)
assertEquals(list[0].dietUserId, 5)
assertEquals(list[0].sensitivityId, 1)
}
}
}
}
@Test @Test
fun customerClubPackageTest() { fun customerClubPackageTest() {
val gson = Gson() val gson = Gson()
@ -58,7 +167,14 @@ class AppCustomerPackageTest {
exerciseResultRepository, exerciseResultRepository,
customerActivityRepository, customerActivityRepository,
customerTrainingPlanRepository, customerTrainingPlanRepository,
customerMembershipRepository customerMembershipRepository,
dietRepository,
dietRawMaterialRepository,
dietUserConsumptionRepository,
dietUserRepository,
dietUserPreferenceRepository,
dietUserSensitivityRepository,
customerConversationRepository
) )
val response = controller.getCustomerClubPackageData(90) val response = controller.getCustomerClubPackageData(90)
@ -106,7 +222,16 @@ class AppCustomerPackageTest {
val controller = CustomerPackageController(customerRepository, customerExerciseDeviceRepository, val controller = CustomerPackageController(customerRepository, customerExerciseDeviceRepository,
exercisesRepository, purchaseRepository, customerPropertyRepository, exercisesRepository, purchaseRepository, customerPropertyRepository,
exerciseResultRepository, customerActivityRepository, customerTrainingPlanRepository, customerMembershipRepository ) exerciseResultRepository, customerActivityRepository, customerTrainingPlanRepository,
customerMembershipRepository,
dietRepository,
dietRawMaterialRepository,
dietUserConsumptionRepository,
dietUserRepository,
dietUserPreferenceRepository,
dietUserSensitivityRepository,
customerConversationRepository)
var response: ResponseEntity<*> = controller.getCustomerPackageData(91) var response: ResponseEntity<*> = controller.getCustomerPackageData(91)
assertEquals(response.statusCode, HttpStatus.NOT_FOUND) assertEquals(response.statusCode, HttpStatus.NOT_FOUND)

View File

@ -2,7 +2,12 @@ package com.aitrainer.api.test
import com.aitrainer.api.controller.PackageController import com.aitrainer.api.controller.PackageController
import com.aitrainer.api.model.* import com.aitrainer.api.model.*
import com.aitrainer.api.model.diet.DietSensitivity
import com.aitrainer.api.model.diet.RawMaterial
import com.aitrainer.api.model.diet.Recipe
import com.aitrainer.api.model.diet.Store
import com.aitrainer.api.repository.* import com.aitrainer.api.repository.*
import com.aitrainer.api.repository.diet.*
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.TestInstance
import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Autowired
@ -56,6 +61,105 @@ class AppPackageTest {
@Autowired @Autowired
private lateinit var membershipRepository: MembershipRepository private lateinit var membershipRepository: MembershipRepository
@Autowired
private lateinit var dietSensitivityRepository: DietSensitivityRepository
@Autowired
private lateinit var rawMaterialRepository: RawMaterialRepository
@Autowired
private lateinit var recipeRepository: RecipeRepository
@Autowired
private lateinit var storeRepository: StoreRepository
@Test
fun testDietPackage() {
val gson = Gson()
val controller = PackageController(
exerciseAbilityRepository,
exerciseTypeRepository,
exerciseTreeRepository,
propertyRepository,
productRepository,
exerciseDeviceRepository,
exerciseTreeParentsRepository,
exercisePlanTemplateRepository,
evaluationRepository,
sportRepository,
tutorialRepository,
descriptionRepository,
faqRepository,
trainingPlanRepository,
splitTestsRepository,
trainingPlanDayRepository,
appTextRepository,
trainingProgramRepository,
membershipRepository,
storeRepository,
recipeRepository,
rawMaterialRepository,
dietSensitivityRepository,
)
val response: ResponseEntity<*> = controller.getDietPackageData()
val dietPackageJson: String = response.body as String
assertTrue(dietPackageJson.isNotEmpty())
val packages = dietPackageJson.split("|||").toTypedArray()
packages.forEach {
val record = it.split("***")
if (record[0] == Membership::class.simpleName) {
val membershipJson: String = record[1]
val type = object : TypeToken<List<Membership?>?>() {}.type
val listMembership: List<Membership> = gson.fromJson(membershipJson, type)
assertTrue(listMembership.isNotEmpty())
} else if ( record[0] == Store::class.simpleName) {
val storeJson: String = record[1]
val type = object : TypeToken<List<Store?>?>() {}.type
val listStore: List<Store> = gson.fromJson(storeJson, type)
assertTrue(listStore.isNotEmpty())
assertEquals(listStore[0].storeName, "Tesco")
assertEquals(listStore[0].country, "HU")
assertEquals(listStore[3].country, "DE")
assertEquals(listStore[3].storeName, "Aldi")
} else if ( record[0] == Recipe::class.simpleName) {
val recipeJson: String = record[1]
val type = object : TypeToken<List<Recipe?>?>() {}.type
val list: List<Recipe> = gson.fromJson(recipeJson, type)
assertTrue(list.isNotEmpty())
assertEquals(list[0].name, "Bableves")
assertEquals(list[0].cal, 180)
assertEquals(list[0].dietUserId, 4)
assertEquals(list[2].name, "Borsóleves")
assertEquals(list[2].protein, 45.0)
assertEquals(list[2].dietUserId, 1)
} else if ( record[0] == RawMaterial::class.simpleName) {
val rawMaterialJson: String = record[1]
val type = object : TypeToken<List<RawMaterial?>?>() {}.type
val list: List<RawMaterial> = gson.fromJson(rawMaterialJson, type)
assertTrue(list.isNotEmpty())
assertEquals(list[0].name, "Tükörtojás")
assertEquals(list[0].kcalMin, 70)
assertEquals(list[0].proteinMax, 25)
assertEquals(list[0].storeId, 4)
assertEquals(list[1].name, "Tigris buci")
} else if ( record[0] == DietSensitivity::class.simpleName) {
val dietSensitivityJson: String = record[1]
val type = object : TypeToken<List<DietSensitivity?>?>() {}.type
val list: List<DietSensitivity> = gson.fromJson(dietSensitivityJson, type)
assertTrue(list.isNotEmpty())
assertEquals(list[0].name, "Nut Allergy")
assertEquals(list[1].name, "Penicillin sensitivity")
}
}
}
@Test @Test
fun testClubPackage() { fun testClubPackage() {
val gson = Gson() val gson = Gson()
@ -79,7 +183,11 @@ class AppPackageTest {
trainingPlanDayRepository, trainingPlanDayRepository,
appTextRepository, appTextRepository,
trainingProgramRepository, trainingProgramRepository,
membershipRepository membershipRepository,
storeRepository,
recipeRepository,
rawMaterialRepository,
dietSensitivityRepository,
) )
val response: ResponseEntity<*> = controller.getClubPackageData() val response: ResponseEntity<*> = controller.getClubPackageData()
@ -135,7 +243,11 @@ class AppPackageTest {
trainingPlanDayRepository, trainingPlanDayRepository,
appTextRepository, appTextRepository,
trainingProgramRepository, trainingProgramRepository,
membershipRepository membershipRepository,
storeRepository,
recipeRepository,
rawMaterialRepository,
dietSensitivityRepository,
) )
val response: ResponseEntity<*> = controller.getPackageData() val response: ResponseEntity<*> = controller.getPackageData()

View File

@ -0,0 +1,20 @@
package com.aitrainer.api.test
import com.aitrainer.api.controller.OpenAIController
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.springframework.boot.test.context.SpringBootTest
@SpringBootTest
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class CompletionTest {
@Test
fun testCompletion() {
val openAIController = OpenAIController()
val response = openAIController.getOpenAIResponse("Mennyi 3 darab közepes tükörtojás kalóriaértéke? Csak egy szám intervallumértéket adj vissza eredményként")
println(response)
// response = openAIController.getOpenAIResponse("Az utolsó 5 kérdésemre: Mennyi 3 darab tükörtojás kalóriaértéke? nagy szórású intervallumokat adtál vissza. Hogyan tudom pontosítani a kérdést?")
// println(response)
}
}

View File

@ -0,0 +1,68 @@
package com.aitrainer.api.test
import com.aitrainer.api.model.CustomerConversation
import com.google.gson.Gson
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.MediaType
import org.springframework.test.context.junit.jupiter.SpringExtension
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
import org.springframework.test.web.servlet.result.MockMvcResultMatchers
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
@ExtendWith(SpringExtension::class)
@SpringBootTest
@AutoConfigureMockMvc
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class CustomerConversationTest {
@Autowired
private lateinit var mockMvc: MockMvc
private var authToken: String? = ""
@BeforeAll
fun initTest() {
authToken = Tokenizer.getToken()
}
@Test
fun `insert customer conversation`() {
val customerConversation = CustomerConversation(1, 123, "2022-01-01 10:10:10", "What's up?", "Not much.")
val gson = Gson()
mockMvc.perform(
post("/api/customer_conversation")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(gson.toJson(customerConversation))
)
.andExpect(status().isOk)
.andExpect(content().json("""
{
"id": 1,
"customerId": 123,
"conversationDate": "2022-01-01 10:10:10",
"question": "What's up?",
"answer": "Not much."
}
""".trimIndent()))
}
@Test
fun `get customer conversation by customer id`() {
mockMvc.perform(get("/api/customer_conversation/123")
.header("Authorization", "Bearer $authToken"))
.andExpect(status().isOk)
.andExpect(MockMvcResultMatchers.jsonPath("$.[0].customerId").value(123))
.andExpect(MockMvcResultMatchers.jsonPath("$.[0].answer").value("Not much."))
}
}

View File

@ -1,26 +1,31 @@
package com.aitrainer.api.test package com.aitrainer.api.test
import com.aitrainer.api.controller.CustomerMembershipController import com.aitrainer.api.controller.CustomerMembershipController
import com.aitrainer.api.model.Customer
import com.aitrainer.api.model.CustomerMembership
import com.aitrainer.api.repository.CustomerMembershipRepository import com.aitrainer.api.repository.CustomerMembershipRepository
import com.aitrainer.api.repository.CustomerRepository import com.aitrainer.api.repository.CustomerRepository
import com.google.gson.Gson
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.TestInstance
import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.HttpStatus import org.springframework.test.web.servlet.MockMvc
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertTrue import kotlin.test.assertTrue
@SpringBootTest @SpringBootTest
@AutoConfigureMockMvc
@TestInstance(TestInstance.Lifecycle.PER_CLASS) @TestInstance(TestInstance.Lifecycle.PER_CLASS)
class CustomerMembershipTest { class CustomerMembershipTest {
@Autowired @Autowired
private lateinit var customerMembershipRepository: CustomerMembershipRepository private lateinit var customerMembershipRepository: CustomerMembershipRepository
@Autowired lateinit var customerRepository: CustomerRepository @Autowired
lateinit var customerRepository: CustomerRepository
@Autowired
private lateinit var mockMvc: MockMvc
@Test @Test
@ -37,7 +42,26 @@ class CustomerMembershipTest {
@Test @Test
fun testInsert() { fun testInsert() {
/* val foundCustomer: Customer? = customerRepository.findByCustomerIdAndActive(90, "Y") /* val authToken = Tokenizer.getToken()
val foundCustomer: Customer? = customerRepository.findByCustomerIdAndActive(90, "Y")
val customerMembership = CustomerMembership(
membershipId = 3,
startDate = "2023-01-30",
)
customerMembership.customer = foundCustomer
mockMvc.perform(
MockMvcRequestBuilders.post("/api/customer_membership")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(toJson(customerMembership))
)
.andExpect(MockMvcResultMatchers.status().isOk)
.andExpect(MockMvcResultMatchers.jsonPath("$.membership").value(3))
.andReturn()
val foundCustomer: Customer? = customerRepository.findByCustomerIdAndActive(90, "Y")
val customerMembership = CustomerMembership( val customerMembership = CustomerMembership(
membershipId = 3, membershipId = 3,
startDate = "2023-01-30", startDate = "2023-01-30",
@ -53,4 +77,9 @@ class CustomerMembershipTest {
customerMembershipRepository.delete(newCustomerMembership) // does not delete the customer_membership customerMembershipRepository.delete(newCustomerMembership) // does not delete the customer_membership
*/ */
} }
private fun toJson(obj: Any): String {
val str = Gson().toJson(obj)
return str
}
} }

View File

@ -5,14 +5,23 @@ import com.aitrainer.api.model.Customer
import com.aitrainer.api.model.User import com.aitrainer.api.model.User
import com.aitrainer.api.repository.CustomerRepository import com.aitrainer.api.repository.CustomerRepository
import com.aitrainer.api.service.ServiceBeans import com.aitrainer.api.service.ServiceBeans
import com.google.gson.Gson
import org.json.JSONObject
import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.TestInstance
import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.HttpHeaders import org.springframework.http.HttpHeaders
import org.springframework.http.HttpStatus import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity import org.springframework.http.ResponseEntity
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.MvcResult
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.result.MockMvcResultMatchers
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -21,11 +30,15 @@ import kotlin.test.assertTrue
@SpringBootTest @SpringBootTest
@TestInstance(TestInstance.Lifecycle.PER_CLASS) @TestInstance(TestInstance.Lifecycle.PER_CLASS)
@AutoConfigureMockMvc
class CustomerTests { class CustomerTests {
@Autowired
private lateinit var mockMvc: MockMvc
@Autowired @Autowired
private var serviceBean: ServiceBeans? = null private var serviceBean: ServiceBeans? = null
private var authToken: String? = ""
@BeforeAll @BeforeAll
fun init() { fun init() {
if ( serviceBean == null ) { serviceBean = ServiceBeans() } if ( serviceBean == null ) { serviceBean = ServiceBeans() }
@ -233,10 +246,10 @@ class CustomerTests {
} }
@Test @Test
fun testClubRegistration() { fun testClubRegistration(@Value("\${firebase.key}") apiKey: String) {
val json = "{\"firstname\":\"Tib\", \"email\": \"mr@andio.biz\", \"goal\": \"shape\", \"fitnessLevel\": \"advanced\", \"weight\": 85}" val json = "{\"firstname\":\"Tib\", \"email\": \"mr@andio.biz\", \"goal\": \"shape\", \"fitnessLevel\": \"advanced\", \"weight\": 85}"
val controller = CustomerController(customerRepository) val controller = CustomerController(customerRepository)
val response: ResponseEntity<*> = controller.clubRegistration(json) val response: ResponseEntity<*> = controller.clubRegistration(json, apiKey)
assertEquals(response.statusCode, HttpStatus.BAD_REQUEST) assertEquals(response.statusCode, HttpStatus.BAD_REQUEST)
} }
@ -315,4 +328,35 @@ class CustomerTests {
} }
@Test
fun `insert recipes successfully`() {
authToken = Tokenizer.getToken()
val customer = Customer(
name = "Kadarka",
firstname = "József",
age = 32,
dateAdd = "2023-02-09 08:00",
birthYear = 1987
)
val mvcResult: MvcResult = mockMvc.perform(
MockMvcRequestBuilders.post("/api/customers")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(toJson(customer))
)
.andExpect(MockMvcResultMatchers.status().isOk)
.andExpect(MockMvcResultMatchers.jsonPath("$.name").value("Kadarka"))
.andExpect(MockMvcResultMatchers.jsonPath("$.age").value(32))
.andExpect(MockMvcResultMatchers.jsonPath("$.birthYear").value(1987))
.andReturn()
val customerId = JSONObject(mvcResult.response.contentAsString).getInt("customerId")
println("MockCustomer Id $customerId")
assertTrue(customerId > 0)
}
private fun toJson(obj: Any): String {
return Gson().toJson(obj)
}
} }

View File

@ -26,7 +26,7 @@ class EmailTest {
@Test @Test
fun testTemplate() { fun testTemplate() {
val html = emailTemplateService.getEmailBody("Tibor", "https://very.link") val html = emailTemplateService.getEmailBody("Tibor", "https://very.link", "registration_email")
print(html) print(html)
assertTrue (html.isNotEmpty()) assertTrue (html.isNotEmpty())
assertTrue(html.contains("Tibor")) assertTrue(html.contains("Tibor"))

View File

@ -4,6 +4,7 @@ import com.aitrainer.api.service.Firebase
import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.TestInstance
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.SpringBootTest
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertTrue import kotlin.test.assertTrue
@ -16,11 +17,12 @@ class FirebaseTest {
@BeforeAll @BeforeAll
fun tearUp() { fun tearUp() {
this.firebase = Firebase()
} }
@Test @Test
fun testAuth() { fun testAuth(@Value("\${firebase.key}") apiKey: String) {
this.firebase = Firebase(apiKey)
val email = "user@exemple.com" val email = "user@exemple.com"
val password = "verystrictpassword1" val password = "verystrictpassword1"
val signupResponse = firebase.signUp(email, password) val signupResponse = firebase.signUp(email, password)

View File

@ -0,0 +1,38 @@
package com.aitrainer.api.test
import com.aitrainer.api.service.Encryptor
import org.json.JSONObject
import org.springframework.http.HttpEntity
import org.springframework.http.HttpHeaders
import org.springframework.http.MediaType
import org.springframework.web.client.RestTemplate
object Tokenizer {
fun getToken(): String {
val headers = HttpHeaders().apply {
contentType = MediaType.APPLICATION_JSON
put("Authorization", arrayOf("1").toMutableList())
}
val restTemplate = RestTemplate()
val username = "bosi"
val password = Encryptor.getEncryptor().decrypt("WZplPYr8WmrLHshesY4T6oXplK3MlUVJ")
val body = JSONObject().apply {
put("username", username)
put("password", password)
}.toString()
val request = HttpEntity(body, headers)
val response = restTemplate.postForEntity("https://apitest.workouttest.org/api/authenticate", request, String::class.java)
if ( response.body == null) {
throw Exception("No authentication")
}
val jsonObject = JSONObject(response.body!!)
return jsonObject.getString("token")
}
}

View File

@ -0,0 +1,132 @@
package com.aitrainer.api.test.diet
import com.aitrainer.api.model.diet.DietUserConsumption
import com.aitrainer.api.test.Tokenizer
import com.google.gson.Gson
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.MediaType
import org.springframework.test.context.junit.jupiter.SpringExtension
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.*
@ExtendWith(SpringExtension::class)
@SpringBootTest
@AutoConfigureMockMvc
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class DietConsumptionTest {
@Autowired
private lateinit var mockMvc: MockMvc
private val dietUserConsumption = DietUserConsumption(
id = 1,
dietUserId = 5,
rawMaterialId = 10,
name = "Tükörtojás",
dateConsumption = "2023-02-08 17:00",
quantity = 120.0,
quantityUnit = "g",
cal = 70,
protein = 32.0,
fat = 11.0,
ch = 1.0,
sugar = 0.0,
)
private var dietUserConsumption2 = DietUserConsumption(
id = 2,
dietUserId = 5,
rawMaterialId = 11,
name = "Rozs zsömle",
dateConsumption = "2023-02-08 16:00",
quantity = 80.0,
quantityUnit = "g",
cal = 60,
protein = 11.0,
fat = 4.0,
ch = 34.0,
sugar = 8.0,
)
private var authToken: String? = ""
@BeforeAll
fun initTest() {
authToken = Tokenizer.getToken()
}
@Test
fun `insert dietUserConsumption successfully`() {
mockMvc.perform(
MockMvcRequestBuilders.post("/api/diet_user_consumption")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(toJson(dietUserConsumption))
)
.andExpect(status().isOk)
.andExpect(jsonPath("$.dietUserId").value(5))
.andExpect(jsonPath("$.rawMaterialId").value(10))
.andExpect(jsonPath("$.protein").value(32.0))
mockMvc.perform(
MockMvcRequestBuilders.post("/api/diet_user_consumption")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(toJson(dietUserConsumption2))
).andExpect(status().isOk)
val dietUserConsumption3 = DietUserConsumption(
id = 2,
dietUserId = 5,
rawMaterialId = 11,
name = "Rozs zsömle",
dateConsumption = "2023-02-08 16:30",
quantity = 80.0,
quantityUnit = "g",
cal = 65, //**
protein = 11.0,
fat = 4.0,
ch = 44.0, //**
sugar = 8.0,
)
mockMvc.perform(
MockMvcRequestBuilders.post("/api/diet_user_consumption/2")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(toJson(dietUserConsumption3))
)
.andExpect(status().isOk)
.andExpect(jsonPath("$.dietUserId").value(5))
.andExpect(jsonPath("$.rawMaterialId").value(11))
.andExpect(jsonPath("$.sugar").value(8.0))
.andExpect(jsonPath("$.cal").value(65.0))
.andExpect(jsonPath("$.ch").value(44.0))
// Act & Assert
mockMvc.perform(get("/api/diet_user_consumption/5")
.header("Authorization", "Bearer $authToken")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk)
.andExpect(jsonPath("$.[0].name").value("Tükörtojás"))
.andExpect(jsonPath("$.[1].name").value("Rozs zsömle"))
.andExpect(jsonPath("$.[1].ch").value(44))
}
private fun toJson(obj: Any): String {
return Gson().toJson(obj)
}
}

View File

@ -0,0 +1,80 @@
package com.aitrainer.api.test.diet
import com.aitrainer.api.model.diet.DietRawMaterial
import com.aitrainer.api.test.Tokenizer
import com.google.gson.Gson
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.MediaType
import org.springframework.test.context.junit.jupiter.SpringExtension
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.*
@ExtendWith(SpringExtension::class)
@SpringBootTest
@AutoConfigureMockMvc
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class DietRawMaterialTest {
@Autowired
private lateinit var mockMvc: MockMvc
private val dietRawMaterial = DietRawMaterial(
dietMealId = 1,
rawMaterialId = 10,
name = "Tükörtojás",
kcalMin = 70,
kcalMax = 110,
proteinMin = 19,
proteinMax = 25,
fatMin = 12,
fatMax = 15,
chMin = 1,
chMax = 3,
sugar = 0,
)
private var authToken: String? = ""
@BeforeAll
fun initTest() {
authToken = Tokenizer.getToken()
}
@Test
fun `insert dietRawMaterial successfully`() {
mockMvc.perform(
MockMvcRequestBuilders.post("/api/diet_raw_material")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(toJson(dietRawMaterial))
)
.andExpect(status().isOk)
.andExpect(jsonPath("$.dietMealId").value(1))
.andExpect(jsonPath("$.rawMaterialId").value(10))
.andExpect(jsonPath("$.proteinMax").value(25))
// Act & Assert
mockMvc.perform(get("/api/diet_raw_material/{dietMealId}", 1)
.header("Authorization", "Bearer $authToken")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk)
.andExpect(jsonPath("$.[0].name").value("Tükörtojás"))
}
private fun toJson(obj: Any): String {
return Gson().toJson(obj)
}
}

View File

@ -0,0 +1,70 @@
package com.aitrainer.api.test.diet
import com.aitrainer.api.model.diet.DietSensitivity
import com.aitrainer.api.test.Tokenizer
import com.google.gson.Gson
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.MediaType
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.*
@SpringBootTest
@AutoConfigureMockMvc
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class DietSensitivityTest {
@Autowired
lateinit var mockMvc: MockMvc
private var authToken: String? = ""
@BeforeAll
fun initTest() {
authToken = Tokenizer.getToken()
}
private val dietSensitivity = DietSensitivity(1, name = "Nut Allergy")
private val dietSensitivity2 = DietSensitivity(2, name = "Penicillin sensitivity")
@Test
fun `insert diet sensitivity successfully`() {
val gson = Gson()
mockMvc.perform(
post("/api/diet_sensitivity")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(gson.toJson(dietSensitivity))
)
.andExpect(status().isOk)
.andExpect(jsonPath("$.name").value("Nut Allergy"))
mockMvc.perform(
post("/api/diet_sensitivity")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(gson.toJson(dietSensitivity2))
)
.andExpect(status().isOk)
}
@Test
fun `get all diet sensitivity successfully`() {
mockMvc.perform(get("/api/diet_sensitivity")
.header("Authorization", "Bearer $authToken")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk)
.andExpect(jsonPath("$.[0].name").value("Nut Allergy"))
.andExpect(jsonPath("$.[1].name").value("Penicillin sensitivity"))
}
}

View File

@ -0,0 +1,105 @@
package com.aitrainer.api.test.diet
import com.aitrainer.api.model.diet.Diet
import com.aitrainer.api.model.diet.DietMeal
import com.aitrainer.api.test.Tokenizer
import com.google.gson.Gson
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.MediaType
import org.springframework.test.context.junit.jupiter.SpringExtension
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.MvcResult
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.*
@ExtendWith(SpringExtension::class)
@SpringBootTest
@AutoConfigureMockMvc
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class DietTest {
@Autowired
private lateinit var mockMvc: MockMvc
private val diet = Diet(
dietUserId = 1,
dietText = "Test diet text",
)
private var authToken: String? = ""
@BeforeAll
fun initTest() {
authToken = Tokenizer.getToken()
}
@Test
fun `insert diet successfully`() {
val mvcResult: MvcResult = mockMvc.perform(
MockMvcRequestBuilders.post("/api/diet")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(toJson(diet))
)
.andExpect(status().isOk)
.andExpect(jsonPath("$.dietUserId").value(1))
.andReturn()
val gson= Gson()
val newDietJson = mvcResult.response.contentAsString
val newDiet = gson.fromJson(newDietJson, Diet::class.java)
mockMvc.perform(get("/api/diet/{dietUserId}", 1)
.header("Authorization", "Bearer $authToken")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk)
.andExpect(jsonPath("$.[0].dietText").value("Test diet text"))
val meal = DietMeal(
mealName = "monday|breakfast",
meal = "Főtt tojás"
)
val meal2 = DietMeal(
mealName = "monday|lunch",
meal = "Disznópörkölt"
)
val meal3 = DietMeal(
mealName = "monday|lunch",
meal = "Savanyúkáposzta"
)
newDiet.meals.add(meal)
newDiet.meals.add(meal2)
newDiet.meals.add(meal3)
//update
mockMvc.perform(
MockMvcRequestBuilders.post("/api/diet/${newDiet.dietId}")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(toJson(newDiet))
)
.andExpect(status().isOk)
.andExpect(jsonPath("$.dietUserId").value(1))
.andExpect(jsonPath("$.meals[0].meal").value("Főtt tojás"))
.andExpect(jsonPath("$.meals[1].mealName").value("monday|lunch"))
}
private fun toJson(obj: Any): String {
return Gson().toJson(obj)
}
}

View File

@ -0,0 +1,93 @@
package com.aitrainer.api.test.diet
import com.aitrainer.api.model.diet.DietUserPreference
import com.aitrainer.api.test.Tokenizer
import com.google.gson.Gson
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.MediaType
import org.springframework.test.context.junit.jupiter.SpringExtension
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.*
@ExtendWith(SpringExtension::class)
@SpringBootTest
@AutoConfigureMockMvc
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class DietUserPreferenceTest {
@Autowired
private lateinit var mockMvc: MockMvc
private val dietUserPreference = DietUserPreference(
id = 1,
rawMaterialId = 10,
dietUserId = 5,
temperature = -1
)
private val dietUserPreference2 = DietUserPreference(
id = 2,
rawMaterialId = 11,
dietUserId = 5,
temperature = 1
)
private var authToken: String = ""
@BeforeAll
fun initTest() {
authToken = Tokenizer.getToken()
}
@Test
fun `insert dietUserPreference successfully`() {
mockMvc.perform(
MockMvcRequestBuilders.post("/api/diet_user_preference")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(toJson(dietUserPreference))
)
.andExpect(status().isOk)
.andExpect(jsonPath("$.dietUserId").value(5))
.andExpect(jsonPath("$.rawMaterialId").value(10))
.andExpect(jsonPath("$.temperature").value(-1))
mockMvc.perform(
MockMvcRequestBuilders.post("/api/diet_user_preference")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(toJson(dietUserPreference2))
)
.andExpect(status().isOk)
}
@Test
fun `get dietUserPreference list by dietUserId id successfully`() {
// Act & Assert
mockMvc.perform(get("/api/diet_user_preference/{dietUserId}", 5)
.header("Authorization", "Bearer $authToken")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk)
.andExpect(jsonPath("$.[0].temperature").value(-1))
.andExpect(jsonPath("$.[0].rawMaterialId").value(10))
.andExpect(jsonPath("$.[1].temperature").value(1))
.andExpect(jsonPath("$.[1].rawMaterialId").value(11))
}
private fun toJson(obj: Any): String {
return Gson().toJson(obj)
}
}

View File

@ -0,0 +1,69 @@
package com.aitrainer.api.test.diet
import com.aitrainer.api.model.diet.DietUserSensitivity
import com.aitrainer.api.test.Tokenizer
import com.google.gson.Gson
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.MediaType
import org.springframework.test.context.junit.jupiter.SpringExtension
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.*
@ExtendWith(SpringExtension::class)
@SpringBootTest
@AutoConfigureMockMvc
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class DietUserSensitivityTest {
@Autowired
private lateinit var mockMvc: MockMvc
private val dietUserSensitivity = DietUserSensitivity(
sensitivityId = 1,
dietUserId = 5,
)
private var authToken: String = ""
@BeforeAll
fun initTest() {
authToken = Tokenizer.getToken()
}
@Test
fun `insert dietUserSensitivity successfully`() {
mockMvc.perform(
MockMvcRequestBuilders.post("/api/diet_user_sensitivity")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(toJson(dietUserSensitivity))
)
.andExpect(status().isOk)
.andExpect(jsonPath("$.dietUserId").value(5))
.andExpect(jsonPath("$.sensitivityId").value(1))
// Act & Assert
mockMvc.perform(get("/api/diet_user_sensitivity/{dietUserId}", 5)
.header("Authorization", "Bearer $authToken")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk)
.andExpect(jsonPath("$.[0].dietUserId").value(5))
.andExpect(jsonPath("$.[0].sensitivityId").value(1))
}
private fun toJson(obj: Any): String {
return Gson().toJson(obj)
}
}

View File

@ -0,0 +1,55 @@
package com.aitrainer.api.test.diet
import com.aitrainer.api.model.diet.DietUser
import com.aitrainer.api.test.Tokenizer
import com.google.gson.Gson
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.MediaType
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.*
@SpringBootTest
@AutoConfigureMockMvc
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class DietUserTest {
@Autowired
lateinit var mockMvc: MockMvc
private var authToken: String? = ""
@BeforeAll
fun initTest() {
authToken = Tokenizer.getToken()
}
@Test
fun `insert diet user successfully`() {
val dietUser = DietUser(1, customerId = 1)
val gson = Gson()
mockMvc.perform(
post("/api/diet_user")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(gson.toJson(dietUser))
)
.andExpect(status().isOk)
.andExpect(jsonPath("$.customerId").value(1))
mockMvc.perform(get("/api/diet_user/${dietUser.dietUserId}")
.header("Authorization", "Bearer $authToken")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk)
.andExpect(jsonPath("$.customerId").value(1))
}
}

View File

@ -0,0 +1,139 @@
package com.aitrainer.api.test.diet
import com.aitrainer.api.model.diet.RawMaterial
import com.aitrainer.api.test.Tokenizer
import com.google.gson.Gson
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.MediaType
import org.springframework.test.context.junit.jupiter.SpringExtension
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.*
@ExtendWith(SpringExtension::class)
@SpringBootTest
@AutoConfigureMockMvc
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class RawMaterialTest {
@Autowired
private lateinit var mockMvc: MockMvc
private val rawMaterial = RawMaterial(
name = "Tükörtojás",
kcalMin = 70,
kcalMax = 110,
proteinMin = 19,
proteinMax = 25,
fatMin = 12,
fatMax = 15,
chMin = 1,
chMax = 3,
sugar = 0,
storeId = 4,
)
private val rawMaterial2 = RawMaterial(
name = "Tigris buci",
kcalMin = 123,
kcalMax = 140,
proteinMin = 19,
proteinMax = 25,
fatMin = 30,
fatMax = 34,
chMin = 50,
chMax = 60,
sugar = 5,
storeId = 2,
)
private val rawMaterial3 = RawMaterial(
name = "Tükörtojás",
kcalMin = 75,
kcalMax = 112,
proteinMin = 12,
proteinMax = 20,
fatMin = 12,
fatMax = 15,
chMin = 1,
chMax = 3,
sugar = 0,
storeId = 2,
)
private var authToken: String? = ""
@BeforeAll
fun initTest() {
authToken = Tokenizer.getToken()
}
@Test
fun `insert rawMaterials successfully`() {
mockMvc.perform(
MockMvcRequestBuilders.post("/api/raw_material")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(toJson(rawMaterial))
)
.andExpect(status().isOk)
.andExpect(jsonPath("$.sugar").value(0))
.andExpect(jsonPath("$.storeId").value(4))
.andExpect(jsonPath("$.proteinMax").value(25))
val mvcResult = mockMvc.perform(
MockMvcRequestBuilders.post("/api/raw_material")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(toJson(rawMaterial2))
)
.andExpect(status().isOk)
.andReturn()
val gson= Gson()
val newRawMaterialJson = mvcResult.response.contentAsString
val newRawMaterial = gson.fromJson(newRawMaterialJson, RawMaterial::class.java)
mockMvc.perform(
MockMvcRequestBuilders.post("/api/raw_material")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(toJson(rawMaterial3))
)
.andExpect(status().isOk)
// Act & Assert
mockMvc.perform(get("/api/raw_material" )
.header("Authorization", "Bearer $authToken")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk)
.andExpect(jsonPath("$.[0].name").value("Tükörtojás"))
.andExpect(jsonPath("$.[1].name").value("Tigris buci"))
.andExpect(jsonPath("$.[2].storeId").value(2))
.andExpect(jsonPath("$.[2].name").value("Tükörtojás"))
// Act & Assert
mockMvc.perform(get("/api/raw_material/${newRawMaterial.id}")
.header("Authorization", "Bearer $authToken")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk)
.andExpect(jsonPath("$.name").value("Tigris buci"))
}
private fun toJson(obj: Any): String {
return Gson().toJson(obj)
}
}

View File

@ -0,0 +1,188 @@
package com.aitrainer.api.test.diet
import com.aitrainer.api.model.diet.Recipe
import com.aitrainer.api.model.diet.RecipeRawMaterial
import com.aitrainer.api.test.Tokenizer
import com.google.gson.Gson
import org.junit.jupiter.api.AfterAll
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.MediaType
import org.springframework.test.context.junit.jupiter.SpringExtension
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.MvcResult
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.*
@ExtendWith(SpringExtension::class)
@SpringBootTest
@AutoConfigureMockMvc
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class RecipeTest {
@Autowired
private lateinit var mockMvc: MockMvc
private val recipe1 = Recipe(
name = "Bableves",
description = "Hozzávalók: ---- Elkészítés: ---",
cal = 180,
protein = 19.0,
fat = 56.0,
ch = 23.0,
dietUserId = 4,
mealId = 0
)
private val recipe2 = Recipe(
name = "Mákos tészta",
description = "Hozzávalók: ---- Elkészítés: ---",
cal = 220,
protein = 19.0,
fat = 30.0,
ch = 78.0,
dietUserId = 4
)
private val recipe3 = Recipe(
name = "Borsóleves",
description = "Hozzávalók: ---- Elkészítés: ---",
cal = 160,
protein = 45.0,
fat = 30.0,
ch = 34.0,
dietUserId = 1,
mealId = 1
)
private var authToken: String? = ""
@BeforeAll
fun initTest() {
authToken = Tokenizer.getToken()
}
@AfterAll
fun tearDown() {
}
@Test
fun `insert recipes successfully`() {
val mvcResult: MvcResult = mockMvc.perform(
MockMvcRequestBuilders.post("/api/recipe")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(toJson(recipe1))
)
.andExpect(status().isOk)
.andExpect(jsonPath("$.name").value("Bableves"))
.andExpect(jsonPath("$.cal").value(180))
.andExpect(jsonPath("$.dietUserId").value(4))
.andReturn()
val gson= Gson()
val newRecipeJson = mvcResult.response.contentAsString
val newRecipe = gson.fromJson(newRecipeJson, Recipe::class.java)
mockMvc.perform(
MockMvcRequestBuilders.post("/api/recipe")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(toJson(recipe2))
)
.andExpect(status().isOk)
mockMvc.perform(
MockMvcRequestBuilders.post("/api/recipe")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(toJson(recipe3))
)
.andExpect(status().isOk)
val recipeRawMaterial1 = RecipeRawMaterial()
with(recipeRawMaterial1) {
quantity = 30
quantityUnit = "g"
rawMaterialId = 2
recipe = recipe1
}
newRecipe.rawMaterials.add(recipeRawMaterial1)
val recipeRawMaterial2 = RecipeRawMaterial()
with (recipeRawMaterial2) {
quantity = 50
quantityUnit = "g"
rawMaterialId = 3
recipe = recipe1
}
newRecipe.rawMaterials.add(recipeRawMaterial2)
mockMvc.perform(
MockMvcRequestBuilders.post("/api/recipe/"+newRecipe.recipeId)
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(toJson(newRecipe))
).andExpect(status().isOk)
.andExpect(jsonPath("$.cal").value(180))
.andExpect(jsonPath("$.rawMaterials.[0].quantity").value(30))
.andExpect(jsonPath("$.rawMaterials.[0].rawMaterialId").value(2))
.andExpect(jsonPath("$.rawMaterials.[1].quantity").value(50))
.andExpect(jsonPath("$.rawMaterials.[1].rawMaterialId").value(3))
// Act & Assert
mockMvc.perform(get("/api/recipe" )
.header("Authorization", "Bearer $authToken")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk)
.andExpect(jsonPath("$.[0].name").value("Bableves"))
.andExpect(jsonPath("$.[1].name").value("Mákos tészta"))
.andExpect(jsonPath("$.[2].dietUserId").value(1))
.andExpect(jsonPath("$.[2].name").value("Borsóleves"))
.andExpect(jsonPath("$.[0].rawMaterials.[0].quantity").value(30))
.andExpect(jsonPath("$.[0].rawMaterials.[1].quantity").value(50))
.andExpect(jsonPath("$.[0].rawMaterials.[1].rawMaterialId").value(3))
// Act & Assert
mockMvc.perform(get("/api/recipe/user/4")
.header("Authorization", "Bearer $authToken")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk)
.andExpect(jsonPath("$.[0].name").value("Bableves"))
.andExpect(jsonPath("$.[1].name").value("Mákos tészta"))
.andExpect(jsonPath("$.[0].rawMaterials.[1].rawMaterialId").value(3))
mockMvc.perform(get("/api/recipe/name/leves")
.header("Authorization", "Bearer $authToken")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk)
.andExpect(jsonPath("$.[0].name").value("Bableves"))
.andExpect(jsonPath("$.[1].name").value("Borsóleves"))
.andExpect(jsonPath("$.[0].rawMaterials.[1].rawMaterialId").value(3))
// GET by User ID
mockMvc.perform(get("/api/recipe/meal/1")
.header("Authorization", "Bearer $authToken")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk)
.andExpect(jsonPath("$.[0].name").value("Borsóleves"))
}
private fun toJson(obj: Any): String {
return Gson().toJson(obj)
}
}

View File

@ -0,0 +1,138 @@
package com.aitrainer.api.test.diet
import com.aitrainer.api.model.diet.Store
import com.aitrainer.api.test.Tokenizer
import com.google.gson.Gson
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.MediaType
import org.springframework.test.context.junit.jupiter.SpringExtension
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.*
@ExtendWith(SpringExtension::class)
@SpringBootTest
@AutoConfigureMockMvc
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class StoreTest {
@Autowired
private lateinit var mockMvc: MockMvc
private val store = Store(
storeId = 1,
storeName = "Tesco",
country = "HU"
)
private val store2 = Store(
storeId = 2,
storeName = "Auchan",
country = "HU"
)
private val store3 = Store(
storeId = 3,
storeName = "Aldi",
country = "HU"
)
private val store4 = Store(
storeId = 4,
storeName = "Aldi",
country = "DE"
)
private var authToken: String? = ""
@BeforeAll
fun initTest() {
authToken = Tokenizer.getToken()
}
@Test
fun `insert recipes successfully`() {
mockMvc.perform(
MockMvcRequestBuilders.post("/api/store")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(toJson(store))
)
.andExpect(status().isOk)
.andExpect(jsonPath("$.storeName").value("Tesco"))
.andExpect(jsonPath("$.country").value("HU"))
mockMvc.perform(
MockMvcRequestBuilders.post("/api/store")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(toJson(store2))
)
.andExpect(status().isOk)
mockMvc.perform(
MockMvcRequestBuilders.post("/api/store")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(toJson(store3))
)
.andExpect(status().isOk)
mockMvc.perform(
MockMvcRequestBuilders.post("/api/store")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(toJson(store4))
)
.andExpect(status().isOk)
}
@Test
fun `get all stores successfully`() {
// Act & Assert
mockMvc.perform(get("/api/store" )
.header("Authorization", "Bearer $authToken")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk)
.andExpect(jsonPath("$.[0].storeName").value("Tesco"))
.andExpect(jsonPath("$.[1].storeName").value("Auchan"))
.andExpect(jsonPath("$.[2].storeName").value("Aldi"))
.andExpect(jsonPath("$.[3].storeName").value("Aldi"))
.andExpect(jsonPath("$.[3].country").value("DE"))
}
@Test
fun `get store by name successfully`() {
// Act & Assert
mockMvc.perform(get("/api/store/Aldi/HU")
.header("Authorization", "Bearer $authToken")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk)
.andExpect(jsonPath("$.storeName").value("Aldi"))
.andExpect(jsonPath("$.country").value("HU"))
}
@Test
fun `get recipe by name unsuccessfully`() {
// Act & Assert
mockMvc.perform(get("/api/store/Aldi/AT")
.header("Authorization", "Bearer $authToken")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isNotFound)
}
private fun toJson(obj: Any): String {
return Gson().toJson(obj)
}
}

View File

@ -0,0 +1,84 @@
package com.aitrainer.api.test.openai
import com.aitrainer.api.model.OpenAI
import com.aitrainer.api.test.Tokenizer
import com.google.gson.Gson
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.MediaType
import org.springframework.test.context.junit.jupiter.SpringExtension
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.result.MockMvcResultMatchers
@ExtendWith(SpringExtension::class)
@SpringBootTest
@AutoConfigureMockMvc
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class OpenAITest {
@Autowired
private lateinit var mockMvc: MockMvc
private var authToken: String? = ""
@BeforeAll
fun initTest() {
authToken = Tokenizer.getToken()
}
@Test
fun `get a question successfully`() {
val question = "Who the f. is Alice?"
mockMvc.perform(
MockMvcRequestBuilders.get("/api/openai/completion")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(question)
)
.andExpect(MockMvcResultMatchers.status().isOk)
//.andExpect(MockMvcResultMatchers.content().string("Sorry I dont know"))
}
@Test
fun `get a question successfully with model name`() {
val question = "Who the f. is Alice? Who sing that song?"
val openai = OpenAI(
question = question,
modelName = "text-ada-001",
temperature = 0.5
)
mockMvc.perform(
MockMvcRequestBuilders.post("/api/openai/completion_with_model")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
.content(toJson(openai))
)
.andExpect(MockMvcResultMatchers.status().isOk)
//.andExpect(MockMvcResultMatchers.content().string("Sorry I dont know"))
}
@Test
fun `get models successfully`() {
mockMvc.perform(
MockMvcRequestBuilders.get("/api/openai/list_models")
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", "Bearer $authToken")
)
.andExpect(MockMvcResultMatchers.status().isOk)
}
private fun toJson(obj: Any): String {
return Gson().toJson(obj)
}
}