From a38c244d79fda160125873907ce5b8c849a1a9cf Mon Sep 17 00:00:00 2001 From: Bossanyi Tibor Date: Mon, 10 May 2021 16:54:20 +0200 Subject: [PATCH] API 1.0.37 faq, training plans --- build.gradle.kts | 2 +- data/db/update_1_0_37.sql | 68 +++++++++++++++++++ .../api/controller/PackageController.kt | 14 +++- .../kotlin/com/aitrainer/api/model/Faq.kt | 20 ++++++ .../com/aitrainer/api/model/FaqTranslation.kt | 19 ++++++ .../com/aitrainer/api/model/TrainingPlan.kt | 20 ++++++ .../aitrainer/api/model/TrainingPlanDetail.kt | 30 ++++++++ .../aitrainer/api/repository/FaqRepository.kt | 9 +++ .../api/repository/TrainingPlanRepository.kt | 9 +++ .../resources/application-prod.properties | 2 +- src/main/resources/application.properties | 2 +- .../com/aitrainer/api/test/AppPackageTest.kt | 23 ++++++- 12 files changed, 212 insertions(+), 6 deletions(-) create mode 100644 data/db/update_1_0_37.sql create mode 100644 src/main/kotlin/com/aitrainer/api/model/Faq.kt create mode 100644 src/main/kotlin/com/aitrainer/api/model/FaqTranslation.kt create mode 100644 src/main/kotlin/com/aitrainer/api/model/TrainingPlan.kt create mode 100644 src/main/kotlin/com/aitrainer/api/model/TrainingPlanDetail.kt create mode 100644 src/main/kotlin/com/aitrainer/api/repository/FaqRepository.kt create mode 100644 src/main/kotlin/com/aitrainer/api/repository/TrainingPlanRepository.kt diff --git a/build.gradle.kts b/build.gradle.kts index 9436950..53746db 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -11,7 +11,7 @@ plugins { } group = "com.aitrainer" -version = "1.0.36" +version = "1.0.37" java.sourceCompatibility = JavaVersion.VERSION_1_8 repositories { diff --git a/data/db/update_1_0_37.sql b/data/db/update_1_0_37.sql new file mode 100644 index 0000000..992d102 --- /dev/null +++ b/data/db/update_1_0_37.sql @@ -0,0 +1,68 @@ +START TRANSACTION; + +CREATE TABLE `training_plan` ( + `training_plan_id` INT(11) NOT NULL AUTO_INCREMENT, + `name` CHAR(50) NOT NULL COLLATE 'utf8_hungarian_ci', + `type` CHAR(50) NULL DEFAULT NULL COLLATE 'utf8_hungarian_ci', + PRIMARY KEY (`training_plan_id`) USING BTREE +) +COLLATE='utf8_hungarian_ci' +ENGINE=InnoDB +; + +CREATE TABLE `training_plan_detail` ( + `training_plan_detail_id` INT(11) NOT NULL AUTO_INCREMENT, + `training_plan_id` INT(11) NOT NULL, + `exercise_type_id` INT(11) NOT NULL, + `sort` INT(3) UNSIGNED ZEROFILL NULL DEFAULT NULL, + `set` INT(3) NULL DEFAULT NULL, + `repeats` INT(5) NULL DEFAULT NULL COMMENT '-1: max', + `weight` DOUBLE NULL DEFAULT NULL COMMENT '-1: calculated', + `resting_time` INT(3) NULL DEFAULT NULL, + `parallel` TINYINT(4) NULL DEFAULT NULL, + `day` CHAR(50) NULL DEFAULT NULL COLLATE 'utf8_hungarian_ci', + PRIMARY KEY (`training_plan_detail_id`) USING BTREE +) +COLLATE='utf8_hungarian_ci' +ENGINE=InnoDB +; + + +CREATE TABLE `customer_training_plan` ( + `customer_training_plan_id` INT(11) NOT NULL AUTO_INCREMENT, + `customer_id` INT(11) NOT NULL DEFAULT '0', + `training_plan_id` INT(11) NOT NULL DEFAULT '0', + `date_add` DATETIME NULL DEFAULT NULL, + PRIMARY KEY (`customer_training_plan_id`) USING BTREE +) +COLLATE='utf8_hungarian_ci' +ENGINE=InnoDB +; + +CREATE TABLE `faq` ( + `faq_id` INT(11) NOT NULL AUTO_INCREMENT, + `name` CHAR(50) NOT NULL COLLATE 'utf8_hungarian_ci', + `description` TEXT NULL DEFAULT NULL COLLATE 'utf8_hungarian_ci', + PRIMARY KEY (`faq_id`) USING BTREE +) +COLLATE='utf8_hungarian_ci' +ENGINE=InnoDB +; + +CREATE TABLE `faq_translation` ( + `translation_id` INT(11) NOT NULL AUTO_INCREMENT, + `faq_id` INT(11) NOT NULL DEFAULT '0', + `name_translation` CHAR(50) NOT NULL DEFAULT '0' COLLATE 'utf8_hungarian_ci', + `description_translation` TEXT NULL DEFAULT NULL COLLATE 'utf8_hungarian_ci', + `language_code` CHAR(2) NULL DEFAULT 'en' COLLATE 'utf8_hungarian_ci', + PRIMARY KEY (`translation_id`) USING BTREE, + INDEX `faq_id` (`faq_id`) USING BTREE +) +COLLATE='utf8_hungarian_ci' +ENGINE=InnoDB +; + + +UPDATE configuration set config_value = "1.0.37", date_change=CURRENT_DATE WHERE config_key = "db_version"; + +COMMIT; diff --git a/src/main/kotlin/com/aitrainer/api/controller/PackageController.kt b/src/main/kotlin/com/aitrainer/api/controller/PackageController.kt index d4668cc..32feaec 100644 --- a/src/main/kotlin/com/aitrainer/api/controller/PackageController.kt +++ b/src/main/kotlin/com/aitrainer/api/controller/PackageController.kt @@ -23,7 +23,9 @@ class PackageController(private val exerciseAbilityRepository: ExerciseAbilityRe private val evaluationRepository: EvaluationRepository, private val sportRepository: SportRepository, private val tutorialRepository: TutorialRepository, - private val descriptionRepository: DescriptionRepository + private val descriptionRepository: DescriptionRepository, + private val faqRepository: FaqRepository, + private val trainingPlanRepository: TrainingPlanRepository ) { private val logger = LoggerFactory.getLogger(javaClass) @@ -71,6 +73,12 @@ class PackageController(private val exerciseAbilityRepository: ExerciseAbilityRe val listDescriptions = descriptionRepository.findAll() val listDescriptionJson: String = gson.toJson(listDescriptions) + val listFaq = faqRepository.findAll() + val listFaqJson: String = gson.toJson(listFaq) + + val listTrainingPlan = trainingPlanRepository.findAll() + val listTrainingPlanJson = gson.toJson(listTrainingPlan) + val packageJson: String = getClassRecord(ExerciseDevice::class.simpleName, listDevicesJson) + "|||" + getClassRecord(Product::class.simpleName, listProductsJson) + @@ -83,7 +91,9 @@ class PackageController(private val exerciseAbilityRepository: ExerciseAbilityRe "|||" + getClassRecord(Evaluation::class.simpleName, listEvaluationJson) + "|||" + getClassRecord(Sport::class.simpleName, listSportsJson) + "|||" + getClassRecord(Tutorial::class.simpleName, listTutorialJson) + - "|||" + getClassRecord(Description::class.simpleName, listDescriptionJson) + "|||" + getClassRecord(Description::class.simpleName, listDescriptionJson) + + "|||" + getClassRecord(Faq::class.simpleName, listFaqJson) + + "|||" + getClassRecord(TrainingPlan::class.simpleName, listTrainingPlanJson) return if (packageJson.isEmpty()) ResponseEntity.notFound().build() else ResponseEntity.ok().body(packageJson) diff --git a/src/main/kotlin/com/aitrainer/api/model/Faq.kt b/src/main/kotlin/com/aitrainer/api/model/Faq.kt new file mode 100644 index 0000000..8a2a1a4 --- /dev/null +++ b/src/main/kotlin/com/aitrainer/api/model/Faq.kt @@ -0,0 +1,20 @@ +package com.aitrainer.api.model + +import com.google.gson.annotations.Expose +import org.hibernate.annotations.Fetch +import org.hibernate.annotations.FetchMode +import org.springframework.lang.NonNull +import javax.persistence.* + +@Entity +data class Faq ( + @Expose @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @get: NonNull var faqId: Long = 0, + @Expose @get: NonNull var name: String, + @Expose @get: NonNull var description: String, + +) { + @OneToMany(cascade = [(CascadeType.ALL)], fetch = FetchType.EAGER, mappedBy = "faq") + @Fetch(value = FetchMode.SUBSELECT) + @Expose val translations: List = mutableListOf().toList() + +} \ No newline at end of file diff --git a/src/main/kotlin/com/aitrainer/api/model/FaqTranslation.kt b/src/main/kotlin/com/aitrainer/api/model/FaqTranslation.kt new file mode 100644 index 0000000..58b222b --- /dev/null +++ b/src/main/kotlin/com/aitrainer/api/model/FaqTranslation.kt @@ -0,0 +1,19 @@ +package com.aitrainer.api.model + +import com.fasterxml.jackson.annotation.JsonIgnore +import com.google.gson.annotations.Expose +import org.springframework.lang.NonNull +import javax.persistence.* +import javax.validation.constraints.NotBlank + +@Entity +data class FaqTranslation ( + @Expose @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @get: NonNull var translationId: Long = 0, + @Expose @get: NotBlank var languageCode: String? = "hu", + @Expose @get: NonNull var nameTranslation: String? = null, + @Expose @get: NonNull var descriptionTranslation: String? = null +) { + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "faqId", nullable = false) + @JsonIgnore val faq: Faq? = null +} \ No newline at end of file diff --git a/src/main/kotlin/com/aitrainer/api/model/TrainingPlan.kt b/src/main/kotlin/com/aitrainer/api/model/TrainingPlan.kt new file mode 100644 index 0000000..e05b774 --- /dev/null +++ b/src/main/kotlin/com/aitrainer/api/model/TrainingPlan.kt @@ -0,0 +1,20 @@ +package com.aitrainer.api.model + +import com.google.gson.annotations.Expose +import org.hibernate.annotations.Fetch +import org.hibernate.annotations.FetchMode +import org.springframework.lang.NonNull +import javax.persistence.* +import javax.validation.constraints.NotBlank + +@Entity +data class TrainingPlan ( + @Expose @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @get: NonNull var trainingPlanId: Long = 0, + @Expose @get: NotBlank var name: String = "", + @Expose @get: NotBlank var type: String = "", +) { + @OneToMany(cascade = [(CascadeType.ALL)], fetch = FetchType.EAGER, mappedBy = "trainingPlan") + @Fetch(value = FetchMode.SUBSELECT) + @Expose val details: List = mutableListOf().toList() + +} \ No newline at end of file diff --git a/src/main/kotlin/com/aitrainer/api/model/TrainingPlanDetail.kt b/src/main/kotlin/com/aitrainer/api/model/TrainingPlanDetail.kt new file mode 100644 index 0000000..8a8f992 --- /dev/null +++ b/src/main/kotlin/com/aitrainer/api/model/TrainingPlanDetail.kt @@ -0,0 +1,30 @@ +package com.aitrainer.api.model + +import com.fasterxml.jackson.annotation.JsonIgnore +import com.google.gson.annotations.Expose +import org.springframework.lang.NonNull +import javax.persistence.* +import javax.validation.constraints.NotBlank + +@Entity +data class TrainingPlanDetail ( + @Expose @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @get: NonNull var trainingPlanDetailId: Long = 0, + @Expose @get: NotBlank var exerciseTypeId: Int = 0, + @Expose @get: NotBlank var sort: Int = 0, + @Expose @get: NotBlank var set: Int = 0, + @Expose @get: NotBlank var repeats: Int = 0, + @Expose @get: NotBlank var weight: Double = 0.0, + @Expose @get: NotBlank var restingTime: Int = 0, + @Expose @get: NotBlank var parallel: Boolean = false, + @Expose var day: String? = null, + +) { + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "trainingPlanId", nullable = false) + @JsonIgnore + val trainingPlan: TrainingPlan? = null + + + +} \ No newline at end of file diff --git a/src/main/kotlin/com/aitrainer/api/repository/FaqRepository.kt b/src/main/kotlin/com/aitrainer/api/repository/FaqRepository.kt new file mode 100644 index 0000000..24c9780 --- /dev/null +++ b/src/main/kotlin/com/aitrainer/api/repository/FaqRepository.kt @@ -0,0 +1,9 @@ +package com.aitrainer.api.repository + +import com.aitrainer.api.model.Faq +import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.stereotype.Repository + +@Repository +interface FaqRepository: JpaRepository { +} \ No newline at end of file diff --git a/src/main/kotlin/com/aitrainer/api/repository/TrainingPlanRepository.kt b/src/main/kotlin/com/aitrainer/api/repository/TrainingPlanRepository.kt new file mode 100644 index 0000000..573d1b4 --- /dev/null +++ b/src/main/kotlin/com/aitrainer/api/repository/TrainingPlanRepository.kt @@ -0,0 +1,9 @@ +package com.aitrainer.api.repository + +import com.aitrainer.api.model.TrainingPlan +import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.stereotype.Repository + +@Repository +interface TrainingPlanRepository: JpaRepository { +} \ No newline at end of file diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties index 39bb83c..1e78877 100644 --- a/src/main/resources/application-prod.properties +++ b/src/main/resources/application-prod.properties @@ -17,6 +17,6 @@ logging.config=classpath:logback-spring.xml logging.file=logs # if the database structure has been changed, increment this version number -application.version=1.0.36 +application.version=1.0.37 jwt.secret=aitrainer \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 1e7f922..3a2fa50 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -17,6 +17,6 @@ logging.config=classpath:logback-spring.xml logging.file=logs # if the database structure has been changed, increment this version number -application.version=1.0.36 +application.version=1.0.37 jwt.secret=aitrainer \ No newline at end of file diff --git a/src/test/kotlin/com/aitrainer/api/test/AppPackageTest.kt b/src/test/kotlin/com/aitrainer/api/test/AppPackageTest.kt index f09fc92..134f290 100644 --- a/src/test/kotlin/com/aitrainer/api/test/AppPackageTest.kt +++ b/src/test/kotlin/com/aitrainer/api/test/AppPackageTest.kt @@ -41,6 +41,10 @@ class AppPackageTest { private lateinit var tutorialRepository: TutorialRepository @Autowired private lateinit var descriptionRepository: DescriptionRepository + @Autowired + private lateinit var faqRepository: FaqRepository + @Autowired + private lateinit var trainingPlanRepository: TrainingPlanRepository @Test fun testAppPackage() { @@ -58,7 +62,9 @@ class AppPackageTest { evaluationRepository, sportRepository, tutorialRepository, - descriptionRepository + descriptionRepository, + faqRepository, + trainingPlanRepository ) val response: ResponseEntity<*> = controller.getPackageData() @@ -150,6 +156,21 @@ class AppPackageTest { assertEquals(descriptions.size, 2) assertEquals(descriptions[0].translations.size, 1) assertEquals(descriptions[0].name, "sales_page") + } else if (record[0] == Faq::class.simpleName) { + val faqJson: String = record[1] + val type = object : TypeToken?>() {}.type + val faqs: List = gson.fromJson(faqJson, type) + assertEquals(faqs.size,1) + assertEquals(faqs[0].name, "What is 1RM?") + assertEquals(faqs[0].translations[0].languageCode, "hu") + } else if (record[0] == TrainingPlan::class.simpleName) { + val trainingPlanJson: String = record[1] + val type = object : TypeToken?>() {}.type + val plans: List = gson.fromJson(trainingPlanJson, type) + assertEquals(plans.size,2) + assertEquals(plans[1].name, "Biceps") + assertEquals(plans[0].details[0].exerciseTypeId, 63) + assertEquals(plans[0].details[1].weight, -1.0) } } }