Skip to content

Domain & Features

Marco Trivisonno edited this page Apr 26, 2024 · 16 revisions

Diagram

Domain diagram
@startuml Domain Diagram
!theme reddress-lightgreen
skinparam defaultFontName monospaced

title Domain Diagram

interface ProductEntity {
  {abstract} +String get id()
  {abstract} +String get name()
  {abstract} +String? get barcode()
  {abstract} +String? get brand()
  {abstract} +String? get imageFrontUrl()
  {abstract} +String? get imageFrontSmallUrl()
  {abstract} +Duration? get expectedShelfLife()
  {abstract} +StorageType? get suggestedStorageType()
  {abstract} +int? get unsealedLifeTimeInDays()
  {abstract} +Measure? get measure()
}
ProductModel *-- Measure: measure
ProductEntity --> StorageType: suggestedStorageType

class ProductModel {
  +String id
  +String name
  +String? barcode
  +String? brand
  +String? imageFrontUrl
  +String? imageFrontSmallUrl
  +Duration? expectedShelfLife
  +StorageType? suggestedStorageType
  +int? unsealedLifeTimeInDays
  +Measure? measure
}

class User {
  +String id
  +String email
  +String displayName
  +List<String> houseIds
}

class House {
  +String id
  +String name
  +String? description
  +String ownerId
  +List<String> adminIds
  +List<String> userIds
}

User --* House: ownerId
User --* HouseUser: userId
HouseUser *-- House: houseId

class HouseUser {
  +String userId
  +String houseId
  +bool isOwner
  +bool isAdmin
}

House *-- Storage: houseId

class Storage {
  +String id
  +String name
  +String? description
  +StorageType storageType
  +String houseId
}

StorageType <-- Storage: storageType

enum StorageType {
  FRIDGE
  FREEZER
  PANTRY
}

' enum ItemCategory {
'   MEAT
'   FISH
'   EGG
'   FRUIT
'   VEGETABLE
'   LEGUMES
'   DAIRY
'   CEREALS
' }

interface ItemEntity {
  {abstract} +String get id()
  {abstract} +String get productId()
  {abstract} +Date get initialExpiryDate()
  {abstract} +DateTime get createdAt()
  {abstract} +String get storageId()
  {abstract} +DateTime? get openedAt()
  {abstract} +int? get unsealedLifeTimeInDays()
  {abstract} +int get amount()
  ---
  +Date get actualExpiryDate()
  {abstract} +ItemEntity copyWith()
}

class ItemModel {
  +String id
  +String productId
  +Date initialExpiryDate
  +DateTime createdAt
  +String storageId
  +DateTime? openedAt
  +int? unsealedLifeTimeInDays
  +int amount

  +Date get actualExpiryDate()
  +ItemEntity copyWith()
}

ItemEntity <|-- ItemModel

Storage *-- ItemEntity: storageId

class Measure {
  +double quantity
  +UnitOfMeasure unitOfMeasure
}
Measure *-- UnitOfMeasure: unitOfMeasure
enum UnitOfMeasure {
  KILOGRAM
  LITER
}

ProductEntity <|-- ProductModel
ProductEntity <.. ItemEntity: references

@enduml

Entities

Entities vs Models

Product

A Product is a good that can be purchased and consumed. Think of it as a product in a supermarket, grocery store, etc., or even something that you made or grew yourself.

A product has the following properties:

  • id*: a unique identifier for the product
  • name*: the name of the product
  • barcode: the barcode of the product
  • brand: the brand of the product
  • imageFrontUrl: the URL of the image of the front of the product
  • imageFrontSmallUrl: the URL of a smaller version of the image of the front of the product
  • expectedShelfLife: how long the product is expected to last after it has been "produced" (e.g. packaged, harvested, etc.)
  • unsealedLifeTimeInDays: how long the product is expected to last after it has been opened
  • suggestedStorageType: the suggested StorageType for the product
  • measure: the measure of the product

Measure

The measure is a pair of:

  • quantity*: a number
  • unit of measure*: a unit of measure

Inventory

The inventory is the whole set of storages and all their items in the user's possession. It is not a real entity, but a concept that can be derived from the user's storages and items.

Storage

A storage is a place where items can be stored.

A storage has the following properties:

  • id*: a unique identifier for the storage
  • name*: the name of the storage
  • storageType*: the type of the storage
  • description: a description of the storage

Storage type

A storage has a mandatory type that can be one of the following:

  • FRIDGE
  • FREEZER
  • PANTRY

Item

An item is a product that has been added to the user's inventory.

An item has the following properties:

  • id*: a unique identifier for the item
  • productId*: the id of the product it refers to
  • initialExpiryDate*: the initial expiry date of the item as mentioned on the product's packaging or by common knowledge (e.g., a banana is known to last for a 5 to 7 days)
  • createdAt*: the date and time when the item was added to the inventory. This property is determined by the system.
  • storageId*: the id of the storage where the item is stored
  • openedAt: the date and time when the item was opened. This property is null if the item has not been opened yet.
  • unsealedLifeTimeInDays: the number of days the item can last after it has been opened. This property is initially copied from the product's property unsealedLifeTimeInDays and can be changed by the user.
  • amount*: the number of units of the item. By default, it is 1. See Grouping items for more information.

An item has the following derived properties:

  • actualExpiryDate: the actual expiry date of the item. This property is determined by the system based on the openedAt property:
    • if the item has not been opened, it is equal to the initialExpiryDate
    • if the item has been opened, it is the minimum between
      • the initialExpiryDate
      • the openedAt date + unsealedLifeTimeInDays

Users and Houses

Static Badge

A User is a person who uses the app. A user can be part of one or more houses.

A House is defined by a group of users and storages. A house must have at least one user.

A house has the following properties:

  • id*: a unique identifier for the house
  • name*: the name of the house, e.g., "Milan Home"
  • description: a description of the house
  • ownerId*: the id of the user who created the house. This user is the owner of the house. The owner is the only user allowed to delete the house even though a house cannot be deleted it it has other users than the owner themselves. The owner can transfer the ownership to another user by leaving the house.
  • adminIds: a list of ids of the users who are admins of the house. Admins can add and remove users from the house (the owner cannot be removed).

NB: it's the house who "owns" the storages with items and not the user!

Features

Grouping items

...

Add item

Item with barcode

User has to scan the product's barcode, and, if the product is recognised user should insert some info:

  • product expiration date
  • storage
  • measure (unit of measure and quantity) (e.g. 500 gr)
  • units (the number of product he buyer, 2 packs of 500gr cookies)

Fresh item

TBD

See add item discussion to know if user wants to add an item that is the same as an existing item.

Delete item

User deletes the item from his inventory. User can undo the deletion, in this case a new item with same information is created.

Open item

A user can open one item at a time. Opening an item means decrease the unit of the item by 1 each time and creating a new item with the date the user opened the item.

Consume an item

User chooses how many units of the item he has consumed and this value is decrease from the total item units. This action is allow only if the units of the item is greater than 1.

Completely consume an item

This action is similar to delete item. The item will be removed from the inventory. User can undo the action, in this case a new item with same information is created.

Notifications

There are several type of notifications:

  • expiring notification: item is going to expire / to be eaten soon -> open the item page
  • daily notification: what did you consume today or what did you buy today? -> open the app
  • reminder notification: user does not open the app by days -> open the app
  • opened item notification: an opened item by days -> open the item page

All notification contains the following fields:

  • id: the id of the notification
  • title: the title of the notification;
  • body: the content of the notification;
  • type: the type of the notification;

If the notification interacts with some content it will have the contentId.

Clone this wiki locally