Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE REQUEST] - Physical item model proposal #865

Closed
grapemix opened this issue Jun 15, 2024 · 6 comments
Closed

[FEATURE REQUEST] - Physical item model proposal #865

grapemix opened this issue Jun 15, 2024 · 6 comments

Comments

@grapemix
Copy link

Hi,

Thanks for open sourcing this project. I am glad to see more open source Rust project and I've seen you actively promote and integrate ryot with other app. So I guess you are open to suggestions.

After taking a glance of the repo, it seems that ryot only able to keep track of virtual items so far. The ability of tracking physical items is missing. For example, if I have 2 bottles of flu medicine.

  • One is bought in 6 months ago, expired in 2 years, 80% full, stored in 100 tablets bottle, located in home;
  • and another one is bought in 1 years ago, checked in 2 days ago, expired in 4 months later, 50% full, stored in 50 tablets bottle in office.

Ryot cannot handle case like this, is my understanding correct?


I would like to propose a generic model to handle above cases. Although I am experienced with PgSql, I have not used SeaORM before, so I would just present the DB relation as diagram.

Unlike virtual items, a physical items have attributes shared in common and individual unique attributes. So I suggest we should break down the model as two.


Problem 1) No generic physical item type model for attributes shared in common

Proposal:

pub struct Stock {
    pub id: String,
    pub name: String,
    #[serde(alias = "description")]
    pub overview: Option<String>,
    pub barcode: Option<String>,
    pub url_list: Option<HashMap<String, String>>,
    pub invert_url_list: Option<HashMap<String, String>>,
    #[serde(deserialize_with = "deserialize_date")]
    pub created: NaiveDate,
    #[serde(deserialize_with = "deserialize_date")]
    pub updated: Option<NaiveDate>,
    #[serde(deserialize_with = "deserialize_date")]
    pub deleted: Option<NaiveDate>,
    pub thumbnail: Option<String>,
}

The url_list is for product page, manufactory page, online manual... And the invert_url_list is for other app's integration, just like the back link concept from wiki(https://wikiless.northboot.xyz/wiki/Backlink?lang=en).


Problem 2) No generic physical item instance model for individual unique attributes

Proposal:

pub struct Instance {
    pub id: String,
    pub quantity: i32,
    pub barcode: Option<String>,
    #[serde(deserialize_with = "deserialize_date")]
    pub expired: Option<NaiveDate>,
}

1 Stock <--> N Instance

Since some items' barcode might different on each one, I suggest that we put barcode fields on both Stock and Instance.


Problem 3) No location model for Instance

Proposal:

pub struct Location {
    pub id: String,
    pub name: String,
    pub barcode: Option<String>,
}

M Location <--> N Instance

Hopefully, we can add an new item instance by just scanning the barcode to "input" location and then scanning another barcode to "input" an item instance in one day. The point is no keyboard involved and just fetching data from an DBs by using the barcode.


Problem 4) No flexible tag model for Stock and Instance

Proposal:

pub struct Tag {
    pub id: String,
    pub key: String,
    pub val: Option<String>,
    pub num: Option<i32>,
}

M Stock <--> N Tag
M Instance <--> N Tag
M Location <--> N Tag

In this way, for example, we can store the following criteria:

  • Tag(name="minAge", num="3") for Stock
  • Tag(name="maxTemperature", num="-1", val="celsius") for Location
  • Tag(name="size", num="50", val="ml") for Instance
  • Tag(name="capacity", num="50", val="percent") for Instance

And query the following criteria:

  • Tell me any medicine for babies(minAge<=3) which will be expired in next 2 months
  • Tell me any frozen food which is low in stock (20%)

Problem 5) No operation model for Instance for auditing or tracking purpose

Proposal:

#[derive(EnumIter, DeriveActiveEnum)]
#[sea_orm(rs_type = "i32", db_type = "Integer")]
pub enum OperationType {
    Purchased = 0,
    Sold = 1,
    CheckPrice = 2,
    Verify = 3,
}

pub struct InstanceOperation {
    pub id: String,
    pub price: Option<f32>,
    pub transaction_url: Option<String>,
    #[serde(deserialize_with = "deserialize_date")]
    pub operation_date: Option<NaiveDate>,
}

1 InstanceOperation <--> M Person/Company
M InstanceOperation <--> 1 Instance

In this way, for example, we can store the following criteria:

  • Purchase milk for $5 from an online store by me a week ago, and the order page is stored in transaction_url
  • Mary has checked if milk has been expired 2 days ago
  • Some price tracker app like Huginn, check if your favorite product is on sale and we can see the log thru the link in transaction_url

Thanks for your time to read till here. I think ryot has lots of potential, so I hope my proposal is welcome in here. In this generic way, hopefully :

  1. You don't need to add every inventory type and reduce your work load.
  2. Allow developers to integrate this app better with other apps because they don't have to wait for a specific inventory type exists.

I hope you would consider the above proposal to further release ryot's potential.

@IgnisDa
Copy link
Owner

IgnisDa commented Jun 15, 2024

This is a long proposal so I'll read and reply to individual points later (thanks for your interest!)

But have you checked out #73? It might be similar to what you described.

@grapemix
Copy link
Author

Totally understand. Please take all the time you need.

As for #73, the yaml proposal is for user input only (which is nice), but we all know SQL DB works in different way than human. A generic SQL schema can be little bit tricky in this feature since we are using SQL instead of document based NoSQL DB in here and hence I proposed the above models. Also, that ticket have not addressed the shared attributes and individual unique attributes problem.

BTW, since Rust is a static language, you might need to use procedural-macros which can be tricky sometimes.

I think my proposal can more or less resolve the following tickets:

Again, I hope my proposal can save you time by completing multiple tickets at once, instead of wasting your time. I understand you will need a lot of time to digest, response, refine and hopefully implement. I will only be grateful and patient. Thanks.

@aureateflux
Copy link

aureateflux commented Jun 28, 2024

Is this in scope for RYOT? This seems like something more at home with something like Homebox, which is specifically designed as a home inventory system and already has at least some of the features discussed here.

I do think this somewhat duplicates #73 and maybe these ideas should be brought into that discussion.

@grapemix
Copy link
Author

  1. duplicates [FEATURE REQUEST] - Allow Ryot to track anything #73 ? Feature-wised, yes.
  2. I took a look for Homebox a while ago. That project is a good one, but
    a. The original author archives the repo now. Although someone picks it up, I don't know how long will the project last
    b. The original author specific said don't want to support food. Food monitoring hay-kot/homebox#431

If there exists a DB schema is flexible enough to support all, why not? It feels good to have a single inventory for everything. But you are right, may be we just have to fall back to what we can have.

@aureateflux
Copy link

I recently heard about a food tracking app called "Grocy" that sounds like what you're looking for, actually! Not to say I don't think your ideas here don't belong as a contribution to the "track everything with RYOT" discussion, just that it sounds like exactly the kind of feature set you're discussing here. 🙂

@IgnisDa
Copy link
Owner

IgnisDa commented Aug 28, 2024

Hi @grapemix, thanks for the extensive proposal you wrote up. However, at this time, I don't think I will be moving forward with these suggestions. I feel like #73 would be a better way to achieve what you want.

That being said, I am opening to hear suggestions. Thanks again!

@IgnisDa IgnisDa closed this as not planned Won't fix, can't repro, duplicate, stale Aug 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants