Repository: IgnisDa/ryot (language: rust)

Issue:
Include collections for workout and workout template exports



Discussion / hints:

Fix patch:
diff --git a/Cargo.lock b/Cargo.lock
index fca5289bb6..e426244964 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2206,6 +2206,7 @@ dependencies = [
  "config",
  "database-models",
  "database-utils",
+ "dependent-models",
  "enums",
  "file-storage-service",
  "fitness-models",
diff --git a/crates/models/common/src/lib.rs b/crates/models/common/src/lib.rs
index d33d9263a7..3fcfe26829 100644
--- a/crates/models/common/src/lib.rs
+++ b/crates/models/common/src/lib.rs
@@ -1,7 +1,7 @@
 use async_graphql::{Enum, InputObject, SimpleObject};
 use enum_meta::{meta, Meta};
 use enums::EntityLot;
-use schematic::Schematic;
+use schematic::{ConfigEnum, Schematic};
 use sea_orm::{prelude::DateTimeUtc, FromJsonQueryResult};
 use serde::{Deserialize, Serialize};
 use strum::{Display, EnumIter};
@@ -46,7 +46,7 @@ impl Default for StoredUrl {
     }
 }
 
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize, Enum)]
+#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize, Enum, ConfigEnum)]
 pub enum CollectionExtraInformationLot {
     String,
     Number,
@@ -65,6 +65,7 @@ pub enum CollectionExtraInformationLot {
     SimpleObject,
     FromJsonQueryResult,
     InputObject,
+    Schematic,
 )]
 #[graphql(input_name = "CollectionExtraInformationInput")]
 pub struct CollectionExtraInformation {
diff --git a/crates/models/database/src/collection.rs b/crates/models/database/src/collection.rs
index 4c43ba0e3c..937a4c41a6 100644
--- a/crates/models/database/src/collection.rs
+++ b/crates/models/database/src/collection.rs
@@ -4,11 +4,14 @@ use async_graphql::SimpleObject;
 use async_trait::async_trait;
 use common_models::CollectionExtraInformation;
 use nanoid::nanoid;
+use schematic::Schematic;
 use sea_orm::entity::prelude::*;
 use sea_orm::ActiveValue;
 use serde::{Deserialize, Serialize};
 
-#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize, SimpleObject)]
+#[derive(
+    Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize, SimpleObject, Schematic,
+)]
 #[sea_orm(table_name = "collection")]
 #[graphql(name = "Collection")]
 pub struct Model {
diff --git a/crates/models/dependent/src/lib.rs b/crates/models/dependent/src/lib.rs
index 4764663c6a..4109b0878c 100644
--- a/crates/models/dependent/src/lib.rs
+++ b/crates/models/dependent/src/lib.rs
@@ -42,6 +42,17 @@ pub struct SearchResults<T: OutputType> {
     pub items: Vec<T>,
 }
 
+/// Details about a specific exercise item that needs to be exported.
+#[skip_serializing_none]
+#[derive(Debug, Serialize, Deserialize, Clone, Schematic)]
+#[serde(rename_all = "snake_case")]
+pub struct ImportOrExportWorkoutItem {
+    /// The details of the workout.
+    pub details: workout::Model,
+    /// The collections this entity was added to.
+    pub collections: Vec<String>,
+}
+
 /// Complete export of the user.
 #[skip_serializing_none]
 #[derive(Debug, Serialize, Deserialize, Clone, Schematic)]
@@ -54,7 +65,7 @@ pub struct CompleteExport {
     /// Data about user's measurements.
     pub measurements: Option<Vec<user_measurement::Model>>,
     /// Data about user's workouts.
-    pub workouts: Option<Vec<workout::Model>>,
+    pub workouts: Option<Vec<ImportOrExportWorkoutItem>>,
     /// Data about user's media groups.
     pub media_group: Option<Vec<media_models::ImportOrExportMediaGroupItem>>,
     /// Data about user's exercises.
diff --git a/crates/services/exporter/Cargo.toml b/crates/services/exporter/Cargo.toml
index c23385d52e..63d34a77f5 100644
--- a/crates/services/exporter/Cargo.toml
+++ b/crates/services/exporter/Cargo.toml
@@ -13,6 +13,7 @@ common-models = { path = "../../models/common" }
 common-utils = { path = "../../utils/common" }
 database-models = { path = "../../models/database" }
 database-utils = { path = "../../utils/database" }
+dependent-models = { path = "../../models/dependent" }
 enums = { path = "../../enums" }
 file-storage-service = { path = "../file-storage" }
 fitness-models = { path = "../../models/fitness" }
diff --git a/crates/services/exporter/src/lib.rs b/crates/services/exporter/src/lib.rs
index 1321f844fb..8c7211c17e 100644
--- a/crates/services/exporter/src/lib.rs
+++ b/crates/services/exporter/src/lib.rs
@@ -13,6 +13,7 @@ use database_models::{
 use database_utils::{
     entity_in_collections, item_reviews, user_measurements_list, workout_details,
 };
+use dependent_models::ImportOrExportWorkoutItem;
 use enums::EntityLot;
 use file_storage_service::FileStorageService;
 use fitness_models::UserMeasurementsListInput;
@@ -348,7 +349,11 @@ impl ExporterService {
         for workout_id in workout_ids {
             let details =
                 workout_details(&self.db, &self.file_storage_service, user_id, workout_id).await?;
-            writer.serialize_value(&details).unwrap();
+            let exp = ImportOrExportWorkoutItem {
+                details: details.details,
+                collections: details.collections.into_iter().map(|c| c.name).collect(),
+            };
+            writer.serialize_value(&exp).unwrap();
         }
         Ok(())
     }
diff --git a/crates/services/importer/src/generic_json.rs b/crates/services/importer/src/generic_json.rs
index 8d9f69720e..8071729c92 100644
--- a/crates/services/importer/src/generic_json.rs
+++ b/crates/services/importer/src/generic_json.rs
@@ -30,7 +30,7 @@ pub async fn import(
         .workouts
         .unwrap_or_default()
         .into_iter()
-        .map(|w| exercises_service.db_workout_to_workout_input(w))
+        .map(|w| exercises_service.db_workout_to_workout_input(w.details))
         .collect_vec();
 
     Ok(ImportResult {
diff --git a/docs/includes/export-schema.ts b/docs/includes/export-schema.ts
index e7bf44d01e..c104cc4f40 100644
--- a/docs/includes/export-schema.ts
+++ b/docs/includes/export-schema.ts
@@ -316,6 +316,14 @@ export interface Workout {
 	summary: WorkoutSummary;
 }
 
+/** Details about a specific exercise item that needs to be exported. */
+export interface ImportOrExportWorkoutItem {
+	/** The collections this entity was added to. */
+	collections: string[];
+	/** The details of the workout. */
+	details: Workout;
+}
+
 /** Complete export of the user. */
 export interface CompleteExport {
 	/** Data about user's exercises. */
@@ -329,5 +337,5 @@ export interface CompleteExport {
 	/** Data about user's people. */
 	people: ImportOrExportPersonItem[] | null;
 	/** Data about user's workouts. */
-	workouts: Workout[] | null;
+	workouts: ImportOrExportWorkoutItem[] | null;
 }


Test patch: