Skip to content

Design and Planning

dreamsh19 edited this page Dec 17, 2019 · 42 revisions

Revision History

  • Rev. 1.0 2019-10-19 - initial version
  • Rev. 2.0 2019-12-17 - revised

System Architecture

system_architecture_2

This picture shows the overall structure of triplannet system. Frontend is implemented using React and Redux, with Material UI. Backend is mainly implemented using Django. The client sends HTTP request to our service, and gets HTTP response back. The two main components communicate with each other using data in JSON format. Google Maps API is connected to our service in order to enable place searching service. We included Universarial Sentence Encoder model(from Tensorflow-hub) into our backend to encode sentences to word embedding vectors. Detailed explanation for each component will be provided in the following sections.

Design Details

Model

Here is ER diagram of our model design SWPP - ER diagram

This explains about ER diagram cardinality.

ER Cardinality2

This ER diagram would implemented by django in our service. User and Travel can have many-to-many relation because we can have many collaborators for one schedule. So we add additional mapping table for collaborators to represent it. Similarly, we add Likes, View table for User and Travel many-to-many relation. We also add DL feature at travel table. For the recommendation purpose, we will store embedded vector for each travel plan by using Sentence2Vec model and calculate similarity when we recommend new travel plan. We also store distribution of block for the similar purpose We made nested design for the travel, travelCommit, travelDay, travelBlock to make a structure of travel. This design also make available to deal with a simple version control by travelCommit table, and modified field

image

Views

