IgnisDa / ryot

Roll your own tracker!
https://ryot.io
GNU General Public License v3.0
1.78k stars 46 forks source link

[FEATURE REQUEST] - Physical item model proposal #865

Open grapemix opened 2 months ago

grapemix commented 2 months ago

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.

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:

And query the following criteria:


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:

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 commented 2 months ago

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 commented 2 months ago

Totally understand. Please take all the time you need.

As for https://github.com/IgnisDa/ryot/issues/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 commented 1 month ago

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 commented 1 month ago
  1. duplicates https://github.com/IgnisDa/ryot/issues/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. https://github.com/hay-kot/homebox/issues/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 commented 1 month ago

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. 🙂