diff --git a/data/db/diet4you.sql b/data/db/diet4you.sql new file mode 100644 index 0000000..8c5785d --- /dev/null +++ b/data/db/diet4you.sql @@ -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) */; diff --git a/data/db/update_1_2_0.sql b/data/db/update_1_2_0.sql index 35e9262..e016437 100644 --- a/data/db/update_1_2_0.sql +++ b/data/db/update_1_2_0.sql @@ -12,7 +12,6 @@ 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', @@ -21,9 +20,33 @@ CREATE TABLE `diet_user` ( 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_id` INT(11) NOT NULL DEFAULT '0', + `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', @@ -125,9 +148,11 @@ CREATE TABLE `recipe` ( `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 diff --git a/readme.MD b/readme.MD index 19156aa..ae5b955 100644 --- a/readme.MD +++ b/readme.MD @@ -30,5 +30,6 @@ Workout Test Club * exercise_type_device * deactivate customer * diet tables +* openAI with automatic database update diff --git a/src/main/kotlin/com/aitrainer/api/ApiApplication.kt b/src/main/kotlin/com/aitrainer/api/ApiApplication.kt index cf16629..8ade98e 100644 --- a/src/main/kotlin/com/aitrainer/api/ApiApplication.kt +++ b/src/main/kotlin/com/aitrainer/api/ApiApplication.kt @@ -9,6 +9,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.builder.SpringApplicationBuilder import org.springframework.context.annotation.Bean + @SpringBootApplication class ApiApplication { @Bean(name = ["jasyptStringEncryptor"]) @@ -43,3 +44,5 @@ class ApiApplication { + + diff --git a/src/main/kotlin/com/aitrainer/api/controller/CustomerController.kt b/src/main/kotlin/com/aitrainer/api/controller/CustomerController.kt index 2f6063b..dda552b 100644 --- a/src/main/kotlin/com/aitrainer/api/controller/CustomerController.kt +++ b/src/main/kotlin/com/aitrainer/api/controller/CustomerController.kt @@ -8,6 +8,7 @@ import com.aitrainer.api.service.EmailTemplateService import com.aitrainer.api.service.Firebase import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired +import org.springframework.beans.factory.annotation.Value import org.springframework.http.HttpHeaders import org.springframework.http.ResponseEntity import org.springframework.security.access.annotation.Secured @@ -153,7 +154,7 @@ class CustomerController ( private val customerRepository: CustomerRepository) { } @PostMapping("/club_registration") - fun clubRegistration(@Valid @RequestBody json: String): ResponseEntity<*> { + fun clubRegistration(@Valid @RequestBody json: String, @Value("\${firebase.key}") apiKey: String): ResponseEntity<*> { val newUser: ClubUser = ClubUser().fromJson(json) @@ -173,7 +174,7 @@ class CustomerController ( private val customerRepository: CustomerRepository) { val stringCharacters = ('0'..'z').toList().toTypedArray() val genPassword = (1..10).map { stringCharacters.random() }.joinToString("") - val firebase = Firebase() + val firebase = Firebase(apiKey) val signupResponse = firebase.signUp(newUser.email, genPassword) ?: return ResponseEntity.badRequest().body("Firebase exception ${firebase.error}") diff --git a/src/main/kotlin/com/aitrainer/api/controller/CustomerPackageController.kt b/src/main/kotlin/com/aitrainer/api/controller/CustomerPackageController.kt index 3b879c3..1a8da2e 100644 --- a/src/main/kotlin/com/aitrainer/api/controller/CustomerPackageController.kt +++ b/src/main/kotlin/com/aitrainer/api/controller/CustomerPackageController.kt @@ -28,7 +28,8 @@ class CustomerPackageController( private val customerRepository: CustomerReposit private val dietUserConsumptionRepository: DietUserConsumptionRepository, private val dietUserRepository: DietUserRepository, private val dietUserPreferenceRepository: DietUserPreferenceRepository, - private val dietUserSensitivityRepository: DietUserSensitivityRepository + private val dietUserSensitivityRepository: DietUserSensitivityRepository, + private val customerConversationRepository: CustomerConversationRepository ) { @@ -53,16 +54,10 @@ class CustomerPackageController( private val customerRepository: CustomerReposit val customerJson: String = gson.toJson(customer) val dietUserJson: String = gson.toJson(dietUser) - val listCustomerProperty = customerPropertyRepository.findLastPropertiesByCustomerId(customerId) - val listCustomerPropertyJson = gson.toJson(listCustomerProperty) - - val listMembership = customerMembership.findAllByCustomer(customer) - val listMembershipJson = gson.toJson(listMembership) - val listDiet = dietRepository.findByDietUserId(dietUserId) val listDietJson = gson.toJson(listDiet) - val listDietRawMaterial = dietRawMaterialRepository.findByDietId(dietUserId) + val listDietRawMaterial = dietRawMaterialRepository.findByDietMealId(dietUserId) val listDietRawMaterialJson = gson.toJson(listDietRawMaterial) val listDietUserConsumption = dietUserConsumptionRepository.findByDietUserId(dietUserId) @@ -74,17 +69,18 @@ class CustomerPackageController( private val customerRepository: CustomerReposit val listDietUserSensitivity = dietUserSensitivityRepository.findByDietUserId(dietUserId) val listDietUserSensitivityJson = gson.toJson(listDietUserSensitivity) - val packageJson: String = - getClassRecord(Customer::class.simpleName, customerJson) + - "|||" + getClassRecord(DietUser::class.simpleName, dietUserJson) - "|||" + getClassRecord(CustomerProperty::class.simpleName, listCustomerPropertyJson) - "|||" + getClassRecord(CustomerMembership::class.simpleName, listMembershipJson) - "|||" + 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) + 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) diff --git a/src/main/kotlin/com/aitrainer/api/controller/OpenAIController.kt b/src/main/kotlin/com/aitrainer/api/controller/OpenAIController.kt index 39a747c..f4a0bb5 100644 --- a/src/main/kotlin/com/aitrainer/api/controller/OpenAIController.kt +++ b/src/main/kotlin/com/aitrainer/api/controller/OpenAIController.kt @@ -1,11 +1,10 @@ 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.GetMapping -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RestController +import org.springframework.web.bind.annotation.* @RestController @RequestMapping("/api") @@ -13,10 +12,10 @@ class OpenAIController() { private val logger = LoggerFactory.getLogger(javaClass) @OptIn(DelicateCoroutinesApi::class) - @GetMapping("/openai/completion") - fun getOpenAIResponse(question: String) : String { + @PostMapping("/openai/completion") + fun getOpenAIResponse(@RequestBody question: String) : String { var result = "" - val openAIService = OpenAIService() + val openAIService = OpenAIService(null, null) val deferred = GlobalScope.async { openAIService.completion(question) } @@ -26,5 +25,35 @@ class OpenAIController() { } 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 { + var result = mutableListOf() + val openAIService = OpenAIService(null, null) + val deferred = GlobalScope.async { + openAIService.getModels() + } + runBlocking { + result = deferred.await() + //println("Result: $result" ) + } + return result + } } diff --git a/src/main/kotlin/com/aitrainer/api/controller/diet/DietController.kt b/src/main/kotlin/com/aitrainer/api/controller/diet/DietController.kt index 6c68a84..05d0a65 100644 --- a/src/main/kotlin/com/aitrainer/api/controller/diet/DietController.kt +++ b/src/main/kotlin/com/aitrainer/api/controller/diet/DietController.kt @@ -15,6 +15,23 @@ class DietController(private val dietRepository: DietRepository) { return ResponseEntity.ok().body(dietRepository.save(diet)) } + @PostMapping("/diet/{id}") + fun update(@PathVariable(value = "id") id: Long, @RequestBody diet: Diet): ResponseEntity { + 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> { val list = dietRepository.findByDietUserId(dietUserId) diff --git a/src/main/kotlin/com/aitrainer/api/controller/diet/DietCustomerController.kt b/src/main/kotlin/com/aitrainer/api/controller/diet/DietCustomerController.kt index 54fd3ff..4104394 100644 --- a/src/main/kotlin/com/aitrainer/api/controller/diet/DietCustomerController.kt +++ b/src/main/kotlin/com/aitrainer/api/controller/diet/DietCustomerController.kt @@ -7,11 +7,10 @@ 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.Email -import com.aitrainer.api.service.EmailTemplateService 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 @@ -25,11 +24,8 @@ class DietCustomerController(private val dietUserRepository: DietUserRepository, @Autowired var serviceBeans: ServiceBeans? = null - @Autowired - private var emailTemplateService: EmailTemplateService? = null - @PostMapping("/diet_registration") - fun insert(@RequestBody dietCustomerJson: String): ResponseEntity<*> { + fun insert(@RequestBody dietCustomerJson: String, @Value("\${firebase.key}") apiKey: String): ResponseEntity<*> { val newDietCustomer: DietCustomer = DietCustomer().fromJson(dietCustomerJson) if ( newDietCustomer.email.isEmpty()) { @@ -48,7 +44,7 @@ class DietCustomerController(private val dietUserRepository: DietUserRepository, var existingCustomer: Customer? = customerRepository.findByEmailAndActive(newDietCustomer.email, "Y") if (existingCustomer == null ) { - val firebase = Firebase() + val firebase = Firebase(apiKey) val signupResponse = firebase.signUp(newDietCustomer.email, genPassword) ?: return ResponseEntity.badRequest().body("Firebase exception ${firebase.error}") idToken = signupResponse.idToken @@ -125,7 +121,7 @@ class DietCustomerController(private val dietUserRepository: DietUserRepository, } // create email link - val activationLink = "https://diet4you.andio.hu/welcome/id=$idToken" + /*val activationLink = "https://diet4you.andio.hu/welcome/id=$idToken" if ( emailTemplateService == null ) { emailTemplateService = EmailTemplateService() } @@ -134,7 +130,7 @@ class DietCustomerController(private val dietUserRepository: DietUserRepository, // send email val email = Email() - email.send(newDietCustomer.email, html, subject) + email.send(newDietCustomer.email, html, subject)*/ return ResponseEntity.ok().body(existingCustomer) } diff --git a/src/main/kotlin/com/aitrainer/api/controller/diet/DietRawMaterialController.kt b/src/main/kotlin/com/aitrainer/api/controller/diet/DietRawMaterialController.kt index c07e77b..2dbefd1 100644 --- a/src/main/kotlin/com/aitrainer/api/controller/diet/DietRawMaterialController.kt +++ b/src/main/kotlin/com/aitrainer/api/controller/diet/DietRawMaterialController.kt @@ -15,9 +15,9 @@ class DietRawMaterialController(private val dietRawMaterialRepository: DietRawMa return ResponseEntity.ok().body(dietRawMaterialRepository.save(dietRawMaterial)) } - @GetMapping("/diet_raw_material/{dietId}") - fun getByDietUserId(@PathVariable dietId: Long): ResponseEntity> { - val list = dietRawMaterialRepository.findByDietId(dietId) + @GetMapping("/diet_raw_material/{dietMealId}") + fun getByDietUserId(@PathVariable dietMealId: Long): ResponseEntity> { + val list = dietRawMaterialRepository.findByDietMealId(dietMealId) return if (list.isEmpty()) ResponseEntity.notFound().build() else ResponseEntity.ok().body(list) } diff --git a/src/main/kotlin/com/aitrainer/api/controller/diet/RecipeController.kt b/src/main/kotlin/com/aitrainer/api/controller/diet/RecipeController.kt index 4a5f4c5..7274179 100644 --- a/src/main/kotlin/com/aitrainer/api/controller/diet/RecipeController.kt +++ b/src/main/kotlin/com/aitrainer/api/controller/diet/RecipeController.kt @@ -26,7 +26,8 @@ class RecipeController(private val recipeRepository: RecipeRepository) { ch = recipe.ch, fat = recipe.fat, protein = recipe.protein, - dietUserId = recipe.dietUserId + dietUserId = recipe.dietUserId, + mealId = recipe.mealId ) recipe.rawMaterials.forEach { it.recipe = recipe @@ -42,13 +43,20 @@ class RecipeController(private val recipeRepository: RecipeRepository) { ResponseEntity.ok().body(list) } - @GetMapping("/recipe/{dietUserId}") + @GetMapping("/recipe/user/{dietUserId}") fun getByDietUserId(@PathVariable dietUserId: Long): ResponseEntity> { 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> { + 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> { val list = recipeRepository.findByName(name) diff --git a/src/main/kotlin/com/aitrainer/api/model/OpenAI.kt b/src/main/kotlin/com/aitrainer/api/model/OpenAI.kt new file mode 100644 index 0000000..56ba465 --- /dev/null +++ b/src/main/kotlin/com/aitrainer/api/model/OpenAI.kt @@ -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, +) \ No newline at end of file diff --git a/src/main/kotlin/com/aitrainer/api/model/diet/Diet.kt b/src/main/kotlin/com/aitrainer/api/model/diet/Diet.kt index 20de8af..69fcc47 100644 --- a/src/main/kotlin/com/aitrainer/api/model/diet/Diet.kt +++ b/src/main/kotlin/com/aitrainer/api/model/diet/Diet.kt @@ -1,27 +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 monday: String = "", - - @Expose @get: NotNull val tuesday: String = "", - - @Expose @get: NotNull val wednesday: String = "", - - @Expose @get: NotNull val thursday: String = "", - - @Expose @get: NotNull val friday: String = "", - - @Expose @get: NotNull val saturday: String = "", - - @Expose @get: NotNull val sunday: String = "" -) \ No newline at end of file + @Expose @get: NotNull val startDate: String = "", +) { + @OneToMany(cascade = [(CascadeType.ALL)], fetch = FetchType.EAGER, mappedBy = "diet") + @Fetch(value = FetchMode.SUBSELECT) + @Expose val meals: MutableList = mutableListOf() +} \ No newline at end of file diff --git a/src/main/kotlin/com/aitrainer/api/model/diet/DietMeal.kt b/src/main/kotlin/com/aitrainer/api/model/diet/DietMeal.kt new file mode 100644 index 0000000..b928850 --- /dev/null +++ b/src/main/kotlin/com/aitrainer/api/model/diet/DietMeal.kt @@ -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 +} \ No newline at end of file diff --git a/src/main/kotlin/com/aitrainer/api/model/diet/DietRawMaterial.kt b/src/main/kotlin/com/aitrainer/api/model/diet/DietRawMaterial.kt index 0db7d9c..175e581 100644 --- a/src/main/kotlin/com/aitrainer/api/model/diet/DietRawMaterial.kt +++ b/src/main/kotlin/com/aitrainer/api/model/diet/DietRawMaterial.kt @@ -7,7 +7,7 @@ import org.jetbrains.annotations.NotNull data class DietRawMaterial ( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Expose val id: Long = 0, - @Expose @get: NotNull val dietId: 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, diff --git a/src/main/kotlin/com/aitrainer/api/model/diet/Recipe.kt b/src/main/kotlin/com/aitrainer/api/model/diet/Recipe.kt index 87d68c6..667acb3 100644 --- a/src/main/kotlin/com/aitrainer/api/model/diet/Recipe.kt +++ b/src/main/kotlin/com/aitrainer/api/model/diet/Recipe.kt @@ -19,6 +19,7 @@ data class Recipe ( @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) diff --git a/src/main/kotlin/com/aitrainer/api/openai/OpenAIService.kt b/src/main/kotlin/com/aitrainer/api/openai/OpenAIService.kt index 0bc6d4e..1ce5f0c 100644 --- a/src/main/kotlin/com/aitrainer/api/openai/OpenAIService.kt +++ b/src/main/kotlin/com/aitrainer/api/openai/OpenAIService.kt @@ -3,13 +3,15 @@ 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 { +class OpenAIService(private val modelName: String?, private val temperature: Double?) { private var openAI: OpenAI? = null @@ -24,7 +26,11 @@ class OpenAIService { private var modelId: ModelId? = null private suspend fun connect(modelName: String) { - openAI = OpenAI(properties.getProperty("openai.key")) + val config = OpenAIConfig( + token = properties.getProperty("openai.key"), + logLevel = LogLevel.All + ) + openAI = OpenAI(config) modelId = ModelId(modelName) model = openAI!!.model(modelId!!) @@ -32,22 +38,46 @@ class OpenAIService { suspend fun completion(question: String): String { return withContext(Dispatchers.IO) { - if (openAI == null) { - connect("text-davinci-003") + 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 = 128, - temperature=0.1, + maxTokens = 2048 - question.length, + temperature=realTemperature, ) val completion: TextCompletion = openAI!!.completion(completionRequest) - val result = completion.choices[0].text - //println("Completion: $result") + val result = completion.choices[0].text result } } + + suspend fun getModels(): MutableList { + return withContext(Dispatchers.IO) { + if (openAI == null) { + openAI = OpenAI(token = properties.getProperty("openai.key")) + } + + val list: MutableList = mutableListOf() + openAI!!.models().forEach { + println(it) + list.add(it.id.id) + } + + return@withContext list + } + } } diff --git a/src/main/kotlin/com/aitrainer/api/repository/diet/DietRawMaterialRepository.kt b/src/main/kotlin/com/aitrainer/api/repository/diet/DietRawMaterialRepository.kt index ca35269..71cab66 100644 --- a/src/main/kotlin/com/aitrainer/api/repository/diet/DietRawMaterialRepository.kt +++ b/src/main/kotlin/com/aitrainer/api/repository/diet/DietRawMaterialRepository.kt @@ -6,5 +6,5 @@ import org.springframework.stereotype.Repository @Repository interface DietRawMaterialRepository : JpaRepository { - fun findByDietId(dietId: Long): List + fun findByDietMealId(dietMealId: Long): List } \ No newline at end of file diff --git a/src/main/kotlin/com/aitrainer/api/repository/diet/DietRepository.kt b/src/main/kotlin/com/aitrainer/api/repository/diet/DietRepository.kt index 3678596..abbf4f5 100644 --- a/src/main/kotlin/com/aitrainer/api/repository/diet/DietRepository.kt +++ b/src/main/kotlin/com/aitrainer/api/repository/diet/DietRepository.kt @@ -2,9 +2,13 @@ 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 { fun findByDietUserId(dietUserId: Long): List + + @Query(" FROM Diet WHERE dietId = :dietId") + fun findByDietId(dietId: Long): Diet? } \ No newline at end of file diff --git a/src/main/kotlin/com/aitrainer/api/repository/diet/RecipeRepository.kt b/src/main/kotlin/com/aitrainer/api/repository/diet/RecipeRepository.kt index 5383261..47680f9 100644 --- a/src/main/kotlin/com/aitrainer/api/repository/diet/RecipeRepository.kt +++ b/src/main/kotlin/com/aitrainer/api/repository/diet/RecipeRepository.kt @@ -9,6 +9,10 @@ interface RecipeRepository : JpaRepository { fun findByName(name: String): List? fun findByDietUserId(dietUserId: Long): List? + @Query(" FROM Recipe WHERE recipeId = :recipeId") fun findByRecipeId(recipeId: Long): Recipe? + + @Query(" FROM Recipe WHERE mealId = :mealId") + fun findByMealId(mealId: Long): List? } diff --git a/src/main/kotlin/com/aitrainer/api/service/Firebase.kt b/src/main/kotlin/com/aitrainer/api/service/Firebase.kt index b8eaa6c..995e908 100644 --- a/src/main/kotlin/com/aitrainer/api/service/Firebase.kt +++ b/src/main/kotlin/com/aitrainer/api/service/Firebase.kt @@ -2,18 +2,22 @@ package com.aitrainer.api.service import com.aitrainer.api.model.firebase_response.SignupResponse 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.http.HttpClient import java.net.http.HttpRequest import java.net.http.HttpResponse import java.nio.charset.StandardCharsets -import org.json.JSONObject +import java.util.* -class Firebase { - private val apiKey: String = "AIzaSyCUXBWV3_qzvV__ZWZA1siHftrrJpjDKh4" +@Service +class Firebase(@Value("\${firebase.key}") private val apiKey: String) { private val firebaseBaseUrl: String = "https://identitytoolkit.googleapis.com/v1/accounts" var statusCode: Int = 0 var error: String = "" + fun signUp(email: String, password: String): SignupResponse? { val json = JSONObject() @@ -42,6 +46,7 @@ class Firebase { } private fun call(command: String, postData: String): String { + val apiKey = this.apiKey val url = URI.create("$firebaseBaseUrl:$command?key=$apiKey") // Create the HTTP request object diff --git a/src/main/resources/application-diet.properties b/src/main/resources/application-diet.properties new file mode 100644 index 0000000..e305476 --- /dev/null +++ b/src/main/resources/application-diet.properties @@ -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 diff --git a/src/main/resources/application-dietprod.properties b/src/main/resources/application-dietprod.properties new file mode 100644 index 0000000..b1168ed --- /dev/null +++ b/src/main/resources/application-dietprod.properties @@ -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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 \ No newline at end of file diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties index 3fffd5b..136f313 100644 --- a/src/main/resources/application-prod.properties +++ b/src/main/resources/application-prod.properties @@ -16,4 +16,7 @@ logging.file=logs # if the database structue has been changed, increment this version number application.version=1.2.0 -jwt.secret=aitrainer \ No newline at end of file +jwt.secret=aitrainer + +firebase.key=AIzaSyCUXBWV3_qzvV__ZWZA1siHftrrJpjDKh4 +openai.key=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 \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 0c644cf..8dcd6d6 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -23,3 +23,4 @@ jwt.secret=aitrainer openai.key=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 spring.mail.properties.mail.mime.charset=UTF-8 +firebase.key=AIzaSyCUXBWV3_qzvV__ZWZA1siHftrrJpjDKh4 \ No newline at end of file diff --git a/src/test/kotlin/com/aitrainer/api/test/AppCustomerPackageTest.kt b/src/test/kotlin/com/aitrainer/api/test/AppCustomerPackageTest.kt index 5fa4aea..b7a5789 100644 --- a/src/test/kotlin/com/aitrainer/api/test/AppCustomerPackageTest.kt +++ b/src/test/kotlin/com/aitrainer/api/test/AppCustomerPackageTest.kt @@ -65,6 +65,9 @@ class AppCustomerPackageTest { @Autowired private lateinit var dietUserSensitivityRepository: DietUserSensitivityRepository + @Autowired + private lateinit var customerConversationRepository: CustomerConversationRepository + @Test fun dietCustomerPackageTest() { val gson = Gson() @@ -84,7 +87,8 @@ class AppCustomerPackageTest { dietUserConsumptionRepository, dietUserRepository, dietUserPreferenceRepository, - dietUserSensitivityRepository + dietUserSensitivityRepository, + customerConversationRepository ) val response = controller.getDietCustomerPackageData(2) @@ -103,8 +107,8 @@ class AppCustomerPackageTest { val dietJson: String = record[1] val type = object : TypeToken?>() {}.type val list: List = gson.fromJson(dietJson, type) - assertEquals(list[0].monday, "Monday meal") assertEquals(list[0].dietText, "Test diet text") + assertEquals(list[0].meals[0].mealName, "monday|breakfast") } record[0] == DietRawMaterial::class.simpleName -> { @@ -169,7 +173,8 @@ class AppCustomerPackageTest { dietUserConsumptionRepository, dietUserRepository, dietUserPreferenceRepository, - dietUserSensitivityRepository + dietUserSensitivityRepository, + customerConversationRepository ) val response = controller.getCustomerClubPackageData(90) @@ -224,7 +229,8 @@ class AppCustomerPackageTest { dietUserConsumptionRepository, dietUserRepository, dietUserPreferenceRepository, - dietUserSensitivityRepository ) + dietUserSensitivityRepository, + customerConversationRepository) var response: ResponseEntity<*> = controller.getCustomerPackageData(91) assertEquals(response.statusCode, HttpStatus.NOT_FOUND) diff --git a/src/test/kotlin/com/aitrainer/api/test/CustomerConversationTest.kt b/src/test/kotlin/com/aitrainer/api/test/CustomerConversationTest.kt index b724341..2836780 100644 --- a/src/test/kotlin/com/aitrainer/api/test/CustomerConversationTest.kt +++ b/src/test/kotlin/com/aitrainer/api/test/CustomerConversationTest.kt @@ -14,6 +14,7 @@ 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 @@ -61,16 +62,7 @@ class CustomerConversationTest { mockMvc.perform(get("/api/customer_conversation/123") .header("Authorization", "Bearer $authToken")) .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())) + .andExpect(MockMvcResultMatchers.jsonPath("$.[0].customerId").value(123)) + .andExpect(MockMvcResultMatchers.jsonPath("$.[0].answer").value("Not much.")) } } diff --git a/src/test/kotlin/com/aitrainer/api/test/CustomerTests.kt b/src/test/kotlin/com/aitrainer/api/test/CustomerTests.kt index 2efb301..8dd423b 100644 --- a/src/test/kotlin/com/aitrainer/api/test/CustomerTests.kt +++ b/src/test/kotlin/com/aitrainer/api/test/CustomerTests.kt @@ -11,6 +11,7 @@ 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.beans.factory.annotation.Value import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc import org.springframework.boot.test.context.SpringBootTest import org.springframework.http.HttpHeaders @@ -245,10 +246,10 @@ class CustomerTests { } @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 controller = CustomerController(customerRepository) - val response: ResponseEntity<*> = controller.clubRegistration(json) + val response: ResponseEntity<*> = controller.clubRegistration(json, apiKey) assertEquals(response.statusCode, HttpStatus.BAD_REQUEST) } diff --git a/src/test/kotlin/com/aitrainer/api/test/FirebaseTest.kt b/src/test/kotlin/com/aitrainer/api/test/FirebaseTest.kt index 3be3b23..e6bc1c1 100644 --- a/src/test/kotlin/com/aitrainer/api/test/FirebaseTest.kt +++ b/src/test/kotlin/com/aitrainer/api/test/FirebaseTest.kt @@ -4,6 +4,7 @@ import com.aitrainer.api.service.Firebase import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance +import org.springframework.beans.factory.annotation.Value import org.springframework.boot.test.context.SpringBootTest import kotlin.test.assertEquals import kotlin.test.assertTrue @@ -16,11 +17,12 @@ class FirebaseTest { @BeforeAll fun tearUp() { - this.firebase = Firebase() + } @Test - fun testAuth() { + fun testAuth(@Value("\${firebase.key}") apiKey: String) { + this.firebase = Firebase(apiKey) val email = "user@exemple.com" val password = "verystrictpassword1" val signupResponse = firebase.signUp(email, password) diff --git a/src/test/kotlin/com/aitrainer/api/test/diet/DietRawMaterialTest.kt b/src/test/kotlin/com/aitrainer/api/test/diet/DietRawMaterialTest.kt index fc20275..a6c5967 100644 --- a/src/test/kotlin/com/aitrainer/api/test/diet/DietRawMaterialTest.kt +++ b/src/test/kotlin/com/aitrainer/api/test/diet/DietRawMaterialTest.kt @@ -28,7 +28,7 @@ class DietRawMaterialTest { private lateinit var mockMvc: MockMvc private val dietRawMaterial = DietRawMaterial( - dietId = 1, + dietMealId = 1, rawMaterialId = 10, name = "Tükörtojás", kcalMin = 70, @@ -60,17 +60,13 @@ class DietRawMaterialTest { .content(toJson(dietRawMaterial)) ) .andExpect(status().isOk) - .andExpect(jsonPath("$.dietId").value(1)) + .andExpect(jsonPath("$.dietMealId").value(1)) .andExpect(jsonPath("$.rawMaterialId").value(10)) .andExpect(jsonPath("$.proteinMax").value(25)) - } - - @Test - fun `get dietRawMaterial list by dietId id successfully`() { // Act & Assert - mockMvc.perform(get("/api/diet_raw_material/{dietId}", 1) + mockMvc.perform(get("/api/diet_raw_material/{dietMealId}", 1) .header("Authorization", "Bearer $authToken") .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk) diff --git a/src/test/kotlin/com/aitrainer/api/test/diet/DietTest.kt b/src/test/kotlin/com/aitrainer/api/test/diet/DietTest.kt index a980b22..09ae9d4 100644 --- a/src/test/kotlin/com/aitrainer/api/test/diet/DietTest.kt +++ b/src/test/kotlin/com/aitrainer/api/test/diet/DietTest.kt @@ -1,6 +1,7 @@ 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 @@ -13,6 +14,7 @@ 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.* @@ -31,13 +33,6 @@ class DietTest { private val diet = Diet( dietUserId = 1, dietText = "Test diet text", - monday = "Monday meal", - tuesday = "Tuesday meal", - wednesday = "Wednesday meal", - thursday = "Thursday meal", - friday = "Friday meal", - saturday = "Saturday meal", - sunday = "Sunday meal" ) private var authToken: String? = "" @@ -50,10 +45,8 @@ class DietTest { @Test fun `insert diet successfully`() { - // Arrange - //given(dietRepository.save(diet)).willReturn(diet) - mockMvc.perform( + val mvcResult: MvcResult = mockMvc.perform( MockMvcRequestBuilders.post("/api/diet") .contentType(MediaType.APPLICATION_JSON) .header("Authorization", "Bearer $authToken") @@ -61,16 +54,49 @@ class DietTest { ) .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) - @Test - fun `get diet list by dietUserId id successfully`() { mockMvc.perform(get("/api/diet/{dietUserId}", 1) .header("Authorization", "Bearer $authToken") .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk) - .andExpect(jsonPath("$.[0].monday").value("Monday meal")) + .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 { diff --git a/src/test/kotlin/com/aitrainer/api/test/diet/RecipeTest.kt b/src/test/kotlin/com/aitrainer/api/test/diet/RecipeTest.kt index fe71c21..dc54ebe 100644 --- a/src/test/kotlin/com/aitrainer/api/test/diet/RecipeTest.kt +++ b/src/test/kotlin/com/aitrainer/api/test/diet/RecipeTest.kt @@ -38,6 +38,7 @@ class RecipeTest { fat = 56.0, ch = 23.0, dietUserId = 4, + mealId = 0 ) private val recipe2 = Recipe( name = "Mákos tészta", @@ -46,7 +47,7 @@ class RecipeTest { protein = 19.0, fat = 30.0, ch = 78.0, - dietUserId = 4, + dietUserId = 4 ) private val recipe3 = Recipe( @@ -57,6 +58,7 @@ class RecipeTest { fat = 30.0, ch = 34.0, dietUserId = 1, + mealId = 1 ) private var authToken: String? = "" @@ -154,7 +156,7 @@ class RecipeTest { // Act & Assert - mockMvc.perform(get("/api/recipe/4") + mockMvc.perform(get("/api/recipe/user/4") .header("Authorization", "Bearer $authToken") .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk) @@ -163,7 +165,6 @@ class RecipeTest { .andExpect(jsonPath("$.[0].rawMaterials.[1].rawMaterialId").value(3)) - // Act & Assert mockMvc.perform(get("/api/recipe/name/leves") .header("Authorization", "Bearer $authToken") .contentType(MediaType.APPLICATION_JSON)) @@ -172,6 +173,13 @@ class RecipeTest { .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 { diff --git a/src/test/kotlin/com/aitrainer/api/test/openai/OpenAITest.kt b/src/test/kotlin/com/aitrainer/api/test/openai/OpenAITest.kt new file mode 100644 index 0000000..ee30414 --- /dev/null +++ b/src/test/kotlin/com/aitrainer/api/test/openai/OpenAITest.kt @@ -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) + } +} \ No newline at end of file