View2

  1. Login page (/login)

    • logging in with the user account
    • Users can log in with other services’ account(Google, Facebook, …)
    • If a user clicks ‘Sign up’ button -> moves to 2. Sign up page
  2. Sign Up page (/sign_up)

    • Signing up a new user
    • Duplicate check for ‘Email’ and ‘User Name’
    • Password requirements will be applied (longer than N characters, …)
    • If a user clicks ‘Cancel’ or ‘Confirm’ button -> moves to 1. Login page
  • Header
    • Header block will always be on the top of the page.
    • If a user clicks reversed triangle of the header block -> Dropdown menu with ‘My Page’ and ‘Logout’ will be shown.
    • If a user clicks ‘My Page’ in the dropdown menu -> moves to the user’s own 8. User Info page.
    • If a user clicks ‘Logout’ in the dropdown menu -> is logged out and moves to 1. Login page
    • If a user types in ‘@username’ -> list of users which include ‘username’ will be shown. If a user selects one of them -> moves to 8. User Info page of that user.
    • If a user types in ‘keyword’ -> list of ‘#tag’ which include ‘keyword’ will be shown. If a user selects one of them -> moves to 4. Search page with the search result of ‘#tag’
  1. Main page (/main)

    • Main page for users. Logged in users will be redirected here from 1. Login page
    • Shows several popular travel plans and recent plans. (default: 10 plans each)
    • If a user clicks a travel plan block -> moves to 5. Travel Detail page of that travel plan.
  2. Search page (/search)

    • Showing the search result of ‘#tag’.
    • Only the search using a tag is supported.
    • If a user clicks a travel plan block -> moves to 5. Travel Detail page of that travel plan.
  3. Travel Detail page (/travel/:id)

    • Showing the detail of the travel plan.
    • If a user clicks ‘Fork’ button -> This plan will be copied to the user’s travel list in 8. User Info page, with the label of ‘Forked’.
    • If a user is viewing the plan of himself or herself, ‘Fork’ button is disabled.
    • If a user clicks the profile picture or the name of the author -> moves to 8. User Info page of the author.
    • If a user clicks the triangle on the travel day block -> more detailed plans of the day are shown. These will disappear if the user clicks the triangle again.
    • Related plans are provided using our recommendation algorithm using ML.
    • A user can push ‘Like’ button.
    • A user can add comments for the plan.
  4. Create Travel page (/travel/create)

    • Creating a new travel plan.
    • A user can add a photo, a title, a summary, a description, and tags of a plan.
    • If a user clicks ‘Select Period’ button in ‘Info’ tab -> Calendar modal pop-up will appear and a user selects the period of a travel there.
    • Day blocks will be provided according to the selected periods. (ex 3 day blocks for 3-day-period)
    • There are currently 5 kinds of travel blocks: Move, Food, Activity, Accomodation, Custom.
    • A user can add plan block by drag-and-dropping travel blocks provided.
    • A user can change the order of plan blocks by drag-and-dropping a travel block to desired position.
    • A user can delete a plan block by drag-and-dropping it to the trash can icon.
    • If a user finishes making a plan and clicks 'confirm', the plan is posted and the user is redirected to 5. Travel Detail Page.
  5. Edit Travel page (/travel/:id/edit)

    • Same as the create travel page, except that the existing plan will be loaded.
    • If a user edits a travel plan, this will be stored as 'travel commit'. 'travel commit' will be merged into the origin plan when 'Merge' button is clicked.
  6. User Info page (/user/:id)

    • Showing the information of a specific user.
    • If a user is viewing another user’s info page -> ‘Create a new plan’ button and ‘Edit’ button disappears.
    • If a user clicks ‘Create a new plan’ button -> moves to 6. Create Travel page.
    • If a user clicks ‘Edit’ button -> moves to 9. Edit User Info page.
    • If a user clicks ‘...’ button on a travel block -> Dropdown menu with ‘Edit’, ‘Delete’, and ‘Logout’ will be shown.
    • If a user clicks ‘Edit’ in the dropdown menu -> moves to 7. Edit Travel page of that plan.
    • If a user clicks ‘Delete’ in the dropdown menu -> The travel plan is deleted after alerting.
    • If a user clicks ‘Settings’ in the dropdown menu -> moves to 9. Travel Settings page of that plan.
    • If the page is of now-logged-in user, plans to which the user is added as a collaborator is also shown.
    • For plans on collaboration, 2 buttons are provided for dropdown menu when '...' button is clicked: 'Edit' and 'Quit'
    • If a user clicks 'Quit' in the dropdown menu of a plan on collaboration -> The user will be removed from the collaborators list of the plan, and the plan will not show on the user's page.
    • For plans that are not the head of a travel, 'Merge' button will be also shown in the dropdown menu.
    • If a user clicks 'Merge' after some editing, the edited content will be applied to the origin travel.
  7. Edit User Info page (/user/:id/edit)

    • Editing the information of a user.
    • If a user clicks ‘Change’ button -> Related input fields, ‘Cancel’ button, and ‘Confirm’ button will appear.
    • User can change his/her password, nickname, and status message here. Each section has own 'Confirm' button, and this will apply changes for each item.
  8. Travel Settings page (/travel/:id/settings)

    • Manage collaborators and editing the settings of a travel plan.
    • If a user clicks ‘Add’ button -> Input field for username will appear. The behavior of the input field is the same as the search field of the header when searching a user.
    • Radio buttons for setting ‘Visibility’ and ‘Comments’ is provided.

Frontend Design

frontend design

Frontend Components

