Sprint 2 Design and Planning - swsnu/swppfall2022-team18 GitHub Wiki
oOo (recOmmend yOur Outfit)
Design and Planning Document
10/21/2022, version 1.0
Document Revision History
- Rev. 1.0 2022-10-21 - initial version
- Rev. 1.1 2022-10-26 - add ERD, fix frontend design, backend design
System Architecture
Design Details
Model

-
User
- ID PK varchar
- username varchar
- password varchar
-
Closet
- ID PK int
- User int FK >- User.ID
-
Outfit
- ID PK int
- outfit_name varchar
- outfit_info varchar
- popularity int
- purchase_link varchar
- image ImageField
- image_link varchar
-
UserCloth
- ID PK int
- closet int FK >- Closet.ID
- name varchar
- image ImageField
- image_link varchar
- type varchar
- color varchar
- pattern varchar
- label_set int FK >- LabelSet.ID
- dates text
-
SampleCloth
- ID PK int
- name varchar(200)
- image ImageField
- image_link varchar
- type varchar
- color varchar
- pattern varchar
- label_set int FK >- LabelSet.ID
- outfit int FK >- Outfit.ID
-
LabelSet
- ID PK int
- type varchar
- color varchar
- pattern varchar
Views
1. Closet Page (/closet)
- Display all the clothes and labels user uploaded
- By select filter of cloth class, user can see only the top, bottom or outer clothes.
- By clicking the ‘Add’ button, a modal page that users can upload their new clothes pops up.
- Move to 2. Add Cloth Pop-up Page (
/closet/add)
- Move to 2. Add Cloth Pop-up Page (
- By clicking the cloth image, a modal page that shows the details of the cloth pops up.
- Move to Cloth Detail Pop-up Page (
/closet/:id)
- Move to Cloth Detail Pop-up Page (
- Header is displayed.
- By clicking
My informationbutton, move to **11.Settingpage (/setting). - By clicking
Logoutbutton, move to **8.Loginpage (/login) and logout.
- By clicking
2. Add Cloth Pop-up
- User can add new cloth and label into ‘Closet’ page
- By clicking ‘Upload’ button, user can upload a cloth image and see the preview image
- For the color label, color label of the image is set either by ML model that classifies color or user can select the color label on their own
- For the type and pattern lable, user can select cloth's labels
- When both the cloth image and label is set -> ‘Add’ button is enabled
- By clicking ‘Add’ button, pop-up window is closed and closet page is refreshed, and user can see the outfit list filtered to class of the cloth he/she uploaded
- By clicking 'Cancel' button -> pop-up window closed
3. Cloth Detail Pop-up
- Cloth image and types are displayed
- User can see get recommendation button, edit button, delete button and cancle button.
- By clicking the ‘Delete’ button, user can delete the cloth he/she chose.
- By clicking the ‘Recommended Styles’ button, the user is moved to ‘Outfit Page (
/outfit)’. Label information is sent so that the filter in ‘Outfit Page’ can be automatically set. - By clicking 'Cancel' button, pop-up window closed
- Calender is displayed
- If user selects the date in calender, 'add date' button or 'delete worn date' button is displayed.
- user can record the date when they wear the cloth by select the date and click the 'add date' button.
- user can delete the date in worn date log by select the date and click the 'delete worn date' button.
4. Outfit Page (/outfit)
- Display all the outfits sorted by popularity
- User can see 'userHave', 'recommend', 'set Filter' and 'reset' button.
- By clicking the image of outfit in list
- move to 6. Outfit Detail page
- By clicking 'Add Label Filter' button
- move to 5. The modal 'Outfit Filter Setting' pops up.
- If some labels are set, labels and erase button for each label are displayed.
- If user clicks erase button for label, selected label is removes from current filter.
- By clicking 'userHave' button
- 'userHave' filter set and page refreshed.
- By clicking 'recommend' button
- 'recommend' filter set and page refreshed.
- By clicking 'reset' button
- All set filter removes
- Header is displayed.
- By clicking
My informationbutton, move to **11.Settingpage (/setting). - By clicking
Logoutbutton, move to **8.Loginpage (/login) and logout.
- By clicking
5. Outfit Filter Setting Pop-up
- Display 'MetaType', 'Type', 'Color' and 'Pattern' options.
- User can select labels in each categories.
- By setting 'MetaType' category, 'Type' category's data changed to the specific type of class in that meta type.
- User can see 'Confirm' and 'Cancel' Button
- If user chooses labels and clicks 'Confirm' button, pop-up window is closed, filter applied
- If user clicks 'Cancel' button, pop-up window is closed
6. Outfit Detail Page (/outfit/:id)
- Display data of selected outfit and the list of samplecloth images that are included in outfit
- By clicking image of clothes, move to 7. A modal for Sample Cloth pops up.
- 'Purchase Link' button is displayed.
- By clicking 'Purchase Link' button, redirect to the shopping mall page for outfit outside our service.
- Header is displayed.
- By clicking
My informationbutton, move to **11.Settingpage (/setting). - By clicking
Logoutbutton, move to **8.Loginpage (/login) and logout.
- By clicking
7. Sample Cloth Pop-up
- Display image and label of selected samplecloth
- 'Purchase button' and 'close' button are displayed.
- By clicking 'Close 'button', pop-up window is closed.
- By clicking 'Purchase Link' button, redirect to the shopping mall page for cloth outside our service.
8. Login Page (/login)
- User can log in and access
Sign UpPage (/signup).- By clicking
Sign Upbutton, move to 9. SingUp Page (/signup) - When the user enters the name and password and presses
Sign Inbutton, the user is moved toHomepage (/home). - If there is no user whose name and password match, the letter "name or password does not match" appears under the password input area.
- By clicking
9. SignUp Page (/signup)
- If the user enters name, password, and password confirmation and presses
Sign Upbutton, you can sign up.- If the name already exists, the letter "The name already exists" appears under the PW confirmation area, and the user cannot sign up.
- If the PW input and PW confirmation input are not the same, the letter 'Password does not match' appears at the bottom of the PW confirmation area and cannot sign up.
- If the subscription is successful, the user is moved to
Loginpage (/login) with a pop-up stating that the subscription was successful.
10. Home Page (/home)
- Closet preview window is displayed.
- User can see three photos of clothes the user have uploaded in the closet.
- User can access **1. 'Closet' page (
/closet) by pressingMorebutton in the closet preview window.
- Today's outfit window is displayed.
- User can see a picture of recommended outfit and detailed information of outfit.
- Press
Wearbutton in today's outfit window, the data of worn date is recorded.
- Popular Outfit window is displayed.
- User can see the list of image and info of popular outfits.
- By clicking the image of outfit, move to **6.
Outfit DetailPage (/outfit/:id). - My clicking
Morebutton, move to **4.OutfitPage (/outfit).
- Header is displayed.
- By clicking
My informationbutton, move to **11.Settingpage (/setting). - By clicking
Logoutbutton, move to **8.Loginpage (/login) and logout.
- By clicking
11. Setting Page (/setting)
- The user can modify his/her name, email, and password.
- When modifying a password, the password and password confirmation input values must be the same.
- The user can withdraw through
Withdrawalbutton. - The modified information is saved through
Savebutton and moved to **10.Homepage (/home).
Frontend Design

Container
- Closet
Title- Text data that shows user entered closet page
ClosetItemadd-cloth-buttonclickAddClothPopupHandler()- This method will be called when the user clicks the 'Add’ button
- Add Cloth Pop-up Page (
/closet/add) will pop up
- Outfit
Header
-
Outfit Preview- Component
OutfitPreview
- Component
-
clickUserHaveHandler()- This method will be called when the user clicks the
userhavebutton
- This method will be called when the user clicks the
-
clickRecommendHandler()- This method will be called when the user clicks the
recommendbutton
- This method will be called when the user clicks the
-
clickFilterHandler()- This method will be called when the user clicks the
Add Label Filterbutton FilterModalis poped up
- This method will be called when the user clicks the
-
clickDoneHandler()- This method will be called when the user clicks the
Donebutton inFilterModal - Close the
FilterModal
- This method will be called when the user clicks the
-
clickResetHandler()- This method will be called when the user clicks the
resetbutton. - Reset the filter component and list all outfits
- This method will be called when the user clicks the
-
clickNextPageHandler()- This method will be called when the user clicks the
next-page-button. - Set page value to current page + 1
- This method will be called when the user clicks the
-
clickBeforePageHandler()- This method will be called when the user clicks the
before-page-button. - Set page value to current page - 1
- This method will be called when the user clicks the
-
clickFirstPageHandler()- This method will be called when the user clicks the
first-page-button. - Set page value to 1
- This method will be called when the user clicks the
-
clickOutfitImageHandler()- This mehtod will be called when the user clicks the one of outfit images.
- Navigate to
/outfit/:id/
-
clickTypeDeleteButton()- This method will be called when the user clicks the
type-filter-delete-button - Reset type value in filter
- This method will be called when the user clicks the
-
clickColorDeleteButton()- This method will be called when the user clicks the
color-filter-delete-button - Reset color value in filter
- This method will be called when the user clicks the
-
clickPatternDeleteButton()- This method will be called when the user clicks the
pattern-filter-delete-button - Reset pattern value in filter
- This method will be called when the user clicks the
-
OutfitDetail
Header
Image- Image of selected outfit
OutfitInfo- Description of outfit
name-label- Description of clothes that consists the outfit
SampleModal- Component
SampleModal
- Component
outfit-purchase-buttonclothImage- Image of clothes in outfit
clickOutfitClothDetailHander()- This method will be called when the user clicks the image of the clothes
- Outfit Cloth Detail Page (
outfit/:id/cloth/:id) will pop up
clickOutfitPurchaseHandler()- This method will be called when the user clicks
Purchase Linkbutton - Move to external shopping mall site
- This method will be called when the user clicks
-
clickOutfitDetailCancelHandler()- This method will be called when the user clicks the
Cancelbutton - Cloth Detail Pop-up Page will be closed
- This method will be called when the user clicks the
-
Login
username-input- User enters his/her Name.
pw-input- User enters his/her Password.
LoginErrorMessage- "Name or password does not match".
clickLoginBtnHandler()- This method will be called when the user clicks the
Sign Inbutton. - Check through
loginChecker()if login is possible when there are an input name and password. - If Login is impossible, display
LoginErrorMessage. - If Login is possible, send Login request and navigate to
Homepage (/home).
- This method will be called when the user clicks the
loginChecker()- Send a request to check if there is a matching user name.
- If the response is true, check whether it is the same as the password of the response.
- Returns true if the name and password match, and false in all other cases.
-
Sign Up
username Input- User enters his/her Name.
PW Input- User enters his/her Password.
PW Input confirmation- User enters his/her Password.
existsSameIDError- "The Name already exists"
notMatchPWError- "Password does not match"
clickSignUpBtnHandler()- This method will be called when the user clicks the
Sign Upbutton - Check whether a user with the same name exists through
existsSameIDChecker(). - If the same name already exists, display
existsSameIDError - Check that
PW InputandPW Input confirmationare the same, if not the same, displaynotMatchPWError. - If all conditions are passed, send a signup request.
- If successful, show pop-up and navigate to
Loginpage (/login).
- This method will be called when the user clicks the
existsSameIDChecker()- Send a request to check if there is a matching user name.
- Returns true if the user doesn't exist.
-
Setting
name Area- User can see his/her name.
Email Input- User enters his/her email.
PW Input- User enters his/her Password.
PW Input confirmation- User enters his/her Password.
notMatchPWError- "Password does not match"
clickWithdrawBtnHandler()- This method will be called when the user clicks the
Withdrawalbutton. - Send a withdrawal request, if successful, display pop-up.
- This method will be called when the user clicks the
clickEditBtnHandler()- This method will be called when the user clicks the
Savebutton. - Check that
PW InputandPW Input confirmationare the same, if not the same, displaynotMatchPWError. - If
PW InputandPW Input confirmationare the same, send a edit user information request.
- This method will be called when the user clicks the
-
Home
Closet DivClosetItem- component of clothes in closet
Today's OutfitOutfitPreview- component of Outfits
OutfitsOutfitPreview- component of Outfits
dataFormat()- This method will be called in the
clickWearHandler() - Format the date data
- This method will be called in the
clickClosetMoreBtnHandler()- This method will be called when the user clicks the
Morebutton in the closet preview window. - navigate to
Closetpage (/closet).
- This method will be called when the user clicks the
clickOutfitMoreBtnHandler()- This method will be called when the user clicks the
Morebutton in the outfit preview window. - navigate to
Outfitpage (/outfit).
- This method will be called when the user clicks the
clickOutfitImgBtnHandler()- This method will be called when the user clicks the Outfit Image.
- navigate to
Outfit DetailPage (/outfit/:id).
clickLogoutBtnHandler()- This method will be called when the user clicks the
Logoutbutton. - navigate to
LoginPage (/login).
- This method will be called when the user clicks the
clickSettingBtnHandler()- This method will be called when the user clicks the
My Settingbutton. - navigate to
SettingPage (/setting).
- This method will be called when the user clicks the
clickWearHandler()- This method will be called when the user clicks the 'Wear' button.
- Post data on when user wore the cloth
Component
-
Header
header Text- Logo of our service 'oOo'
- Connected to
clickHeaderHandler()which makes user move to Home Page ('/Home')
info Button- Connected to
clickInfoHandler()which makes user move to Setting Page ('/Setting')
- Connected to
logout Button- Connected to
clickLogOutHandler()which makes user sign out and move to first page ('Signin/up')
- Connected to
-
ClosetItem
Cloth Image- Image of userCloth
clickClothDetailPopupHandler()- This method is called when the user clicks the
Cloth Image ClothDetailModalwill pop up
- This method is called when the user clicks the
clickClothDetailPopupCloseHandler()- This method is called when the user clicks the close button in
ClothDetailModal
- This method is called when the user clicks the close button in
-
ClothDetailModal
Image- image of selected userCloth
Label- labels of selected userCloth
Calendar- Calendar that shows the worn date log
clickDeleteClothHandler()- This method is called when the user clicks the ‘Delete’ button
ClothDetailModalwill be closed andClosetPage will be refreshed
clickMoveToRecommendedStyleHandler()- This method is called when the user clicks the ‘Get Recommendation’ button
- User will be moved to
OutfitPage
clickEditClothHandler()- This method is called when the user finished editing and clicked 'finish edit' button.
- Save the set data in edit mode.
- Update the data of selected userCloth in DB.
setWearDateHandler(clickedDate : any)- This method is called when the user clicks a date in calendar.
- set
AddOrDelete : booleanstate to true or false.
clickSaveWearDateHandler(addOrDelete: boolean)- This method is called when the user clicks '입은 날짜 추가하기' button or '입은 날짜 삭제하기' button.
- Update the worn date log of selected userCloth in DB.
clickTypeOptionHandler()- This method is called when the user selected type label in
TypeFilterin edit mode. - Set type of selected userCloth.
- This method is called when the user selected type label in
clickColorOptionHandler()- This method is called when the user selected color label in
ColorFilterin edit mode. - Set color of selected usercloth.
- This method is called when the user selected color label in
clickPatternOptionHandler()- This method is called when the user selected pattern label in
PatternFilterin edit mode. - Set pattern of selected userCloth.
- This method is called when the user selected pattern label in
-
AddClothModal
Image- Image of cloth user puts in
Upload Clothbutton- Upload button to find cloth image in user's local PC.
Meta Type SelectOption- Select options for metaType of userCloth
clickMetaTypeOptionHandler()- This method is called when the user selected metaType of uploaded cloth.
TypeFiltermodal's options are changed into chosen metaType.
clickAddClothHandler()- This method is called when the user clicked 'create' button.
- If the user uploaded image and selected every labels, new userCloth is created in DB and
AddClothModalclosed.
saveFileImage()- This method is called when the user selected image of cloth in user's local PC.
- Save image and call api
model/to classify color label by ML model.
clickTypeOptionHandler()- This method is called when the user selected type label in
TypeFilterin edit mode. - Set type of selected userCloth.
- This method is called when the user selected type label in
clickColorOptionHandler()- This method is called when the user selected color label in
ColorFilterin edit mode. - Set color of selected userCloth.
- This method is called when the user selected color label in
clickPatternOptionHandler()- This method is called when the user selected pattern label in
PatternFilterin edit mode. - Set pattern of selected userCloth.
- This method is called when the user selected pattern label in
-
OutfitPreview
Image- Image of Outfit
- Connected to
clickOutfitDetailHandler()which makes user move toOutfit Detailpage (outfit/:id).
Info- Information of Outfit
-
SampleClothModal
Image- Image of selected sampleCloth
Label- Label of selected SampleCloth
clickPurchaseHandler()- This method will be called when the user clicks
Purchase Linkbutton - Move to external shopping mall site
- This method will be called when the user clicks
-
FilterModal
Meta Type Selectoption- Select options for metaType
clickMetaTypeOptionHandler()- This method is called when the user selected metaType
TypeFiltermodal's options are changed into chosen metaType.
TypeFilterColorFilterPatternFilterclickTypeOptionHandler()- This method is called when the user selected type label in
TypeFilter - Set type label of
FilterModal
- This method is called when the user selected type label in
clickColorOptionHandler()- This method is called when the user selected color label in
ColorFilter - Set color label of
FilterModal
- This method is called when the user selected color label in
clickPatternOptionHandler()- This method is called when the user selected pattern label in
PatternFilter - Set pattern label of
FilterModal
- This method is called when the user selected pattern label in
Donebutton- Connected to
clickFilterConfirmHandler()which sets filter inOutfitpage (outfit/).
- Connected to
-
TypeFilter
Type SelectOption- Select options for type of cloth
- Connected to
clickTypeOptionHandler()which sets type label.
-
ColorFilter
Color SelectOption- Select options for color of cloth
- Connected to
clickColorOptionHandler()which sets color label.
-
PatternFilter
Pattern SelectOption- Select options for pattern of cloth
- Connected to
clickPatternOptionHandler()which sets pattern label.
Frontend Relation

Backend Design
Closet
| API | GET | POST | PUT | DELETE |
|---|---|---|---|---|
| closet/ | Get clothes list user uploaded | Upload new usercloth | X | X |
| closet/:id/ | Get usercloth by id | Update wear date log of selected usercloth | Edit labels of selected usercloth | Delete selected usercloth |
Outfit
| API | GET | POST | PUT | DELETE |
|---|---|---|---|---|
| outfit/ | get all outfit list | get filtered outfit list | X | X |
| outfit/today/ | get today's recommend outfit | X | X | X |
| outfit/:id/ | get selected outfit and sampleclothes included | X | X | X |
| outfit/samplecloth/:id/ | get selected samplecloth and matched usercloth | X | X | X |
User
| API | GET | POST | PUT | DELETE |
|---|---|---|---|---|
| user/info/ | Get user info (username) | X | Edit user info (password) | Delete user |
| user/signin/ | X | Login user | X | X |
| user/signup/ | X | Signup user | X | X |
| user/signout/ | X | Logout user | X | X |
| user/token/ | Get csrf token | X | X | X |
Model
| API | GET | POST | PUT | DELETE |
|---|---|---|---|---|
| model/ | X | Get color label of the image by using ML model | X | X |
Implementation Plan
Our service provides users to upload their clothes in the online closet and to get recommendation of the outfit based on the cloth user chose. Thus Closet page and Outfit page are key features of our service to achieve our service's goal. As these pages have to handle many functions user can do inside, our team planned to separated these pages into several components in a software development aspect, and treat as key features to implement.
Other frontend pages, e.g. Home page, displays previews of Closet page and Outfit page, so our team planned to implement these two pages prior to other pages, and then move on to implementing Home page, Sign Up page and Settings page. But before implementing the two pages, we'll implement Log In page and related backend software to set up a skeleton code for our convenience(Sprint2, please see the below table for the details).
After that we'll move on to Closet page and Outfit page. Although these pages have relations to each other as user should first visit Closet page -> choose a cloth he/she want to take on -> and then move on to Outfit page to get an outfit recommendation, we do not think there would be any components or formats that could be used for both pages, so we planned to implement the two pages and their backends at the same time (Sprint 3-1, please see the below table for the details).
As a last phase we'll implement Home page, Sign Up page and Settings page(Sprint 3-2, please see the below table for the details). After all of these work are finished, we'll implement testing codes for the front & backend to ensure the program works properly.
All members are going to implement both frontend and backend - details for the implementation schedule are planned as below.
Frontend
| Sprint | Page | Description | Expected Duration | Assignee | Possible Risks |
|---|---|---|---|---|---|
| 2 | Log In | Log-in page for a user | 2 days | Jaeyoung | |
| 3-1 | Closet | Displays user clothes | 3 days | Pyojin, Jaeyoung | |
| 3-1 | Outfit | Displays popular outfits and outfit recommendation | 4 days | Junyoung, Pyojin | Error while handling filters |
| 3-2 | Sign up | Sign-up page for a user | 1 day | Junkyoung | |
| 3-2 | Settings | Settings page for a user | 1 day | Junkyoung | |
| 3-2 | Home | Displays previews of Closet page and Outfit page |
3 days | Junkyoung, Junyoung |
Backend
| Sprint | Page | Description | Expected Duration | Assignee | Possible Risks |
|---|---|---|---|---|---|
| 2 | Log In | Handle user log-in | 2 days | Jaeyoung | |
| 3 | Closet | Handle closet-related functions & data | 7 days | Pyojin, Jaeyoung | |
| 3 | Outfit | Handle outfit-related functions & data | 7 days | Junyoung, Pyojin | Error while handling filters |
Testing plan
Unit testing
A purpose of a unit testing is to determine if the unit works as intended and to detect bug early so that we can find and fix it which would be hard to be fixed later testing stages. We're going to test every components of both front & backend.
For framework, we're going to use Jest/Enzyme and Mock/Spy for components that has external dependency. We're going to use Django's TestCase class for the backend.
Functional testing
A purpose of a functional testing is to verify that each feature works as intended, and it involves comparing each function to the relevant requirements of the function to determine whether it shows the output as user expected.
We're going to test if APIs are returning appropriate response or functions as it is intended to. Again, Jest/Enzyme will be used for testing the frontend code and Django's TestCase will be used for the backend code.
Acceptance & Integration Test
A purpose of an acceptance test is to verify appropriate changes are made as intended after certain event - Jest and Enzyme will be used. Travis will be used for an integration test.