Furthermore, not sure how we are going to handle the searching. Maybe a full-text search index? For now, it has been ignored, but the filters seem to be working properly.
349 lines
13 KiB
Markdown
349 lines
13 KiB
Markdown
# Technical Specifications
|
|
|
|
<!--toc:start-->
|
|
- [Technical Specifications](#technical-specifications)
|
|
- [Devices & Responsiveness](#devices-responsiveness)
|
|
- [Page Requirements](#page-requirements)
|
|
- [Home](#home)
|
|
- [UI Requirements](#ui-requirements)
|
|
- [API Requirements](#api-requirements)
|
|
- [Favorites](#favorites)
|
|
- [Create](#create)
|
|
- [Shopping List](#shopping-list)
|
|
- [Profile](#profile)
|
|
- [Database Requirements](#database-requirements)
|
|
- [Table ID Choice](#table-id-choice)
|
|
- [Tables](#tables)
|
|
- [Enums and Types](#enums-and-types)
|
|
<!--toc:end-->
|
|
|
|
Application specifications.
|
|
|
|
## Devices & Responsiveness
|
|
|
|
This application is a web app, however, it is built following a "mobile-first" pattern. Which
|
|
means the desktop interface is lacking and will be designed after the completion of the mobile
|
|
web interface.
|
|
|
|
## Page Requirements
|
|
|
|
This section outlines the specific technical requirements for the application. It is broken down
|
|
by page.
|
|
|
|
|
|
#### Home
|
|
|
|
The home page will server as the landing page where users can search recipes, filter their search, as
|
|
well as view lists of recently made recipes, recently viewed and trending recipes lists.
|
|
|
|
##### UI Requirements
|
|
|
|
- [x] Welcome Banner
|
|
- [x] Video display with large text overhead
|
|
- [x] Sub text below the video with a "Call to Action"
|
|
- [ ] ~Interactive banner that can be hidden with a "Got it!" or "X"~
|
|
|
|
- [x] Message & Pills Banner
|
|
- [x] Message with text like "Craving Something Specific?"
|
|
- [ ] ~Pill buttons below which allow for a direct search for meal type~
|
|
|
|
- [x] Search bar
|
|
- [x] Ability to search for recipes, meals, and tags
|
|
|
|
- [x] Filter drop down
|
|
- [x] **Filter by meal** - *E_Meal enum type*
|
|
- [x] **Filter by time requirements** - *15min, 30min, 1hr, 1.5hr, +1.5hr*
|
|
- [x] **Filter by difficulty** - *1 to 5 stars*
|
|
- [x] **Filter by serving size** - *1 to 16*
|
|
|
|
- [x] Recipe of The Week
|
|
- [x] **Single recipe display** of the best performing recipe, with spotlight effect
|
|
- [x] **Display recipe details in depth** - Title, duration, **image***, meal category, simplified description
|
|
- [x] **Make now** button to allow easy access to meal directions
|
|
|
|
- [x] Recently Viewed List
|
|
- [x] Scrolling list of the most recent 5-10 recipes viewed
|
|
- [x] **Display recipe details** - Title, duration, **image***, meal category, and a heart to like the recipe
|
|
|
|
- [x] Make Again List
|
|
- [x] Scrolling list of the most recent 5-10 recipes made
|
|
- [x] **Display recipe details** - Title, duration, **image***, meal category, and a heart to like the recipe
|
|
|
|
- [x] Create Recipe CTA (call-to-action)
|
|
- [x] **Large CTA banner** with text prompting users to create a recipe
|
|
- [x] **Button** to take the user to the create page
|
|
|
|
'*': Not sure yet, still under consideration
|
|
|
|
|
|
##### API Requirements
|
|
|
|
- [ ] Message & Pills Banner
|
|
- [ ] Search all recipes of a specific meal type
|
|
|
|
- [ ] Search bar
|
|
- [ ] Text search on titles based on search query
|
|
- [ ] Text search on tags based on search query
|
|
- [ ] Text search on **meal** based on search query
|
|
|
|
- [ ] Filter drop down
|
|
- [ ] Update search to only contain meals from selected filter
|
|
- [ ] Update search to only contain means that meet the time requirement of the selected filter
|
|
- [ ] Update search to only contain meals that meet the difficulty level of the selected filter
|
|
- [ ] Update search to only contain meals that meet the serving size of the selected filter
|
|
|
|
- [ ] Recipe of The Week
|
|
- [ ] Fetch the most performing recipe of the last 7 days and all of the required meta data
|
|
- [ ] Most views (W: 0.1)
|
|
- [ ] Most makes (W: 0.5)
|
|
- [ ] Most likes (W: 0.3)
|
|
- [ ] Most reviews (W: 0.4)
|
|
- [ ] Highest avg rating (W: 0.2/star, 0.0 - 1.0)
|
|
- [ ] Direct a user to the recipes display page
|
|
- [ ] Telemetry data to collect clicks for each recipe
|
|
|
|
- [ ] Recently Viewed List
|
|
- [ ] Fetch a list of recently viewed meals and all required meta data
|
|
- [ ] Like a post and store it in user's liked posts list
|
|
- [ ] Direct a user to the recipes display page
|
|
- [ ] Telemetry data to collect clicks for each recipe
|
|
|
|
- [ ] Make Again List
|
|
- [ ] Fetch a list of recently viewed meals and all required meta data
|
|
- [ ] Like a post and store it in user's liked posts list
|
|
- [ ] Direct a user to the recipes display page
|
|
- [ ] Telemetry data to collect clicks for each recipe
|
|
|
|
'**': Not sure implementation
|
|
|
|
|
|
|
|
#### Favorites
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### Create
|
|
|
|
The create page will contain a page to create a new recipe. It will include
|
|
all of the required details without any need to move to other pages. The entire
|
|
creation process will take place here
|
|
|
|
|
|
##### UI Requirements
|
|
|
|
- [x] Create Recipe Heading Banner
|
|
- [x] Large, simple text banner that displays a header
|
|
- [x] Smaller text section that contains some useful information for using the wizard
|
|
|
|
- [x] Recipe Creation Wizard
|
|
- [x] **Recipe Details:** required
|
|
- [x] **Recipe title:** small text input (1 to 128)
|
|
- [x] **Recipe description:** large text input
|
|
- [x] **Meal category:** pill radio buttons or drop down*
|
|
- [x] **Service size:** numeric input (1 to 16)
|
|
- [x] **Difficulty rating:** star buttons that can be selected (up to 5)
|
|
- [x] **Duration:** prep and cook time, individual numeric inputs
|
|
- [x] **Ingredients:** required
|
|
- [x] **Dynamic ingredient list:** List of each ingredient
|
|
- [x] **Content:** name and quantity (both text inputs)
|
|
- [ ] **Actions:** delete button and **reorder element***
|
|
- [x] **Add ingredient button:** Simple button to add a blank ingredient row
|
|
- [x] **Instructions:** required
|
|
- [x] **Dynamic instructions list:** Numbered list of each instruction
|
|
- [x] **Content:** number and large text instruction
|
|
- [ ] **Rich text editor?***
|
|
- [ ] **Actions:** delete button and **reorder element***
|
|
- [x] **Add step button:** Simple button to add a blank instruction element
|
|
- [x] **Media & Tags:** optional
|
|
- [x] **Image Upload**
|
|
- [x] Single image selector for the thumbnail image
|
|
- [x] Small image display once one has been upload
|
|
- [x] Remove button to remove the image
|
|
- [x] Replace button to replace the image
|
|
- [x] **Tags**
|
|
- [x] Text input to add tags
|
|
- [ ] Using list of existing tags, use a prefill while typing
|
|
- [x] Tags that don't exist will be added
|
|
- [x] Display a small list of added tags
|
|
- [x] Clicking a tag will remove it from the list
|
|
- [x] **Footer & Submit**
|
|
- [x] Save recipe button to complete the form
|
|
- [ ] Button is disabled until the minimum required fields are complete*
|
|
|
|
- [x] Input Validation
|
|
- [x] Required elements should have a **required indicator**
|
|
- [x] Required elements will be validated input
|
|
- [ ] **Valid:** Green outline or indicator* maybe a small, green check mark
|
|
- [x] **Invalid:** Red outline or indicator* maybe a red border with error text
|
|
|
|
|
|
'*': Not sure yet, still under consideration
|
|
|
|
|
|
##### API Requirements
|
|
|
|
|
|
- [x] Middleware
|
|
- [x] **Authentication:** User must be logged in to access this page
|
|
- [x] **Authentication:** User must be logged in to submit the creation of a recipe (fallback)
|
|
|
|
- [x] Recipe Creation Wizard
|
|
- [x] Create a new recipe object in the database
|
|
- [x] Recipe should be attached to a user (logged in)
|
|
- [x] User should be directed to the view recipe page on a successful creation
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### Shopping List
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### Profile
|
|
|
|
|
|
|
|
## Database Requirements
|
|
|
|
This section outlines the specific technical requirements for the database store for
|
|
this application. It will describe the required tables, fields, and other expectations.
|
|
|
|
|
|
##### Table ID Choice
|
|
|
|
Typically, I like to use UUID's for ID's. However, after some research I have concluded that for this
|
|
application, the use of the `SERIAL` or `SERIAL` type will work sufficiently. Security is not a huge
|
|
concern with this application since no major data will be stored, however, measures will still be in
|
|
place (of course).
|
|
|
|
One of the biggest reasons **I** choose UUID's is their obscurity which provides some basic security
|
|
against specific attack styles (enumeration attacks, etc.), however, I do not anticipate that being a
|
|
large concern, so the simplicity of using an integer will surpass the small, niche benefits of using
|
|
UUID's.
|
|
|
|
|
|
### Tables
|
|
|
|
Below is a breakdown of the required tables and their respective fields. The fields will
|
|
also have a list of attributes which are to be implemented at the database level. **JSONB**
|
|
data fields will also have a small example object. A more in-depth data structure can be
|
|
found in **OTHER** section.
|
|
|
|
- [x] Recipes: Represents a single recipe.
|
|
- [x] ID (PK) Serial
|
|
- [x] Title (Required) string(128)
|
|
- [x] Description (Required) text
|
|
- [x] Instructions (Required) string(1024)[]
|
|
- [x] Serves (Required) int(0..16)
|
|
- [x] Difficulty (Required) int(1..5)
|
|
- [x] Duration (Required) JSONB({ "total": int, "prep": int, "cook": int })
|
|
- [x] Category (Required) E_Meal (defined in the [enums](#enums-and-types) section)
|
|
- [x] Ingredients (Required) JSONB({ "item_a": [{ "name": string, "quantity": string }], "item_b": ... })
|
|
- [x] UserId (FK: User.Id) Serial
|
|
- [x] Modified () date/time stamp
|
|
- [x] Created (Required) date/time stamp
|
|
|
|
- [x] Users: Represents a single user.
|
|
- [x] ID (PK) Serial
|
|
- [x] GoogleId (Unique, Required) text
|
|
- [x] Name (Required) string(64)
|
|
- [x] Email (Unique, Required) string(128)
|
|
- [x] ImageURL () text
|
|
- [x] GoogleRefreshToken () text
|
|
- [x] Created (Required) date/time stamp
|
|
|
|
- [ ] Engagements: Represents a single engagement from a single user.
|
|
- [ ] ID (PK) Serial
|
|
- [ ] Message () text (Used to store any relevant notes, if needed)
|
|
- [ ] Entity (Serial) Serial (Used to relate an entity, if needed)
|
|
- [ ] UserId (FK: User.Id, Required) Serial
|
|
- [ ] Created (Required) date/time stamp
|
|
|
|
- [ ] Likes: **Many-to-many** table to represent a list of recipes liked by a user.
|
|
- [ ] ID (PK) *Composite key***
|
|
- [ ] UserId (FK: User.Id, Required) Serial
|
|
- [ ] RecipeId (FK: Recipe.Id, Required) Serial
|
|
- [ ] Created (Required) date/time stamp
|
|
|
|
- [ ] Tags: Represents a single tag that can be had by many recipes.
|
|
- [ ] ID (PK) Serial
|
|
- [ ] Name (Unique, Required) string(32)
|
|
- [ ] Created (Required) date/time stamp
|
|
|
|
- [ ] RecipeTags: **Many-to-many** table to represent a list of tags on a recipe.
|
|
- [ ] ID (PK) Serial
|
|
- [ ] RecipeId (FK: Recipe.Id, Required) Serial
|
|
- [ ] TagId (FK: Tag.Id, Required) Serial
|
|
- [ ] Created (Required) date/time stamp
|
|
|
|
- [ ] Lists: Represents a single users shopping list.
|
|
- [ ] ID (PK) Serial
|
|
- [ ] UserId (FK: User.Id, Required) Serial
|
|
- [ ] Content (Required) JSONB([ { "name": string, "quantity": string }, ... ])
|
|
- [ ] Created (Required) date/time stamp
|
|
|
|
- [ ] Images: Represents a single image used by a single recipe.
|
|
- [ ] ID (PK) Serial
|
|
- [ ] RecipeId (FK: Recipe.Id, Required) Serial
|
|
- [ ] Alt (Required) string(128) (alt text for accessibility, same as recipe title)
|
|
- [ ] Url (Required) text
|
|
- [ ] Created (Required) date/time stamp
|
|
|
|
- [ ] Reviews: Represents a single review on a recipe from a single author.
|
|
- [ ] ID (PK) Serial
|
|
- [ ] Comment (Required) text
|
|
- [ ] Rating () int(0..5) (Optional b/c nested replies don't need a rating)
|
|
- [ ] ReviewId (FK: Review.Id) Serial (This is used for nested replies)
|
|
- [ ] RecipeId (FK: Recipe.Id, Required) Serial
|
|
- [ ] UserId (FK: User.Id, Required) Serial
|
|
- [ ] Created (Required) date/time stamp
|
|
|
|
- [ ] Notifications: Represents a single user notification.
|
|
- [ ] ID (PK) Serial
|
|
- [ ] UserId (FK: User.Id, Required) Serial
|
|
- [ ] Type (Required) E_Notification
|
|
- [ ] Message (Required) text
|
|
- [ ] Entity (Serial) Serial (Used to relate an entity, if needed)
|
|
- [ ] Read (Required, Default: F) boolean
|
|
- [ ] Created (Required) date/time stamp
|
|
|
|
|
|
'**': Not sure implementation
|
|
|
|
### Enums and Types
|
|
|
|
Below is a breakdown of the required enumerated types that should be stored in the database.
|
|
Various tables will reference these types.
|
|
|
|
- [x] E_Meal: Type to represent the type of meal of a recipe.
|
|
- [x] breakfast: string
|
|
- [x] lunch: string
|
|
- [x] dinner: string
|
|
- [x] dessert: string
|
|
- [x] snack: string
|
|
- [x] side: string
|
|
- [x] other: string
|
|
|
|
- [ ] E_Notification: Type to represent a type of user notification.
|
|
- [ ] comment: string
|
|
- [ ] like: string
|
|
- [ ] system: string
|
|
|
|
- [ ] E_Engagement: Type to represent a type of user engagement.
|
|
- [ ] made: string
|
|
- [ ] liked: string
|
|
- [ ] viewed: string
|
|
- [ ] shared: string
|
|
- [ ] reviewed: string
|
|
- [ ] rated: string
|