Containers

  1. Login

    • username
      • User id that a user entered.
    • password
      • User password that a user entered.
    • onSubmit()
      • Request login to backend, get user hash key
      • If a user succeed to login, this page will be redirected to recent schedule page.
      • If a user fail to login, the reason of login failure will be spanned below the password input tag.
  2. Sign Up

    • email
      • User id that a user entered, this value always be checked to be email format.
    • password
      • User password that a user entered.
    • password_confirm
      • Password confirm that a user entered. This value is expected to be same with password. The confirmation is checked automatically with onChange
    • nickname
      • User nickname that a user entered.
    • is_confirm_failure
      • Boolean value
      • If the password and password confirm value are not same, this value will be true o.w. false.
    • checkEmail(), checkNickname()
      • The email/nickname that user entered must be identical under the database.
      • When a user click check button next to the username input tag, this handler will request checkEmail, checkNickname.
      • If the claimed username is already in the database, the value of the username input tag would be null and alert.
      • If the claimed username is not in the database, the check button is disabled until the user change the username value.
    • signUpButtonHandler()
      • Request new user information to backend, get user hash key
      • Redirect to login page when signUp is succeeded.
    • cancelButton Handler()
      • Redirect to Login page.
  3. My Travel

    • travelSchedules
      • this.state.travelSchedules keeps save all schedules registered the user.
      • All contents should contain a title, a period, number of likes, description, image link, is_forked.
    • clickScheduleDetailHandler()
      • This method will be called when a user click a travel block.
      • Move to travel detail page.
    • clickEditScheduleHandler()
      • This method will be called when a user clicks Edit Button.
      • Move to edit travel schedule page.
    • clickDeleteScheduleHandler()
      • This method will be called when a user clicks Delete Button.
      • Delete the schedule after window.confirm the action.
    • clickScheduleSettingHandler()
      • This method will be called when a user clicks Setting Button.
      • Move to travel setting page.
    • clickCreateScheduleHandler()
      • This method will be called when a user clicks Create Button.
      • Move to create travel page.
  4. User Travel

    • travelSchedules
      • this.state.travelSchedules keeps save all schedules registered the user.
      • All contents should contain a title, a period, number of likes, description, image link.
    • clickScheduleDetailHandler()
      • This method will be called when a user click a travel block.
      • Move to travel detail page.
  5. Create Travel

    • Title, Summary, Description
      • Text data that a user writes
    • Image
      • A user can add his/her image about the travel.
    • StartDate
      • Start datetime contains year, month, day
    • EndDate
      • End datetime contains year, month, day
    • Tags
      • Several tags started with '#'
    • Travel Blocks
      • All travel block data, title, description, period ...
    • clickSubmitHandler()
      • This method will be called when a user clicks Submit button.
      • Create a new travel schedule and redirect to travel detail page.
  6. Edit Travel

    • same as Create Schedule page, but initial state value would be travel information.
  7. Travel Detail

    • Title, Summary, Description
      • Text data that a user writes
    • Image
      • Image that users added
    • Period
      • Travel period that contains year, month, day
    • Tags
      • Several tags started with '#'
    • Travel Blocks
      • All travel block data, title, description, period ...
    • Recommendation Travels
      • All travels have their recommendation travels.
      • Communicate with backend to show the recommendations.
    • Comments
      • All comments related to a travel schedule
    • newComment
      • A comment that a user writes
    • Likes
      • Integer value of likes numbers
    • commentHandler()
      • This method will be called when a user clicks Comment button.
      • Create a new comment to travel detail page.
    • clickLikeHandler()
      • This method will be called when a user clicks LIKE.
      • The likes number of the travel will be added.
    • clickForkHandler()
      • This method will be called when a user clicks Fork button.
      • The travel schedule will be cloned to a user space.
    • clickScheduleHandler()
      • This method will be called when a user click Travel Block.
      • Redirect to some recommended travel detail page.
  8. Travel Setting

    • collaborators
      • The list of collaborators of the travel schedule.
    • authorization
      • Private or Public
    • allowComment
      • T/F
    • clickSubmitHandler()
      • This method will be called when a user clicks Submit Button.
      • Submit changed the settings of the schedule.
    • searchCollaborator(string)
      • This method will be called when a user clicks Search Button.
      • The recommended username will be served.
  9. Header

    • clickIconHandler()
      • This method will be called when a user clicks Icon.
      • Redirect to Recent Schedule page.
    • clickMyPage()
      • This method will be called when a user clicks MyPage button.
      • Redirect to My Travel page.
    • logoutHandler()
      • This method will be called when a user clicks Logout Button.
      • Break the session and redirect to login page.
  10. Search Tab

    • query
      • Search query
    • onChangeHandler()
      • This method will be called when a user writes some queries.
      • Matching username or tags will be expanded under the query.
    • clickSearchHandler()
      • This method will be called when a user clicks Search Button.
      • Show the results of query with Search Schedule page.
  11. Recent Travel

    • popularTravel, recentTravel
      • Travel Schedule lists.
    • clickScheduleDetailHandler()
      • This method will be called when a user clicks a travel block.
      • Move to travel detail page.
  12. Search Travel

    • Same as Recent Schedule with specific data
  13. User Profile

    • thumbnail, status
      • Custom image, status that represent the user.
    • password, password confirm
      • Password information to be edited.
    • handleProfile()
      • To handle image that user handles
    • clickSubmitHandler()
      • This method will be called when a user clicks Submit Button.
      • Submit changed the user profile.
  14. 400, 404, 500 Error Page

    • clickLoginHandler()
      • This method will be called when a user clicks Login Button.
      • Redirect to Login page.

