From 91d39a4d8357e38d5a5ddc1b78cd3c73ff4a2a09 Mon Sep 17 00:00:00 2001
From: JMARyA <jmarya@hydrar.de>
Date: Wed, 16 Apr 2025 04:27:45 +0200
Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/{ => core}/flow.rs        |  0
 src/{ => core}/item.rs        |  4 ++++
 src/{ => core}/location.rs    |  0
 src/core/mod.rs               |  5 +++++
 src/{ => core}/transaction.rs |  5 ++++-
 src/{ => core}/variant.rs     | 11 ++++++++++-
 src/main.rs                   | 11 ++++++-----
 7 files changed, 29 insertions(+), 7 deletions(-)
 rename src/{ => core}/flow.rs (100%)
 rename src/{ => core}/item.rs (94%)
 rename src/{ => core}/location.rs (100%)
 create mode 100644 src/core/mod.rs
 rename src/{ => core}/transaction.rs (96%)
 rename src/{ => core}/variant.rs (96%)

diff --git a/src/flow.rs b/src/core/flow.rs
similarity index 100%
rename from src/flow.rs
rename to src/core/flow.rs
diff --git a/src/item.rs b/src/core/item.rs
similarity index 94%
rename from src/item.rs
rename to src/core/item.rs
index a407b4a..65c182e 100644
--- a/src/item.rs
+++ b/src/core/item.rs
@@ -35,6 +35,7 @@ pub struct Item {
     pub variants: HashMap<String, Variant>,
 }
 
+/// Get the path of an image file in `path`
 pub fn get_image(path: &std::path::Path) -> Option<String> {
     let parent = path.parent()?;
     let file_name = path.file_stem()?.to_str()?;
@@ -120,12 +121,14 @@ impl Item {
         self.variants.get(variant).cloned()
     }
 
+    /// Get all active `Transaction`s of this `Item` not yet consumed
     pub async fn inventory(&self) -> Vec<Transaction> {
         sqlx::query_as("SELECT * FROM transactions WHERE item = $1 AND consumed_timestamp IS NULL ORDER BY created DESC")
         .bind(&self.id)
         .fetch_all(get_pg!()).await.unwrap()
     }
 
+    /// Get all active `Transaction`s of this `Item` not yet consumed of `origin`
     pub async fn inventory_by_origin(&self, origin: &str) -> Vec<Transaction> {
         sqlx::query_as("SELECT * FROM transactions WHERE item = $1 AND consumed_timestamp IS NULL AND origin = $2 ORDER BY created DESC")
         .bind(&self.id)
@@ -133,6 +136,7 @@ impl Item {
         .fetch_all(get_pg!()).await.unwrap()
     }
 
+    /// Get all active `Transaction`s of this `Item` not yet consumed of `destination`
     pub async fn consumed_by_destination(&self, destination: &str) -> Vec<Transaction> {
         sqlx::query_as("SELECT * FROM transactions WHERE item = $1 AND consumed_timestamp IS NOT NULL AND destination = $2 ORDER BY created DESC")
         .bind(&self.id)
diff --git a/src/location.rs b/src/core/location.rs
similarity index 100%
rename from src/location.rs
rename to src/core/location.rs
diff --git a/src/core/mod.rs b/src/core/mod.rs
new file mode 100644
index 0000000..1761011
--- /dev/null
+++ b/src/core/mod.rs
@@ -0,0 +1,5 @@
+pub mod flow;
+pub mod item;
+pub mod location;
+pub mod transaction;
+pub mod variant;
diff --git a/src/transaction.rs b/src/core/transaction.rs
similarity index 96%
rename from src/transaction.rs
rename to src/core/transaction.rs
index 5c2c71a..2b95645 100644
--- a/src/transaction.rs
+++ b/src/core/transaction.rs
@@ -54,14 +54,17 @@ impl Transaction {
         .fetch_one(get_pg!()).await.unwrap()
     }
 
+    /// Get a reference to the `Item` of the `Transaction`
     pub async fn item(&self) -> Option<&Item> {
         get_itemdb!().get_item(&self.item)
     }
 
+    /// Get a reference to the `Variant` of the `Item` of the `Transaction`
     pub async fn item_variant(&self) -> Option<Variant> {
         get_itemdb!().get_item(&self.item)?.variant(&self.variant)
     }
 
+    /// Get a `Transaction` via `id`
     pub async fn get(id: &uuid::Uuid) -> Option<Self> {
         sqlx::query_as("SELECT * FROM transactions WHERE id = $1")
             .bind(id)
@@ -203,7 +206,7 @@ impl ToAPI for Transaction {
             "timestamp": self.created.timestamp(),
             "consumed": consumed,
             "note": self.note,
-            "expired": self.is_expired().await
+            "expired": self.is_expired().await,
         })
     }
 }
diff --git a/src/variant.rs b/src/core/variant.rs
similarity index 96%
rename from src/variant.rs
rename to src/core/variant.rs
index 692b44a..e14628b 100644
--- a/src/variant.rs
+++ b/src/core/variant.rs
@@ -104,6 +104,8 @@ impl Variant {
         }
     }
 
+    /// Get a API id for this Item Variant.
+    /// The ID has the format: `<ITEM>::<VARIANT>`
     pub fn item_variant_id(&self) -> String {
         format!("{}::{}", self.item, self.variant)
     }
@@ -189,6 +191,7 @@ impl Variant {
         .unwrap()
     }
 
+    /// Get Transactions within `year` and `month`
     pub async fn get_transaction_timeslice(&self, year: i32, month: u32) -> Vec<Transaction> {
         let (start, end) = timestamp_range(year, month);
 
@@ -198,6 +201,7 @@ impl Variant {
         .fetch_all(get_pg!()).await.unwrap()
     }
 
+    /// Get all unique origins
     pub async fn get_unique_origins(&self) -> Vec<String> {
         let res: Vec<(String,)> = sqlx::query_as("SELECT DISTINCT(origin) FROM transactions WHERE origin NOT LIKE 'flow::%' AND item = $1 AND variant = $2")
         .bind(&self.item)
@@ -206,6 +210,7 @@ impl Variant {
         res.into_iter().map(|x| x.0).collect()
     }
 
+    /// Get all unique destinations
     pub async fn get_unique_destinations(&self) -> Vec<String> {
         let res: Vec<(String,)> = sqlx::query_as("SELECT DISTINCT(destination) FROM transactions WHERE destination NOT LIKE 'flow::%' AND item = $1 AND variant = $2")
         .bind(&self.item)
@@ -214,6 +219,7 @@ impl Variant {
         res.into_iter().map(|x| x.0).collect()
     }
 
+    /// Get the last `limit` price values for `origin`
     pub async fn price_history_by_origin(&self, origin: &str, limit: Option<i64>) -> Vec<f64> {
         let res: Vec<(f64,)> = sqlx::query_as(
             &format!("SELECT price FROM transactions WHERE item = $1 AND variant = $2 AND origin = $3 ORDER BY created DESC {}", if let Some(limit) = limit {
@@ -227,6 +233,7 @@ impl Variant {
         res.into_iter().map(|x| x.0).collect()
     }
 
+    /// Get the latest price for `origin`
     pub async fn get_latest_price(&self, origin: Option<String>) -> f64 {
         if let Some(origin) = origin {
             let res: (f64,) = sqlx::query_as("SELECT price FROM transactions WHERE item = $1 AND variant = $2 AND origin = $3 ORDER BY created DESC LIMIT 1")
@@ -257,6 +264,7 @@ impl Variant {
         (false, 0)
     }
 
+    /// Check if the `Variant` satisfies `StorageConditions`
     pub async fn satisfy_condition(&self, conditions: &StorageConditions) -> bool {
         if let Some(needs) = &self.needs {
             if let Some(room_temp) = conditions.accurate_temperature().await {
@@ -346,7 +354,8 @@ impl Variant {
             "name": self.name,
             "min": self.min,
             "expiry": self.expiry,
-            "barcodes": self.barcodes
+            "barcodes": self.barcodes,
+            "needs": self.needs
         })
     }
 }
diff --git a/src/main.rs b/src/main.rs
index 67779c0..b97670f 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -7,15 +7,16 @@ use rocket::{http::Method, launch};
 use tokio::sync::OnceCell;
 
 mod config;
+mod core;
 mod db;
-mod flow;
 mod integrity;
-mod item;
 mod json_store;
-mod location;
+pub use core::flow;
+pub use core::item;
+pub use core::location;
+pub use core::transaction;
+pub use core::variant;
 mod routes;
-mod transaction;
-mod variant;
 
 pub static PG: OnceCell<sqlx::PgPool> = OnceCell::const_new();