Components

  1. TravelOverviewBlock

    • clickTravelHandler()
      • Redirect to travel detail page.
    • clickEditScheduleHandler()
      • This method will be called when a user clicks Edit Button.
      • Move to edit travel schedule page.
    • clickDeleteScheduleHandler()
      • This method will be called when a user clicks Delete Button.
      • Delete the schedule after window.confirm the action.
    • clickScheduleSettingHandler()
      • This method will be called when a user clicks Setting Button.
      • Move to travel setting page.
  2. TravelHeaderBlockView, TravelHeaderBlockEdit

    • clickSubmitHandler()
      • This method will be called when a user clicks Submit Button.
      • Submit changed items.
  3. TravelDayBlockView, TravelDayBlockEdit

    • clickSubmitHandler()
      • This method will be called when a user clicks Submit Button.
      • Submit changed items.
    • clickSpreadHandler()
      • This method will be called when a user clicks Spread Button(shape of inverted traingle).
      • show or hide the all units of this travel day block.
  4. TravelUnitBlockView, TravelUnitBlockEdit

    • clickSubmitHandler()
      • This method will be called when a user clicks Submit Button.
      • Submit changed items.
    • clickSearchHandler()
      • This method will be called when a user clicks Search Button.
      • Return recommended places list(through Google Maps API)
    • clickCalenderHandler()
      • This method will be called when a user clicks a time period window.
      • Show the calendar window to select the period of the unit.
    • clickTravelIconHandler()
      • This method will be called when a user clicks Icon.
      • Span the Icon block to choose representatative icon of the unit.
  5. UserProfile

    • clickEditHandler()
      • This method will be called when a user clicks Edit Button.
      • Redirect to User Profile page.

Reducers(with actions) & Service

  1. User
    • getUser()
      • get a user profile like status, thumbnail, etc.
    • login()
      • post login to server with given username and password.
    • logout()
      • logout the currently logged in user.
    • signUp()
      • post a new user to backend with username, password, nickname.
    • isLoggedIn()
      • request the logged in session is valid.
    • setUserSessionStorage()
      • store the user at user's sessionStorage.
    • getUserSessionStorage()
      • get the stored user from sessionStorage.
    • setUserProfile()
      • request the edited profile of user.
    • setUserPassword()
      • request the changed password of user.
    • searchUser()
      • request recommended user list given user string.
  2. Travel
    • getTravel()
      • get each travel information
    • setTravel()
      • set edited travel information.
    • deleteTravel()
      • delete specific travel.
    • getRecentTravel()
      • get recent travel list to show recent travel page.
    • getPopularTravel()
      • get popular travel list that sorted with likes to show recent travel page.
    • searchTravel()
      • search travel query and get popular travel and recent travel.
    • getUserTravel()
      • get some travels that the user registered.
    • forkTravel()
      • clone the travel to the user.
    • mergeTravel()
      • merge the travel with origin travel.
    • getRecommendTravel()
      • request recommended travel with given travel(machine learning feature).
    • likeToggle()
      • change like status.
  3. Place
    • getPlace()
      • get each place information.
    • postTag()
      • cache information that place searched.
    • searchPlace()
      • request autocomplete place list given place query.
  4. Comment
    • getComments()
      • request all comments related to the travel.
    • postComment()
      • post a new comment.
    • deleteComment()
      • delete my comment.
    • editComment()
      • edit my comment.

Frontend Relations

frontend relation 1 frontend relation 2

  • Above halven picture is about frontend relations.
  • Dotted lines are container relations.
  • Solid lines are relations between containers and others.

Backend Design

The data exchange between the frontend and the backend using the HTTP protocol consists of the following restful APIs.

User

API GET POST PUT DELETE
user/auth/ X login X X
user/signup/ X Create new user X X
user/:id/ Get specified user X Edit specified user information X
user/:id/profile_photo/ X X Change user's profile photo X
user/serach/:query/ Search user by email X X X
user/check/email/:email/ Check duplicate email X X X
user/check/nickname/:nickname/ Check duplicate nickname X X X
user/search_by_nickname/:query/ Search user nickname X X X

Travel

API GET POST PUT DELETE
travel/ X Create new travel X X
travel/:id/ Get specified travel by request user X X Delete specified travel
travel/:id/fork/ X Fork specified travel and create new travel X X
travel/:id/travelCommit/ X Create new travelCommit under specified travel X X
travel/:id/comment/ Get comment list of specified travel Create new comment on specified travel X X
travel/:tid/comment/:cid/ X X Update specified comment Delete specified comment
travel/travelCommit/:id/photo/ X X Change the photo of specified travel commit X
travel/travelCommit/:id/merge/ X Merge specified travel commit into travel X X
travel/recent/ Get most recent travel list X X X
travel/popular/ Get most popular travel list X X X
travel/search/:query/ Get travel list that contain specified tag X X X
travel/user/:id/ Get travel list written by specified user X X X
travel/collaborator/:id/ Get travel list that specified user collaborating X X X
travel/tag/:tag/ Get tag list that contains specified tag Create new tag X X
travel/recommend/:id/ Get similar recommendation travels by specified travel X X X
travel/recommend/:uid/:tid/ Get similar recommendation travels by user and travel X X X
travel/settings/:id/ X X Change settings of specified travel such as collaborators X
travel/view/:id/ X Update specified travel's viewer list X X
travel/like/:id/ X Update specified travel's like list X X

Maps

API GET POST PUT DELETE
maps/autocomplete/:query/ Get autocomplete query and save it as cache X X X
maps/search/:query/ Get search result of Google maps API and save result in cache X X X

Deployment

API

The service will deploy through two servers: backend, frontend. Each server should set https ssl to garantee secure communication between server and client. Our backend consist of django library and the database would be mounted on MySQL engine. The backend server always handle database with the engine and communicate with django models. The server also response several requests asynchronously, nginx will be applied to server to handle the requests. If the requests would be expected hard with auto-complete search tab function, we can apply gunicon to the backend server to handle this.

ML Feature

The application could serve recommendation system within the travel detail page. The pretrained sentence2vec model should always mounted backend server, this might be disadvantages to the server. The server should be managed carefully with memory management tools like supervisord, etc.

External Service

When a user create travel data, the place data should be served to the user, and this should be implemented by google maps API.

Implementation Plan

The purpose of our service is to share my travel plan and manage some detail travel plan with web application. For this purpose the Create Travel page and Travel Detail page are the key feature of the service. Behind frontend components and relations Create Travel page and Travel Detail page contains lots of components and backend details. We separate these page into small component to implement step by step. Each page and backend model has its own test module, so try to remove dependency while implement service.

Some frontend components are quite similar, for example My Travel page and User Travel page have same format. We make the common part of these container to one component and try to implement this component early. The first schedule of frontend is to implement Create Travel and Travel Detail page. The second schedule of frontend is to implement Search page, this feature will be challenging because the length of travel plans will be chagned dynamically.

It is easy to implement frontend components after implement related backend models. All backend models should be implemented earlier than other services, and the model should remain unchanged until the project is over. When the model is fixed, the API will be implemented with reducers in frontend components. After that, the testings for both frontend and backend will be followed to ensure the frontend and backend work properly

Every members will challenge to implement both backend and frontend. All issues and communication should share with issue page and PR page. Below table is feature and assignee of the service.

Frontend

Page Feature Time Sprint Assignee Challenge
Login Handle user session 1d 2 Suh
Sign Up check user input valid 1d 3 Han
My Travel list all my travels 2d 3 Hwang
User Travel list all use travels 0.5d 3 Jang
Create Travel add travel component 7d 3,4 Hwang Drag & Drop component, Hard test cases
Edit Travel edit travel plan 1d 3,4 Jang
Travel Detail Overview travel, comment 3d 3,4 Suh handle likes, comments
Search map user and travel within query 3d 4,5 Han Test execution time
Header common page 1d 3 Hwang
User Profile change user info 1d 4 Jang
Travel Setting change travel setting 1d 4 Jang
Error Page 400, 500 errors 1d 5 Suh

Backend Model

Model Feature Time Sprint Assignee Challenge
User handle login 2d 3 Jang
Travel travel information 3d 3 Han
Comment comment on travel 2d 3 Suh
place POI data 2d 3 Hwang

Backend Service

Service Feature Time Sprint Assignee Challenge
Search select travel matching query 4d 4,5 Han The most time consuming feature
ML feature sentence2vector 6d 4,5 Jang Would inference model be fast? Add ml model metric
Google Maps API connect the service and google API 3d 3,4 Hwang

Frontend Testing

Page Feature Time Sprint Assignee Challenge
Login Test Handle user session 1d 3 Suh
Sign Up Test check user input valid 1d 3 Han
My Travel Test list all my travels 1d 3 Hwang
User Travel Test list all use travels 0.5d 3 Jang
Create Travel Test add travel component 2d 4 Hwang Drag & Drop component, Hard test cases
Edit Travel Test edit travel plan 1d 4 Jang
Travel Detail Test Overview travel, comment 1d 4 Suh handle likes, comments
Search Test map user and travel within query 1d 5 Han Test execution time
Header Test common page 1d 3 Hwang
User Profile Test change user info 1d 4 Jang
Travel Setting Test change travel settint 1d 4 Jang
Error Page Test 400, 500 errors 1d 5 Suh

Backend Testing

Model Feature Time Sprint Assignee Challenge
User Test handle login 1d 3 Jang
Travel Test travel information 1d 3 Han
Comment Test comment on travel 1d 3 Suh
place Test POI data 1d 3 Hwang

Testing plan

Unit testing

We need to test for both frontend and backend. All components and modules need to be tested. For the frontend, we use React and Redux, so we will use Jest and Enzyme for framework. We will use Mock and Spy for components with externel depedency. For the backend, we use Django, so we will use Django’s TestCase class which is based on Python unittest.

Functional testing

We will test all RESTful APIs. Test will check wheter APIs give appropriate response, or do appropriate action. Also we will test the functions are well working by checking the results or responses for the components For the frontend, we will use Jest and Enzyme for testing APIs used by React and Redux. For the backend, we will use Django’s TestCase class which is based on Python unittest.

Acceptance & Integration Testing

For the accpetance test, we have to check whether desired changes are maded when some event occurs. We will use Jest and Enzyme for the testing. For the integration test, we will use Travis CI.

Testing goal

Our goal is to achieve above 90% of test coverage, with appropriate tests.