Skip to content

Final Report

Emirhan Yasin Cetin edited this page Jan 3, 2020 · 4 revisions

Assesment

We, as the Kereviz team, feel like we succeeded in creating a cross-paltform, decentralized language learning platform. We were constantly in touch with our customer, being aware of their requirements, we accomplished in satisfying most of them.

We met weekly and talked with our customer, decided what to work on, divided the work and planned our process. We tried to adopt an agile philosophy since many of us were incredibly inexperienced and planning without estimations and predictions were a nightmare, so we took it a step at a time. Every team decided on the roadmap of its own, we were lucky for our back-end team was running a couple steps in front of us so our android and web team could work without limitations. Our android and web team took the approach of "who implemented the feature the first time, decides the design. The other will comply.". It worked well since we do not have a designated designer.

We were pained to realize that some of our teammates were not putting in the same effort, which resulted in the trade-off of implementing less features, implementing them in a lower quality or putting many extra hours to comply with our contract with our customer. We felt bad every time we were faced with this decision, and every choice was the way to go more than once.

All in all, it was an invaluable learning experience in multiple domains. Each of us worked in a cross-platform application with many moving parts in it. We learned to work in a team, and working with people is hard. We learned how to interact with a customer and how to understand what to make of what they want from what they say, which can be surprisingly different. We implemented a W3C standard, which was in itself a serious achievement. We deployed and managed a server by ourselves, we implemented a continuous integration solution for testing and fast deployments. We had good moments, we had bad moments, and we learned how to handle them all. Sometimes we rallied, sometimes we compromised to find a good balance with our customer. We motivated each other, not a single serious conflict was present since we were all extremely constructive with our criticisms and suggestions. Thank you for this growth opportunity.

Android Assessment

When we started this project, we as the Android team didn't know much about Android programming. We started out with tutorials and tried to develop an app from scratch.

At the end of the project, we have most of our app working in the way that we wanted. We believe that we have improved greatly.

For example, when we first started programming we had system.out.printlns as our debugging method. Then we improved to using Android logs. Then we discovered Android Studio's debugging tool.

We believe we improved on using the GitHub tools as well. We now write longer issue descriptions, pull request and commit messages. We also started using projects to keep track of the issues.

One of the points that we could improve as the Android team is the state of directories of our codebase. We don't have any directory management system under Android code, we simply put every java file to the same location. We are aware of this problem but as we had limited time to implement new features, we couldn't find time to organize our directory.

Another point that we can improve is the testing of the Android app. As our app is highly dependent on the backed for logical functionalities, we don't have any unit tests. We would like to write more tests but we didn't know how to or what to write tests to.

Front End Team Assessment

We, being the awesome front-end team, aspired to write the best web application we can with the resources we currently have. Working side by side with each other, we succeeded to reduce the differences of our experience levels greatly. With the back-end team implementing the functionalities of our application, we attacked the issue of interacting with our users.

Our github usage was satisfactory, we used branches for feature development and issues for figuring out who is working on what at any moment. We used pull requests for code reviews.

Our work hours were bursty, as in implementing many features at one sitting, our schedules are nearly full and working in the same place at the same time appealed to us. We rushed to develop our application generally near deadlines, and sometimes our product quality suffered for it.

Implementing the Annotation model was hard, and doing it in the front end was a necessary evil if we wanted to have that feature in our product, and Halit was the one who stepped up to that challenge, just sending and receiving strings from the backend. It was hard work, and he pulled it off. A better choice would be the logic being on the back-end part, but that team had their hands full and android team had decided to not implement it so this decision was our only choice.

For the less experienced developers on our team, the hard part was learning, taming and integrating some less-than-optimal, not-so-cleanly implemented libraries into our code base. Sometimes it took delving into the source code, sometimes it required some cheating and abusing its exposed API. Without the help we gave to each other, it wouldn't be possible. Strong teamwork paid off.

List of Deliverables

Team Deliverables
Android - Register Page
- Login Page
- Language selection page
- Proficiency exam page
- Exam result page
- Profile page
- Viewing someone else's profile
- Sending message request to other users
- Chats list page
- Messaging page
- User search
- Content search (semantic search)
- Exercise types list page
- Solving exercise page in writing
-Solved writing exercises page
- Comment and rating page
- Add exercise page
- Exercises with image
- Recommended reviewers page
Frontend - Register Page
- Login Page
- Language selection page
- Proficiency exam page
- Exam result page
- Profil page
- Viewing someone else's profile
- Sending message request to other users
- Chats list page
- Messaging page
- User search
- Content search (semantic search)
- Exercise types list page
- Solving exercise page in writing
-Solved writing exercises page
- Comment and rating page
- Add exercise page
- Exercises with image
- Recommended reviewers page
- W3C Annotation model implementation for annotation of image and text based essays.
- Unit tests!
Backend - Register Endpoint
- Login Endpoint
- Language endpoint
- Proficiency exam endpoint
- Grade endpoints
- Profil Info endpoint
- Chat Invitation endpoints
- Chats list endpoint
- Messaging endpoints
- User search endpoint
- Content search (semantic search) endpoint
- Solving exercise endpoint
- Tagging endpoint
- Conversation endpoint
- Annotation endpoints
- Assignment endpoints
- Comment endpoints
- Content endpoints
- Essay endpoints
- Image and Sound File adding endpoints
- Rating endpoints
- Recommendation endpoints
- Essay review Request endpoints

Status and Evaluation of Deliverables

Android

We have implemented register, login, language selection, proficiency exam, exam result pages, profile page, viewing someone else's profile, sending message request to other users, chat list page, chat page, user and content search pages, list of exercise types page, exercise solving page in the previous milestone and made an evaluation for these pages.

Exercise solving page in writing

Users can write an essay in text format or upload a photo for the corresponding question. Both text and photos can be uploaded to support the requirement item 1.2.5.1. This page is also a part of the implementation of the requirement 1.2.2.4. except for tags part.

Solved writing exercises page

Users can see their own solved writing exercises under the Previously Solved Exercises heading in this page as stated in the requirement item 1.1.1.1.2.6. Also they can reach recommended users page and see ongoing reviews on this page.

Comment and rating page

Users can search other users by clicking the search icon on the navigation bar. Users can click on the result and go to that user's profile page. In this page, the user can see another user's profile with his/her language, level and rate. User can also see two buttons on this page. One of them is to send message to that user. The second one is to rate him and write a comment, also user can see rates and comments previously made. In the comment and rating page, the stars looks great. This page is also a part of the implementation of the requirement 1.2.6.1. However, all users of this app can rate and comment each other. It would be better if this was possible only when the users have interaction with each other.

Add exercise page

Users can add exercises by clicking on the plus icon in the exercise type list page. Users need to write a question body and options and select the question level. They can add a photo. This implementation is the part of requirement item 1.1.1.1.2.7.

Exercises with image

Previously in this app, photos were not displayed in the exercises. Displaying images in exercises improved our app.

Recommended reviewers page

Users can list the recommended reviewers by clicking on the recommended reviewers button on the previously solved writing exercises page. Users can see the first five reviewers here. These reviewers are displayed according to the response of API. This response logic returns the users who have the highest ratings and whose level is higher than the review requester.

Frontend

Register Page

The register page in the frontend works as expected. Items 1.1.3.1.1. (Users shall give their email address while registering.), 1.1.3.1.2. (Users shall give their names while registering.), 1.1.3.1.3. (Users shall set up a password while registering to the system) of project requirements list have been implemented in this page. It is connected to the backend and the input is checked.

Login Page

The login page in the frontend works as expected. The item 1.1.3.2.1.(Users shall be able to login to the system using their email address and their passwords.) of project requirements list has been implemented in this page. Some UI polish is needed in the frontend generally as the current version seems a little simple.

Language Selection Page

This page is also working perfectly. With this page one of the use cases has been realized and item 1.2.3.1. (The system shall support multiple languages.) of requirements has been partly realized. Currently, we are giving three options to users but only English is working so we need to work on that as well.

Proficiency Exam Page

Questions are retrieved from the backend and displayed with no problem. The user cannot see correct answers until submission.

Exam Result Page

Exam results are calculated and updated in the backend. We need to show the result in a more detailed way. Currently, only the A1, A2, etc. level is shown but some level information like intermediate, advanced etc needs to shown as well. The result is shown in a pop-up so.

Exercise Page

Questions are retrieved from the backend and displayed with no problem. The correct answers are shown after each question by making the correct answer red in the frontend. Thus, the item 1.1.1.1.2.3. (After every question, the users shall be able to see the correct answer) of project requirements list has been fulfilled. It supports both audio/image/text exercises.

Profile Page (self or other's)

User can view other user's profile page when they click the user's name on the user search result. User can view self profile page when they click profile button from topbar. In profile page; languages, progress on these languages, their levels in languages are shown as stated in the requirement item 1.1.1.1.2.6. and 1.1.1.1.2.10. Users also can request to chat with a user on another user's profile page. Users can rate each other, comment each other, view previous comments on each other's profile page.

Sending Message Request to Other Users

We have implemented the feature where user's can send a message request to each other as stated in the requirement 1.1.2.1.1. Users can see in other user's profile page if their request is approved or not, and send a request if they haven't already. The only unimplemented part of this requirement is to see the list of the message request that has sent to the user and approving/rejecting them as told in requirement 1.1.2.1.2. We will implement that part in the profile page of the user.

User Search Page

Users can reach the user search page by going to users page through topbar and find out results by filling search form values. By writing another user's name on the search part, users would be able to list all the users with that name. Users can click on the result and go to that user's profile page. This implementation is the part of requirement item 1.2.8.3.

Content Search Page(Semantic Search)

Users can reach the content search page by going to exercise search page through sidebar. In the content search page, by filling search form values the user can do a semantic search with the tags of the exercises. For example, users can search for a tag that they wanted. In the result, user would see the exercises that have that tag or a tag that is related to the tag that the user was searching for. Currently, users can only do a semantic search with the tag of the given exercise. This feature is written to implement the requirements 1.2.8.2. and 1.2.8.1.

Solving exercise page

Questions are retrieved from the backend and displayed with no problem. Unlike the proficiency exam page, the correct answers are shown after each question by making the correct answer green, selected answer highlighted and wrong answers red. Thus, the item 1.1.1.1.2.3. (After every question, the users shall be able to see the correct answer) of project requirements list has been fulfilled. Users can solve exercises with audio/image in listening/reading/grammar/vocabulary exercises.

Writing Exercise Page

The user can write essay about one of the available topics and submit it in either text or image format.

Recommend Review Page

The user can receive recommendations for essay reviews.

Annotation Page

The user or the reviewer can add annotations to an essay, complying to the w3c annotation standards. To add annotation, the user/reviewer can click on where to add (if the source is image) or select some text (if the source is text) to add an annotation. Then, the user who created an annotation can edit the annotation from the same page. It is not possible to move the annotation made to text to another place (one can delete it and re-add it to change the text it was pointing to) but can update all other fields. If the source is image, the user/reviewer gets a rectangle selector, which he/she can move/resize etc. to change the place an annotation is pointing to.

Chat Page

Users can view pending chat requests and chat with those who've accepted the requests on the chat page.

Coding Work of Individuals

Member Work
Irem Worked on Android application.
- Added comment and rating pages to user's profile pages.
- Added the page that user can see the previously solved writing exercises.
- Do research about annotations in Android.
- Added the page for a solved writing exercise.
- Added images to exercises in Android.
- Fixed bug on bottom navigation bar on user recommendation page.
Gamze Worked on Android application.
- Added recommended reviewers page display and adapter java files, added recommended_users and recommendation page xml files.
- Exercises are getting by userId so when user solved an exercise, s/he cannot see or solve it one more time.
- Improved recommended_user.xml design, added grade level with explanations, changed the recommended user icon.
- Changed top bar and app colors in some pages.
- Made send review button rounded.
- Research about annotation.
Gokhan Worked on Backend.
- Implemented SearchUserTest which tests corresponding endpoint.
- more coming soon.
Egemen Worked on web application.
- Created and beautified profile component. Used in profile page and user search.
- Created user search
- Created a multi-state invite button, proud of it.
- Created the Chat page
- Provided the user with chat invites and conversations in the same place
- Created commenting and rating mechanisms for profile page
- Created essay selection, getting recommendation and requesting review components.
Ahmet Worked on Backend.
- Created and integrated AWS S3 for storage, both images and audio.
- Created file upload service.
- Created recommendation mechanism.
- Created assignment services and endpoints.
- Created comment and rating system.
- Created review request mechanism.
- Created essay services and endpoints.
Emirhan - Learned the new structure Halit created, fixed bugs
- Added exercises to frontend.
- Created writing exercise page and an endpoint for the exercise inputs
- Created an exercise suggestion page compatible with our multiple choice exercise types
- Learned about annotation, W3C.
- Fixed exercise component in frontend.
Arda Worked on Backend.
- Implemented Comment System endpoints and services.
- Implemented Annotation System endpoints and services.
- Implemented two new endpoints and related services for Rating system, which is used to get or update a rating between two given users.
- Implemented getSourceByEssayId endpoint, which returns the essay text of an essay with a given Id.
İbrahim Worked on Android application.
- Created exercise addition page.
- Added writing exercise solving page with text&image upload options.
- Added text&image upload options to exercise addition page.
- Connected exercise addition page to API.
- Connected writing solving page to API.
Halit Worked on web application.
- Created frontend layout and structure.
- Created exercises, exercise search and prof. exam pages.
- Created login/register pages.
- Created an annotation system supporting both text/image sources, (created parsers for w3c data model, and a annotation UI, I literally ended up creating AnnotationDataFactory.js in frontend), proud of it.
- Connected React-Cosmos (for checking out/testing components) and React-Testing-Library for unit testing.
- Built CI/CD system with Travis & AWS.
- Helped Backend team with deployment & server configurations.
- Made lots of bug fixes in all parts frontend.

Annotation Implementation & W3C Standard Compliance

The annotation service is a critical feature in our project. After reading out and digging into the details of the W3C Annotation Model Standard, we have narrowed it down to the below scheme to use in our case with respect to our needs.

The original docs for the annotation model can be accessed from this link:

https://www.w3.org/TR/annotation-model/

Our Scheme Includes:

Term Type Description
@context Property The context that determines the meaning of the JSON as an Annotation.
The Annotation MUST have 1 or more @context values and http://www.w3.org/ns/anno.jsonld MUST be one of them. If there is only one value, then it MUST be provided as a string.
id Property The identity of the Annotation.
An Annotation MUST have exactly 1 IRI that identifies it.
type Relationship The type of the Annotation.
An Annotation MUST have 1 or more types, and the Annotation class MUST be one of them.
Annotation Class The class for Web Annotations.
The Annotation class MUST be associated with an Annotation using type.
body Relationship The relationship between an Annotation and its Body.
There SHOULD be 1 or more body relationships associated with an Annotation but there MAY be 0.
target Relationship The relationship between an Annotation and its Target.
There MUST be 1 or more target relationships associated with an Annotation.
creator Relationship The agent responsible for creating the resource. This may be either a human, an organization or a software agent.
There SHOULD be exactly 1 creator relationship for Annotation and Body, but MAY be 0 or more than 1, as the resource's creator may wish to remain anonymous, or multiple agents may have worked together on it. The relationships MAY be associated with other resources.
created Property The time at which the resource was created.
There SHOULD be exactly 1 created property for Annotation and Body, and MUST NOT be more than 1. The property MAY be associated with other resources. The datetime MUST be a xsd:dateTime with the UTC timezone expressed as "Z".
modified Property The time at which the resource was modified, after creation.
There MAY be exactly 1 modified property for Annotation and Body, and MUST NOT be more than 1. The property MAY be associated with other resources. The datetime MUST be a xsd:dateTime with the UTC timezone expressed as "Z".
motivation Relationship The relationship between an Annotation and a Motivation.
There SHOULD be exactly 1 motivation for each Annotation, and MAY be 0 or more than 1.

Motivation field is one of these:

Term Type Description
Motivation Class The Motivation for an Annotation is a reason for its creation, and might include things like Replying to another annotation, Commenting on a resource, or Linking to a related resource.
assessing Instance The motivation for when the user intends to assess the target resource in some way, rather than simply make a comment about it. For example to write a review or assessment of a book, assess the quality of a dataset, or provide an assessment of a student's work.
bookmarking Instance The motivation for when the user intends to create a bookmark to the Target or part thereof. For example an Annotation that bookmarks the point in a text where the reader finished reading.
classifying Instance The motivation for when the user intends to classify the Target as something. For example to classify an image as a portrait.
commenting Instance The motivation for when the user intends to comment about the Target. For example to provide a commentary about a particular PDF document.
describing Instance The motivation for when the user intends to describe the Target, as opposed to (for example) a comment about it. For example describing the above PDF's contents, rather than commenting on their accuracy.
editing Instance The motivation for when the user intends to request a change or edit to the Target resource. For example an Annotation that requests a typo to be corrected.
highlighting Instance The motivation for when the user intends to highlight the Target resource or segment of it. For example to draw attention to the selected text that the annotator disagrees with.
identifying Instance The motivation for when the user intends to assign an identity to the Target. For example to associate the IRI that identifies a city with a mention of the city in a web page.
linking Instance The motivation for when the user intends to link to a resource related to the Target.
moderating Instance The motivation for when the user intends to assign some value or quality to the Target. For example annotating an Annotation to moderate it up in a trust network or threaded discussion.
questioning Instance The motivation for when the user intends to ask a question about the Target. For example to ask for assistance with a particular section of text, or question its veracity.
replying Instance The motivation for when the user intends to reply to a previous statement, either an Annotation or another resource. For example providing the assistance requested in the above.
tagging Instance The motivation for when the user intends to associate a tag with the Target.

The creator field is as follows:

Term Type Description
id Property The IRI that identifies the agent.
An Agent SHOULD have exactly 1 IRI that identifies it, and MUST NOT have more than 1.
type Relationship The type of the Agent.
An Agent SHOULD have 1 or more classes, from those listed below.
Person Class The class for a human agent.
name Property The name of the agent.
Each agent SHOULD have exactly 1 name property, and MAY have 0 or more.
email Relationship The email address associated with the agent, using the mailto: IRI scheme [rfc6086].
Each agent MAY have 1 or more email addresses.

Our body field is always TextualBody

Term Type Description
id Property The IRI that identifies the Textual Body.
The Body MAY have exactly 1 IRI that identifies it.
type Relationship The type of the Textual Body resource.
The Body SHOULD have the TextualBody class, and MAY have other classes.
TextualBody Class A class assigned to the Body for embedding textual resources within the Annotation.
The Body SHOULD have the TextualBody class.
value Property The character sequence of the content of the Textual Body. There MUST be exactly 1 value property associated with the TextualBody.

Our target field is as follows

Term Type Description
id Property The IRI that identifies the Body or Target resource.
Bodies or Targets which are External Web Resources MUST have exactly 1 id with the value of the resource's IRI.
format Property The format of the Web Resource's content.
The Body or Target SHOULD have exactly 1 format associated with it, but MAY have 0 or more. The value of the property SHOULD be the media-type of the format, following the [rfc6838] specification.
type Relationship The type of the Body or Target resource.
The Body or Target MAY have 1 or more types, and if so, the value SHOULD be drawn from the list of classes below, but MAY come from other vocabularies.
selector Relationship The relationship between a Specific Resource and a Selector.
There MAY be 0 or more selector relationships associated with a Specific Resource. Multiple Selectors SHOULD select the same content, however some Selectors will not have the same precision as others. Consuming user agents MUST pick one of the described segments, if they are different.

The target type can be one of below:

Term Type Description
Image Class The class for image resources, primarily intended to be seen.
Text Class The class for a resource primarily intended to be read.

The selector field of the target is as follows:

Term Type Description
type Relationship The class of the Selector.FragmentSelectors MUST have exactly 1 type and the value MUST be FragmentSelector.
FragmentSelector Class A resource which describes the Segment through the use of the fragment component of an IRI.
value Property The contents of the fragment component of an IRI that describes the Segment. The FragmentSelector MUST have exactly 1 value property.
conformsTo Relationship The relationship between the FragmentSelector and the specification that defines the syntax of the IRI fragment in the value property.
The Fragment Selector SHOULD have exactly 1 conformsTo link to the specification that defines the syntax of the fragment and MUST NOT have more than 1.

The conformsTo and value fields are as follows:

Name Fragment Specification Description
Plain Text http://tools.ietf.org/rfc/rfc5147 [rfc5147] Example: char=0,10
Media http://www.w3.org/TR/media-frags/ [media-frags] Example: xywh=50,50,640,480

So the annotation format is as below:

Image source:

  {
    "@context": "http://www.w3.org/ns/anno.jsonld",
    "id": "https://api.bounswe2019group9.tk/annotations?id=1",
    "type": "Annotation",
    "creator": {
      "id": "https://bounswe2019group9.tk/users/1",
      "name": "John Russel",
      "email": "[email protected]"
    },
    "created": "2015-01-28T12:00:00Z",
    "modified": "2015-01-29T09:00:00Z",
    "body": {
      "type" : "TextualBody",
      "value" : "Great Essay",
      "format" : "text/plain"
    },
    "motivation": "assessing",
    "target": {
      "id": "https://api.bounswe2019group9.tk/images/image1.jpg",
      "type": "Image",
      "format": "image/jpeg",
      "selector": {
        "type": "FragmentSelector",
        "conformsTo": "http://www.w3.org/TR/media-frags/",
        "value": "xywh=100,100,300,300"
      }
    }
  }

Text Source:

  {
    "@context": "http://www.w3.org/ns/anno.jsonld",
    "id": "http://api.bounswe2019group9.tk/annotation/find?id=2",
    "type": "Annotation",
    "creator": {
      "id": "https://bounswe2019group9.tk/users/1",
      "name": "John Russel",
      "email": "[email protected]"
    },
    "created": "2015-01-28T12:00:00Z",
    "modified": "2015-01-29T09:00:00Z",
    "body": {
      "type" : "TextualBody",
      "value" : "Bad Mistake",
      "format" : "text/plain"
    },
    "motivation": "commenting",
    "target": {
      "id": "https://api.bounswe2019group9.tk/essays/getSourceByEssayId?id=2",
      "type": "Text",
      "format" : "text/plain",
      "selector": {
        "type": "FragmentSelector",
        "conformsTo": "http://tools.ietf.org/rfc/rfc5147",
        "value": "char=0,10"
      }
    }
  }

Our Annotation API endpoints can be found in the API Doc Part of this document.

Language Learning Platform REST API Documentation

Test Endpoint

Greeting

This is created for testing purpose, say hi

GET /greeting?name=group9
{
  "id": 3,
  "content": "Hello, group9!"
}

User Endpoints

Get User By Id

Request Content: id

Response Content: The user with corresponding id if it exists, null otherwise.

Example Request
GET /users/get?id=2
Example Response
{
  "id": 2,
  "email": "[email protected]",
  "password": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
  "firstName": "ahmet",
  "lastName": "test"
}

Register User

Request Content: e-mail, password, firstName, lastName

Response Content: The created user with 200 status code if successful. The reason with 400(Bad Request) if unsuccessful.

Example Request-1
POST /users/register
{
  "email": "[email protected]",
  "password": "123456",
  "firstName": "testname",
  "lastName": "testsurname"
}
Example Response-1
{
  "status": 200,
  "explanation": null,
  "data": {
    "email": "[email protected]",
    "password": "123456",
    "firstName": "testname",
    "lastName": "testsurname"
  }
}
Example Request-2
POST /users/register
{
  "email": "testtest.com",
  "password": "123456",
  "firstName": "testname",
  "lastName": "testsurname"
}
Example Response-2
{
  "status": 400,
  "explanation": "Invalid email",
  "data": null
}
Example Request-3
POST /users/register
{
  "email": "[email protected]",
  "password": "123456",
  "firstName": "testname",
  "lastName": "testsurname"
}
Example Response-3
{
  "status": 400,
  "explanation": "This e-mail has already been registered",
  "data": null
}

Login User

Request Content: e-mail, password

Response Content: The user with 200 status code if successful. The reason with 400(Bad Request) if unsuccessful.

Example Request-1
POST /users/login
{
  "email": "[email protected]",
  "password": "123456"
}
Example Response-1
{
  "status": 200,
  "explanation": null,
  "data": {
      "id": 5,
      "email": "[email protected]",
      "password": "123456",
      "firstName": "testname",
      "lastName": "testsurname"
  }
}
Example Request-2
POST /users/login
{
  "email": "[email protected]",
  "password": "wrongpassword"
}
Example Response-2
{
  "status": 400,
  "explanation": "Wrong credentials",
  "data": null
}

Get Profile Info by User Id

Request Content: id

Response Content: The profile info with 200 status code if successful. The reason with 400(Bad Request) if unsuccessful.

Example Request-1
GET /users/profile?id=6
Example Response-1
{
  "status": 200,
  "explanation": null,
  "data": {
    "userId": 6,
    "firstName": "testname",
    "lastName": "testsurname",
    "email": "[email protected]",
    "languages": [
      "English"
    ],
    "grades": [
      5
    ],
    "progressLevels": [
      0
    ]
  }
}
Example Request-2
GET /users/profile?id=66
Example Response-2
{
  "status": 404,
  "explanation": "User not found with id: 66",
  "data": null
}

Solved Exercise

Request Content: exercise id, user id

Response Content: The user with 200 status code if successful. The reason with 400(Bad Request) if unsuccessful.

Example Request-1
POST /users/solved
{
  "userId": 6,
  "exerciseId": "6"
}
Example Response-1
{
  "status": 200,
  "explanation": "Successful",
  "data": null
}

Content Endpoints

Get Exercise By Id

Request Content: exercise id

Response Content: Exercise with tags if successful, 404 not found if not.

Example Request
GET /contents?id=3
Example Response
{
  "status": 404,
  "explanation": "No exercise with this id.",
  "data": null
}
Example Request
GET /contents?id=13
Example Response
{
  "status": 200,
  "explanation": null,
  "data": {
    "id": 13,
    "languageId": 1,
    "grade": 2,
    "typeId": 2,
    "imageUrl": "",
    "soundUrl": "",
    "questionBody": "_______ he should have spent all the weekend preparing for his test, he in fact just lay in bed watching videos.",
    "optionA": "however",
    "optionB": "whereas",
    "optionC": "despite",
    "optionD": "nevertheless",
    "correctAnswer": 2,
    "tags": [
      {
        "id": 4,
        "exerciseId": 13,
        "tagText": "lazy"
      },
      {
        "id": 3,
        "exerciseId": 13,
        "tagText": "video"
      },
      {
        "id": 6,
        "exerciseId": 13,
        "tagText": "tv"
      },
      {
        "id": 7,
        "exerciseId": 13,
        "tagText": "television"
      }
    ]
  }
}

Get All Available Languages List

Request Content: none

Response Content: The list of available languages

Example Request
GET /contents/languages
Example Response
{
  "status": 200,
  "explanation": null,
  "data": [
    "English",
    "Turkish",
    "Italian"
  ]
}

Get All Exercises List

Request Content: none

Response Content: The list of all exercises of all languages

Example Request
GET /contents/all
Example Response
{
    "status": 200,
    "explanation": null,
    "data": [
        {
            "languageId": 1,
            "typeId": 1,
            "imageUrl": null,
            "soundUrl": null,
            "question": "what is your name?",
            "optionA": "my name is..",
            "optionB": "your name is..",
            "optionC": "his name is...",
            "optionD": "her name is...",
            "correctAnswer": 1
        },
        {
          ...
        },
        
        ...
    ]
}

Get Proficiency Exam

Request Content: Language name as request parameter. Language names should be in English and capitalized.

Response Content: 10 questions from given language

Example Request
GET /contents/prof?language=English
Example Response
{
    "status": 200,
    "explanation": null,
    "data": [
        {
            "languageId": 1,
            "typeId": 1,
            "imageUrl": null,
            "soundUrl": null,
            "question": "what is your name?",
            "optionA": "my name is..",
            "optionB": "your name is..",
            "optionC": "his name is...",
            "optionD": "her name is...",
            "correctAnswer": 1
        },
        {
          ...
        },
        
        ...
    ]
}
Example Request
GET /contents/prof?language=english
Example Response
{
    "status": 400,
    "explanation": "Language not found.",
    "data": null
}

Create exercise

Request Content:

languageId(1 for English, 2 for Turkish, 3 for Italian)

typeId(1 for Grammar, 2 for vocabulary, 3 for reading, 4 for listening)

imageUrl(not necessary for proficiency, just delete)

soundUrl(not necessary for proficiency, just delete)

questionBody(As it sounds)

optionA, optionB, optionC, optionD(as it sounds)

correctAnswer(1 for A, 2 for B etc)

Only image url and sound url can be null

Response Content: Exercise itself

Example Request
POST /contents/add
{
  "correctAnswer": 4,
  "languageId": 1,
  "optionA": "Bean",
  "optionB": "Potato",
  "optionC": "Bread",
  "optionD": "Apple",
  "questionBody": "Which one of these is a fruit?",
  "typeId": 2
}
Example Response
{
    "status": 200,
    "explanation": null,
    "data": {
        "correctAnswer": 4,
        "imageUrl": null,
        "languageId": 1,
        "optionA": "Bean",
        "optionB": "Potato",
        "optionC": "Bread",
        "optionD": "Apple",
        "questionBody": "Which one of these is a fruit?",
        "soundUrl": null,
        "typeId": 2
      }
}

Delete exercise

Request Content:

Exercise id

Response Content: none

Example Request
GET /contents/delete?id=3
Example Response
{
    "status": 200,
    "explanation": null,
    "data": null
}

Grade Endpoints

Get Grade by UserId and LanguageId

Request Content: User id and language id

Response Content: Grade

Example Request
GET /grades/get?userId=3&languageId=1
Example Response
{
  "status": 200,
  "explanation": null,
  "data": {
    "id": 10,
    "userId": 12,
    "languageId": 1,
    "grade": 1
  }
}

Add Grade

Request Content: UserId, languageId, grade

Response Content: Grade itself

Example Request
POST /grades/add
{
  "grade": 4,
  "languageId": 1,
  "userId": 4
}
Example Response
{
  "status": 200,
  "explanation": null,
  "data": {
    "userId": 4,
    "languageId": 1,
    "grade": 4
  }
}

Search Endpoints

Search User

Request Content: First name, last name, grade and language

Response Content: List of users

Example Request
POST /search/users
{
  "firstName": "t",
  "grade": 3,
  "languageId": 1,
  "lastName": "te"
}
Example Response
{
  "status": 200,
  "explanation": null,
  "data": [
    {
      "userId": 3,
      "firstName": "ahmet",
      "lastName": "test",
      "email": "[email protected]",
      "languages": [
        "English"
      ],
      "grades": [
        3
      ],
      "progressLevels": [
        0
      ]
    },
    {
      "userId": 6,
      "firstName": "testname",
      "lastName": "testsurname",
      "email": "[email protected]",
      "languages": [
        "English"
      ],
      "grades": [
        5
      ],
      "progressLevels": [
        0
      ]
    }
  ]
}

Search Exercises

Request Content: UserId, languageId, grade, typeId, tag

Response Content: List of exercises which fits in given parameters; grade, type and language. Also if tag is given, returns only the exercises with tags semantically similar to the given one. Also if user id is given, returns the exercises which that user haven't solved yet.

Example Request
POST /search/exercises
{
  "grade": 2,
  "languageId": 1,
  "tag": "television",
  "typeId": 2,
  "userId": 7
}
Example Response
{
  "status": 200,
  "explanation": null,
  "data": [
    {
      "id": 13,
      "languageId": 1,
      "grade": 2,
      "typeId": 2,
      "imageUrl": "",
      "soundUrl": "",
      "questionBody": "_______ he should have spent all the weekend preparing for his test, he in fact just lay in bed watching videos.",
      "optionA": "however",
      "optionB": "whereas",
      "optionC": "despite",
      "optionD": "nevertheless",
      "correctAnswer": 2,
      "tags": [
        {
          "id": 4,
          "exerciseId": 13,
          "tagText": "lazy"
        },
        {
          "id": 3,
          "exerciseId": 13,
          "tagText": "video"
        },
        {
          "id": 6,
          "exerciseId": 13,
          "tagText": "tv"
        },
        {
          "id": 7,
          "exerciseId": 13,
          "tagText": "television"
        }
      ]
    }
  ]
}

Tag Endpoints

Add Tag

Request Content: Exercise id, tag text

Response Content: Tag itself

Example Request
POST /tags
{
  "exerciseId": 12,
  "tagText": "test"
}
Example Response
{
  "status": 200,
  "explanation": null,
  "data": {
    "id": 8,
    "exerciseId": 12,
    "tagText": "test"
  }
}

Invitation Endpoints

Add Invitation

Request Content: receiver id, source id

Response Content: Invitation itself

Example Request
POST /invitations
{
  "receiverId": 1,
  "sourceId": 5
}
Example Response
{
  "status": 200,
  "explanation": null,
  "data": {
    "id": 15,
    "sourceId": 5,
    "receiverId": 1,
    "createdAt": "2019-12-01T15:06:22.626+0000"
  }
}

Answer Invitation

Request Content: receiver id, source id, approved(boolean)

Response Content: Conversation itself

Example Request
POST /invitations/answer
{
  "approved": true,
  "receiverId": 1,
  "sourceId": 5
}
Example Response
{
  "status": 200,
  "explanation": null,
  "data": {
    "id": 11,
    "userIdOne": 5,
    "userIdTwo": 1,
    "lastUpdatedAt": "2019-12-01T15:08:05.896+0000"
  }
}
Example Response(if conversation already exists)
{
  "status": 400,
  "explanation": "Conversation already exists",
  "data": null
}

Get Inviter Profile Infos

Request Content: receiver user id

Response Content: List of profile infos

Example Request
GET /invitations/byReceiverId?userId=1
Example Response
{
  "status": 200,
  "explanation": null,
  "data": [
    {
      "userId": 6,
      "firstName": "testname",
      "lastName": "testsurname",
      "email": "[email protected]",
      "languages": [
        "English"
      ],
      "grades": [
        5
      ],
      "progressLevels": [
        0
      ]
    }
  ]
}

Get Invitation State

Request Content: userId1, userId2

Response Content: Invitation state

Example Request
GET /invitations/state?userId1=1&userId2=6
Example Response
{
  "status": 200,
  "explanation": null,
  "data": {
    "userId1": 1,
    "userId2": 6,
    "pendingRequestFromOneToTwo": false,
    "pendingRequestFromTwoToOne": true,
    "startedConversation": false
  }
}

Conversation Endpoints

Get Conversation Profile Info

Request Content: user id

Response Content: List of profile infos of given user id

Example Request
GET /conversations?id=1
Example Response
{
  "status": 200,
  "explanation": null,
  "data": [
    {
      "userId": 5,
      "firstName": "testname",
      "lastName": "testtest",
      "email": "[email protected]",
      "languages": [],
      "grades": [],
      "progressLevels": []
    },
    {
      "userId": 2,
      "firstName": "ahmet",
      "lastName": "test",
      "email": "[email protected]",
      "languages": [],
      "grades": [],
      "progressLevels": []
    },
    {
      "userId": 3,
      "firstName": "ahmet",
      "lastName": "test",
      "email": "[email protected]",
      "languages": [
        "English"
      ],
      "grades": [
        3
      ],
      "progressLevels": [
        0
      ]
    },
    {
      "userId": 4,
      "firstName": "ahmet",
      "lastName": "test",
      "email": "[email protected]",
      "languages": [
        "English"
      ],
      "grades": [
        1
      ],
      "progressLevels": [
        25
      ]
    }
  ]
}

Message Endpoints

Get Messages By User Id

Request Content: user id

Response Content: List of Messages of the User

Example Request
GET /messages?userId=9
Example Response
{
  "status": 200,
  "explanation": null,
  "data": [
    {
      "id": 10,
      "sourceId": 9,
      "receiverId": 2,
      "content": "selam",
      "createdAt": "2019-11-24T14:49:07.090+0000"
    },
    {
      "id": 11,
      "sourceId": 2,
      "receiverId": 9,
      "content": "selam",
      "createdAt": "2019-11-24T14:49:19.480+0000"
    },
    {
      "id": 12,
      "sourceId": 2,
      "receiverId": 9,
      "content": "nabber",
      "createdAt": "2019-11-24T14:49:28.963+0000"
    },
    {
      "id": 13,
      "sourceId": 2,
      "receiverId": 9,
      "content": "nabber",
      "createdAt": "2019-11-24T14:49:30.561+0000"
    },
    {
      "id": 14,
      "sourceId": 2,
      "receiverId": 9,
      "content": "nabber",
      "createdAt": "2019-11-24T14:49:31.344+0000"
    },
    {
      "id": 15,
      "sourceId": 2,
      "receiverId": 9,
      "content": "nabber",
      "createdAt": "2019-11-24T15:55:51.799+0000"
    },
    {
      "id": 16,
      "sourceId": 9,
      "receiverId": 2,
      "content": "asffghff",
      "createdAt": "2019-11-24T16:01:23.690+0000"
    },
    {
      "id": 17,
      "sourceId": 9,
      "receiverId": 2,
      "content": "asdfghjkli",
      "createdAt": "2019-11-24T16:01:34.912+0000"
    },
    {
      "id": 18,
      "sourceId": 9,
      "receiverId": 2,
      "content": "ibrahm",
      "createdAt": "2019-11-24T16:01:46.860+0000"
    },
    {
      "id": 19,
      "sourceId": 9,
      "receiverId": 2,
      "content": "iyi",
      "createdAt": "2019-11-24T16:18:16.600+0000"
    },
    {
      "id": 20,
      "sourceId": 9,
      "receiverId": 2,
      "content": "çok güzel mesajlaşma",
      "createdAt": "2019-11-24T16:56:26.617+0000"
    },
    {
      "id": 21,
      "sourceId": 9,
      "receiverId": 2,
      "content": "yfgjomö",
      "createdAt": "2019-11-24T17:02:18.924+0000"
    },
    {
      "id": 22,
      "sourceId": 9,
      "receiverId": 2,
      "content": "irem",
      "createdAt": "2019-11-24T17:09:54.875+0000"
    },
    {
      "id": 23,
      "sourceId": 37,
      "receiverId": 9,
      "content": "Selam İremm ",
      "createdAt": "2019-11-25T04:51:11.692+0000"
    },
    {
      "id": 24,
      "sourceId": 37,
      "receiverId": 9,
      "content": "Deneme yapıyorum :D ",
      "createdAt": "2019-11-25T04:51:39.463+0000"
    },
    {
      "id": 25,
      "sourceId": 9,
      "receiverId": 37,
      "content": "selam ",
      "createdAt": "2019-11-25T04:53:31.176+0000"
    },
    {
      "id": 26,
      "sourceId": 37,
      "receiverId": 9,
      "content": "Günaydın irem",
      "createdAt": "2019-11-25T10:39:09.810+0000"
    },
    {
      "id": 27,
      "sourceId": 37,
      "receiverId": 9,
      "content": "Ben de ibrahim :D",
      "createdAt": "2019-11-25T10:39:16.587+0000"
    },
    {
      "id": 28,
      "sourceId": 9,
      "receiverId": 37,
      "content": "Ben de game :D\n",
      "createdAt": "2019-11-25T10:39:34.911+0000"
    },
    {
      "id": 29,
      "sourceId": 37,
      "receiverId": 9,
      "content": "Ama saat sıkıntılı :D",
      "createdAt": "2019-11-25T10:40:12.159+0000"
    },
    {
      "id": 30,
      "sourceId": 37,
      "receiverId": 9,
      "content": "13 40 yazıyor",
      "createdAt": "2019-11-25T10:40:24.313+0000"
    },
    {
      "id": 31,
      "sourceId": 9,
      "receiverId": 8,
      "content": "selam gg",
      "createdAt": "2019-11-25T10:40:30.933+0000"
    },
    {
      "id": 32,
      "sourceId": 37,
      "receiverId": 9,
      "content": "Halbuki 16 40",
      "createdAt": "2019-11-25T10:40:36.387+0000"
    },
    {
      "id": 33,
      "sourceId": 9,
      "receiverId": 8,
      "content": "deneme",
      "createdAt": "2019-11-25T17:17:43.781+0000"
    }
  ]
}

Get Conversation Content

Request Content: user id1, user id2

Response Content: List of Messages of the conversation

Example Request
GET /messages/chat?userId1=9&userId2=8
Example Response
{
  "status": 200,
  "explanation": null,
  "data": [
    {
      "id": 31,
      "sourceId": 9,
      "receiverId": 8,
      "content": "selam gg",
      "createdAt": "2019-11-25T10:40:30.933+0000"
    },
    {
      "id": 33,
      "sourceId": 9,
      "receiverId": 8,
      "content": "deneme",
      "createdAt": "2019-11-25T17:17:43.781+0000"
    }
  ]
}

Create Message

Request Content: sourceId, receiverId, content

Response Content: Conversation content between two users

Example Request
POST /messages
{
  "content": "this is a message",
  "receiverId": 9,
  "sourceId": 8
}
Example Response
{
  "status": 200,
  "explanation": null,
  "data": [
    {
      "id": 31,
      "sourceId": 9,
      "receiverId": 8,
      "content": "selam gg",
      "createdAt": "2019-11-25T10:40:30.933+0000"
    },
    {
      "id": 33,
      "sourceId": 9,
      "receiverId": 8,
      "content": "deneme",
      "createdAt": "2019-11-25T17:17:43.781+0000"
    },
    {
      "id": 42,
      "sourceId": 8,
      "receiverId": 9,
      "content": "this is a message",
      "createdAt": "2019-12-01T16:20:34.554+0000"
    }
  ]
}

Annotation Endpoints

Create Annotation

Request Content: Annotation string

Response Content: Ok

Example Request
POST /annotations
{
  "annotation": "This is an annotation message."
}
Example Response
{
  "data": null,
  "explanation": null,
  "status": 200
}

Update Annotation

Request Content: Annotation string, annotation id

Response Content: Ok

Example Request
POST /annotations
{
  "annotation": "This is an annotation message.",
  "id": 3
}
Example Response
{
  "data": null,
  "explanation": null,
  "status": 200
}

Get Annotation

Request Content: Annotation id

Response Content: Annotation itself, by id

Example Request
GET /annotations/getById?id=3
Example Response
{
  "id": "http://api.bounswe2019group9.tk/annotations?id=3",
  "field": "hasan",
  "field2": "mahmut"
}

Delete Annotation

Request Content: Annotation id

Response Content: Ok

Example Request
GET /annotations/deleteById?annotationId=3
Example Response
{
  "data": null,
  "explanation": null,
  "status": 200
}

Search Annotation

Request Content: Target id

Response Content: Annotation string

Example Request
GET /annotations/searchInAnnotations?targetId=3
Example Response
{
  "status": 200,
  "explanation": null,
  "data": [
    "{ \"id\": \"http://api.bounswe2019group9.tk/annotations?id=4\",\"field\":\"http://www.w3.org/TR/media-frags/\", \"field2\":\"mahmut\"}",
    "{ \"id\": \"http://api.bounswe2019group9.tk/annotations?id=5\",\"field\":\"http://www.w3.org/TR/media-frags/\", \"field2\":\"mahmut\"}",
    "{ \"id\": \"http://api.bounswe2019group9.tk/annotations?id=6\", \"url\": \"http://www.w3.org/TR/media-frags/\" }",
    "{ \"id\": \"http://api.bounswe2019group9.tk/annotations?id=7\", \"url\": \"http://www.w3.org/ns/anno.jsonld/\" }",
    "{ \"id\": \"http://api.bounswe2019group9.tk/annotations?id=8\", 'url': 'http://www.w3.org/ns/anno.jsonld/', 'neden': 'singlequote' }",
    "{ \"id\": \"http://api.bounswe2019group9.tk/annotations?id=19\", \"dasdsa\": \" 5635 \" }",
    "{ \"id\": \"http://api.bounswe2019group9.tk/annotations?id=20\", \"dasdsa\": \" 5635 \" }",
    "{ \"id\": \"http://api.bounswe2019group9.tk/annotations?id=37\",\"@context\":\"http://www.w3.org/ns/anno.jsonld\",\"type\":\"Annotation\",\"creator\":{\"id\":\"https://bounswe2019group9.tk/users/22\",\"name\":\"Mahmut Kızıloğlu\",\"email\":\"[email protected]\"},\"created\":\"2019-12-24T14:43:10.115Z\",\"modified\":\"2019-12-24T14:43:19.094Z\",\"body\":{\"type\":\"TextualBody\",\"value\":\"kjhkjhjkhlkjhliutuyftsrtyuiuytr\",\"format\":\"text/plain\"},\"motivation\":\"assessing\",\"target\":{\"id\":\"https://api.bounswe2019group9.tk/essays/getSourceByEssayId?id=24\",\"type\":\"Text\",\"format\":\"text/plain\",\"selector\":{\"type\":\"FragmentSelector\",\"conformsTo\":\"http://tools.ietf.org/rfc/rfc5147\",\"value\":\"char=323,482\"}}}",
    "{ \"id\": \"http://api.bounswe2019group9.tk/annotations?id=38\",\"@context\":\"http://www.w3.org/ns/anno.jsonld\",\"type\":\"Annotation\",\"creator\":{\"id\":\"https://bounswe2019group9.tk/users/22\",\"name\":\"Mahmut Kızıloğlu\",\"email\":\"[email protected]\"},\"created\":\"2019-12-24T14:43:29.904Z\",\"modified\":\"2019-12-24T14:43:33.008Z\",\"body\":{\"type\":\"TextualBody\",\"value\":\"jgt\",\"format\":\"text/plain\"},\"motivation\":\"commenting\",\"target\":{\"id\":\"https://api.bounswe2019group9.tk/essays/getSourceByEssayId?id=24\",\"type\":\"Text\",\"format\":\"text/plain\",\"selector\":{\"type\":\"FragmentSelector\",\"conformsTo\":\"http://tools.ietf.org/rfc/rfc5147\",\"value\":\"char=180,192\"}}}",
    "{ \"id\": \"http://api.bounswe2019group9.tk/annotations?id=25\",\"@context\":\"http://www.w3.org/ns/anno.jsonld\",\"type\":\"Annotation\",\"creator\":{\"id\":\"https://bounswe2019group9.tk/users/30\",\"name\":\"John Johnwell\",\"email\":\"[email protected]\"},\"created\":\"2019-12-24T10:55:49.132Z\",\"modified\":\"2019-12-24T11:18:45.251Z\",\"body\":{\"type\":\"TextualBody\",\"value\":\"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.\",\"format\":\"text/plain\"},\"motivation\":\"describing\",\"target\":{\"id\":\"https://api.bounswe2019group9.tk/essays/getSourceByEssayId?id=17\",\"type\":\"Text\",\"format\":\"text/plain\",\"selector\":{\"type\":\"FragmentSelector\",\"conformsTo\":\"http://tools.ietf.org/rfc/rfc5147\",\"value\":\"char=3,5\"}}}",
    "{ \"id\": \"http://api.bounswe2019group9.tk/annotations?id=26\",\"@context\":\"http://www.w3.org/ns/anno.jsonld\",\"type\":\"Annotation\",\"creator\":{\"id\":\"https://bounswe2019group9.tk/users/30\",\"name\":\"John Johnwell\",\"email\":\"[email protected]\"},\"created\":\"2019-12-24T11:30:44.664Z\",\"modified\":\"2019-12-24T11:36:44.649Z\",\"body\":{\"type\":\"TextualBody\",\"value\":\"Well done here\",\"format\":\"text/plain\"},\"motivation\":\"assessing\",\"target\":{\"id\":\"https://kereviz-upload.s3.eu-central-1.amazonaws.com/image/essay/6_30.jpeg\",\"type\":\"Image\",\"format\":\"image/jpeg\",\"selector\":{\"type\":\"FragmentSelector\",\"conformsTo\":\"http://www.w3.org/TR/media-frags/\",\"value\":\"xywh=56,209,305,46\"}}}",
    "{ \"id\": \"http://api.bounswe2019group9.tk/annotations?id=27\",\"@context\":\"http://www.w3.org/ns/anno.jsonld\",\"type\":\"Annotation\",\"creator\":{\"id\":\"https://bounswe2019group9.tk/users/30\",\"name\":\"John Johnwell\",\"email\":\"[email protected]\"},\"created\":\"2019-12-24T11:30:56.984Z\",\"modified\":\"2019-12-24T11:36:49.841Z\",\"body\":{\"type\":\"TextualBody\",\"value\":\"Oh my god, great!!\",\"format\":\"text/plain\"},\"motivation\":\"describing\",\"target\":{\"id\":\"https://kereviz-upload.s3.eu-central-1.amazonaws.com/image/essay/6_30.jpeg\",\"type\":\"Image\",\"format\":\"image/jpeg\",\"selector\":{\"type\":\"FragmentSelector\",\"conformsTo\":\"http://www.w3.org/TR/media-frags/\",\"value\":\"xywh=54,321,88,181\"}}}",
    "{ \"id\": \"http://api.bounswe2019group9.tk/annotations?id=28\",\"@context\":\"http://www.w3.org/ns/anno.jsonld\",\"type\":\"Annotation\",\"creator\":{\"id\":\"https://bounswe2019group9.tk/users/30\",\"name\":\"John Johnwell\",\"email\":\"[email protected]\"},\"created\":\"2019-12-24T12:23:03.494Z\",\"modified\":\"2019-12-24T12:23:09.048Z\",\"body\":{\"type\":\"TextualBody\",\"value\":\"Wow dude\",\"format\":\"text/plain\"},\"motivation\":\"commenting\",\"target\":{\"id\":\"https://kereviz-upload.s3.eu-central-1.amazonaws.com/image/essay/6_12.jpeg\",\"type\":\"Image\",\"format\":\"image/jpeg\",\"selector\":{\"type\":\"FragmentSelector\",\"conformsTo\":\"http://www.w3.org/TR/media-frags/\",\"value\":\"xywh=138,193,60,30\"}}}",
    "{ \"id\": \"http://api.bounswe2019group9.tk/annotations?id=29\",\"@context\":\"http://www.w3.org/ns/anno.jsonld\",\"type\":\"Annotation\",\"creator\":{\"id\":\"https://bounswe2019group9.tk/users/30\",\"name\":\"John Johnwell\",\"email\":\"[email protected]\"},\"created\":\"2019-12-24T12:23:10.269Z\",\"modified\":\"2019-12-24T12:23:22.445Z\",\"body\":{\"type\":\"TextualBody\",\"value\":\"This is the best thing I've ever seen\",\"format\":\"text/plain\"},\"motivation\":\"bookmarking\",\"target\":{\"id\":\"https://kereviz-upload.s3.eu-central-1.amazonaws.com/image/essay/6_12.jpeg\",\"type\":\"Image\",\"format\":\"image/jpeg\",\"selector\":{\"type\":\"FragmentSelector\",\"conformsTo\":\"http://www.w3.org/TR/media-frags/\",\"value\":\"xywh=360,516,171,30\"}}}",
    "{ \"id\": \"http://api.bounswe2019group9.tk/annotations?id=33\",\"@context\":\"http://www.w3.org/ns/anno.jsonld\",\"type\":\"Annotation\",\"creator\":{\"id\":\"https://bounswe2019group9.tk/users/9\",\"name\":\"irem Uguz\",\"email\":\"[email protected]\"},\"created\":\"2019-12-24T13:30:48.093Z\",\"modified\":\"2019-12-24T13:31:04.987Z\",\"body\":{\"type\":\"TextualBody\",\"value\":\"burası net\",\"format\":\"text/plain\"},\"motivation\":\"classifying\",\"target\":{\"id\":\"https://kereviz-upload.s3.eu-central-1.amazonaws.com/image/essay/3_9.jpeg\",\"type\":\"Image\",\"format\":\"image/jpeg\",\"selector\":{\"type\":\"FragmentSelector\",\"conformsTo\":\"http://www.w3.org/TR/media-frags/\",\"value\":\"xywh=277,307,60,30\"}}}",
    "{ \"id\": \"http://api.bounswe2019group9.tk/annotations?id=30\",\"@context\":\"http://www.w3.org/ns/anno.jsonld\",\"type\":\"Annotation\",\"creator\":{\"id\":\"https://bounswe2019group9.tk/users/30\",\"name\":\"John Johnwell\",\"email\":\"[email protected]\"},\"created\":\"2019-12-24T12:23:23.805Z\",\"modified\":\"2019-12-24T12:23:33.583Z\",\"body\":{\"type\":\"TextualBody\",\"value\":\"It even supports scroll, woah\",\"format\":\"text/plain\"},\"motivation\":\"highlighting\",\"target\":{\"id\":\"https://kereviz-upload.s3.eu-central-1.amazonaws.com/image/essay/6_12.jpeg\",\"type\":\"Image\",\"format\":\"image/jpeg\",\"selector\":{\"type\":\"FragmentSelector\",\"conformsTo\":\"http://www.w3.org/TR/media-frags/\",\"value\":\"xywh=138,642,60,30\"}}}",
    "{ \"id\": \"http://api.bounswe2019group9.tk/annotations?id=32\",\"@context\":\"http://www.w3.org/ns/anno.jsonld\",\"type\":\"Annotation\",\"creator\":{\"id\":\"https://bounswe2019group9.tk/users/9\",\"name\":\"irem Uguz\",\"email\":\"[email protected]\"},\"created\":\"2019-12-24T13:30:17.798Z\",\"modified\":\"2019-12-24T13:30:44.551Z\",\"body\":{\"type\":\"TextualBody\",\"value\":\"Merhaba bunu ben yazdım\",\"format\":\"text/plain\"},\"motivation\":\"bookmarking\",\"target\":{\"id\":\"https://kereviz-upload.s3.eu-central-1.amazonaws.com/image/essay/3_9.jpeg\",\"type\":\"Image\",\"format\":\"image/jpeg\",\"selector\":{\"type\":\"FragmentSelector\",\"conformsTo\":\"http://www.w3.org/TR/media-frags/\",\"value\":\"xywh=301,45,201,215\"}}}",
    "{ \"id\": \"http://api.bounswe2019group9.tk/annotations?id=31\",\"@context\":\"http://www.w3.org/ns/anno.jsonld\",\"type\":\"Annotation\",\"creator\":{\"id\":\"https://bounswe2019group9.tk/users/12\",\"name\":\"Johnie Walker\",\"email\":\"[email protected]\"},\"created\":\"2019-12-24T12:24:11.645Z\",\"modified\":\"2019-12-24T12:24:49.757Z\",\"body\":{\"type\":\"TextualBody\",\"value\":\"I know right!!\",\"format\":\"text/plain\"},\"motivation\":\"moderating\",\"target\":{\"id\":\"https://kereviz-upload.s3.eu-central-1.amazonaws.com/image/essay/6_12.jpeg\",\"type\":\"Image\",\"format\":\"image/jpeg\",\"selector\":{\"type\":\"FragmentSelector\",\"conformsTo\":\"http://www.w3.org/TR/media-frags/\",\"value\":\"xywh=18,394,75,56\"}}}",
    "{ \"id\": \"http://api.bounswe2019group9.tk/annotations?id=34\",\"@context\":\"http://www.w3.org/ns/anno.jsonld\",\"type\":\"Annotation\",\"creator\":{\"id\":\"https://bounswe2019group9.tk/users/41\",\"name\":\"Doğan Çavdarcı\",\"email\":\"[email protected]\"},\"created\":\"2019-12-24T13:32:15.392Z\",\"modified\":\"2019-12-24T13:32:26.445Z\",\"body\":{\"type\":\"TextualBody\",\"value\":\"burası olmamıs düzelecek\",\"format\":\"text/plain\"},\"motivation\":\"editing\",\"target\":{\"id\":\"https://kereviz-upload.s3.eu-central-1.amazonaws.com/image/essay/3_9.jpeg\",\"type\":\"Image\",\"format\":\"image/jpeg\",\"selector\":{\"type\":\"FragmentSelector\",\"conformsTo\":\"http://www.w3.org/TR/media-frags/\",\"value\":\"xywh=397,290,60,30\"}}}",
    "{ \"id\": \"http://api.bounswe2019group9.tk/annotations?id=35\",\"@context\":\"http://www.w3.org/ns/anno.jsonld\",\"type\":\"Annotation\",\"creator\":{\"id\":\"https://bounswe2019group9.tk/users/30\",\"name\":\"John Johnwell\",\"email\":\"[email protected]\"},\"created\":\"2019-12-24T13:37:19.537Z\",\"modified\":\"2019-12-24T13:37:23.015Z\",\"body\":{\"type\":\"TextualBody\",\"value\":\"asdasdas\",\"format\":\"text/plain\"},\"motivation\":\"describing\",\"target\":{\"id\":\"https://api.bounswe2019group9.tk/essays/getSourceByEssayId?id=17\",\"type\":\"Text\",\"format\":\"text/plain\",\"selector\":{\"type\":\"FragmentSelector\",\"conformsTo\":\"http://tools.ietf.org/rfc/rfc5147\",\"value\":\"char=0,3\"}}}",
    "{ \"id\": \"http://api.bounswe2019group9.tk/annotations?id=36\",\"@context\":\"http://www.w3.org/ns/anno.jsonld\",\"type\":\"Annotation\",\"creator\":{\"id\":\"https://bounswe2019group9.tk/users/22\",\"name\":\"Mahmut Kızıloğlu\",\"email\":\"[email protected]\"},\"created\":\"2019-12-24T14:42:56.554Z\",\"modified\":\"2019-12-24T14:43:01.283Z\",\"body\":{\"type\":\"TextualBody\",\"value\":\"jhg\",\"format\":\"text/plain\"},\"motivation\":\"highlighting\",\"target\":{\"id\":\"https://api.bounswe2019group9.tk/essays/getSourceByEssayId?id=24\",\"type\":\"Text\",\"format\":\"text/plain\",\"selector\":{\"type\":\"FragmentSelector\",\"conformsTo\":\"http://tools.ietf.org/rfc/rfc5147\",\"value\":\"char=152,456\"}}}"
  ]
}

Comment Endpoints

Create Comment

Request Content: Content text, source id, receiver id

Response Content: Comment itself

Example Request
POST /comments
{
  "content": "Good one",
  "receiverId": 2,
  "sourceId": 3
}
Example Response
{
  "data": {
    "content": "Good one",
    "receiverId": 2,
    "sourceId": 3
  },
  "explanation": null,
  "status": 200
}

Get Comments By Receiver Id

Request Content: Receiver user id

Response Content: Comments of that user

Example Request
GET /comments/getCommentsByReceiverId?userId=3
Example Response
{
  "status": 200,
  "explanation": null,
  "data": [
    {
      "sourceFirstName": "ahmet",
      "sourceLastName": "test",
      "comment": {
        "id": 1,
        "sourceId": 1,
        "receiverId": 3,
        "content": "nice",
        "createdAt": "2019-12-14T00:00:00.000+0000"
      }
    }
  ]
}

Assignment Endpoints

Create Assignment

Request Content: Language id, question text

Response Content: Assignment itself

Example Request
POST /assignments
{
  "languageId": 1,
  "text": "What do you think about fortune telling?"
}
Example Response
{
  "data": {
    "languageId": 1,
    "text": "What do you think about fortune telling?"
  },
  "explanation": null,
  "status": 200
}

Get Assignment By Id

Request Content: Id

Response Content: Assignment with that id

Example Request
GET /assignments?id=3
Example Response
{
  "status": 200,
  "explanation": null,
  "data": {
    "id": 3,
    "question": "Describe a place you will never forget.",
    "languageId": 1
  }
}

Get Assignment By Language Id

Request Content: Language Id

Response Content: Assignments in that language

Example Request
GET /assignments/language?id=1
Example Response
{
  "status": 200,
  "explanation": null,
  "data": [
    {
      "id": 3,
      "question": "Describe a place you will never forget.",
      "languageId": 1
    },
    {
      "id": 4,
      "question": "Describe a sporting event you attended recently.",
      "languageId": 1
    },
    {
      "id": 5,
      "question": "Describe someone you respect deeply.",
      "languageId": 1
    },
    {
      "id": 6,
      "question": "Describe your childhood home.",
      "languageId": 1
    },
    {
      "id": 7,
      "question": "Describe the nightlife in a city you are familiar with.",
      "languageId": 1
    },
    {
      "id": 8,
      "question": "What would you do if you got lost in an unfamiliar city?",
      "languageId": 1
    },
    {
      "id": 9,
      "question": "What would you do if you left something in a locked building?",
      "languageId": 1
    },
    {
      "id": 1,
      "question": "What is your opinion about fortune telling?",
      "languageId": 1
    },
    {
      "id": 2,
      "question": "What is your opinion about cellular phones?",
      "languageId": 1
    }
  ]
}

Project Requirements

  • User: A person using the app/web platform of the project.
    • Guest: A user who is not registered yet.
    • Registered: A user who has signed up to the platform.
    • Admin: A user with special privileges.
  • Language: One of English/Turkish/Chinese or other provided language in the platform.
  • Learning Material: Content in one of the categories below, in one of the types below, in a given language used to teach users that language.
    • Categories: Categories of a learning material, one of Listening, Reading, Grammar, Vocabulary or Writing.
      • Listening: Materials relating to improving listening skills in a given language.
      • Reading: Materials relating to improving reading skills in a given language.
      • Grammar: Materials relating to improving grammar skills in a given language.
      • Vocabulary: Materials relating to improving vocabulary skills in a given language.
      • Writing: Materials relating to improving writing skills in a given language.
    • Types: Types of a learning material, one of Notes, Assignment, Exercise or Exam.
      • Notes: Materials that present notes about the content.
      • Assignments: Materials that require user to write a long answer(paragraph, essay, etc.) and another user to review & evaluate.
      • Exercises: Materials that require user to answer questions which can be automatically graded.
  • Proficiency Exam: A special exam consisting of questions used to evaluate the expertise of a user in a given language if the user wants to start directly from any level higher than A1.
  • Achievement: A user can get special labels according to accomplishing some tasks with given conditions, such as in 2 minutes.
  • Progress of Learning: The statistics about the users' learning history of a given language i.e. accomplished exercises, assignments, duration.
  • Interaction: Users can interact with each other in either one of the ways below.
    • Communication: A user can send a request to another user to chat privately.
      • Request: When a user sends a chat request to another user, chatting only starts after receiver user accepts the request.
    • Review: The process of a user grading another user's writing assignment, and providing feedback to that user related to the assignment.
      • Feedback: An explanation of how the user can do better or an error found in one's writing assignment.
      • Annotation: A user can add annotation to the writing assignment he/she is reviewing to give feedback to the reviewed.
  • Rating: A user can rate other users he/she interacted based on the related interaction.
  • Comment: A user can comment about other users he/she interacted based on the related interaction.
  • Level of Expertise:: The users' level of proficiency shown as either A1, A2, B1, B2, C1 or C2 in a given language.
  • Search System: A system allowing users to search for contents in a given language.
    • Basic Search System: A search system based on keywords and semantic search.
    • Advanced Search System: A search system that allows search and filter features by type, difficulty and tags.
  • Contribution System: Users can upload new learning materials and suggest them to be added to the system, or they can suggest new tags to existing material.
    • Verification: Admins can verify suggested tags to existing material to add them to the system. Also, for suggested new user uploaded materials, either a specified amount of users can support the suggestion to approval or an admin user can verify the material by himself/herself.

Requirements

1. Functional Requirements

1.1. User Requirements

  • 1.1.1. Users

    • 1.1.1.1. There will be three types of users.

    • 1.1.1.1.1. Guests

      • 1.1.1.1.1.1. Guest users can only access 5 exercises for each type of learning materials(except writing) before being prompted for registering.
    • 1.1.1.1.2. Registered Users

      • 1.1.1.1.2.1. Registered users should access to materials anytime and anywhere.
      • 1.1.1.1.2.2. Proficiency exam
        • 1.1.1.1.2.2.1. The users who want to start from higher level, shall take a proficiency exam.
        • 1.1.1.1.2.2.2. Users shall be able to see their exam results and see the content of corresponding level of their scores.
      • 1.1.1.1.2.3. After every question, the users shall be able to see the correct answer.
      • 1.1.1.1.2.4. Users shall be able to send their essays to other users for grading which includes feedback as well as the grade.
      • 1.1.1.1.2.5. If one user has graded other's assignment, or they have conversed via messaging, they shall be able to rate or comment on each other.
      • 1.1.1.1.2.6. Users shall be able to see their learning process such as completed exercises, grade achievements for each language.
      • 1.1.1.1.2.7. Users shall be able to upload their suggestion of some learning materials.
      • 1.1.1.1.2.8. Users shall be able to declare whether they want to review essays or not.
      • 1.1.1.1.2.9. Users shall be able to report inappropriate behavior and sensitive content.
      • 1.1.1.1.2.10. Users' profile pages should include the review count, rating, achievements, uploaded contents and comments about them.
    • 1.1.1.1.3. Administrators

      • 1.1.1.1.3.1. Administrators shall handle reports and be able to suspend or ban user accounts.
      • 1.1.1.1.3.2. Administrators shall be able to accept or reject a suggested content.
  • 1.1.2. Communication

    • 1.1.2.1. Users shall be able to communicate over a messaging channel.
      • 1.1.2.1.1. Two users can use the messaging service if and only if one sends a request for communication and the other one accepts.
      • 1.1.2.1.2. Users shall be able to see their message requests and accept or reject them.
  • 1.1.3. Login and Sign-up

    • 1.1.3.1. Unregistered users shall be able to register after giving the necessary information.
      • 1.1.3.1.1. Users shall provide their email address while registering.
      • 1.1.3.1.2. Users shall provide their names while registering.
      • 1.1.3.1.3. Users shall set up a password while registering to the system.
      • 1.1.3.1.4. Users shall provide their native languages whlie registering.
    • 1.1.3.2. Registered users shall be able to login to the system.
      • 1.1.3.2.1. Users shall be able to login to the system using their email address and their passwords.
      • 1.1.3.2.2. The users that had forgotten their passwords shall be able to set up a new password with a verification e-mail.

1.2. System Requirements

  • 1.2.1. Learning Materials
    • 1.2.1.1. There should be learning materials in different languages.
    • 1.2.1.2. The learning materials should be mapped into 5 different categories: listening, reading, grammar, vocabulary and writing.
    • 1.2.1.3. The materials uploaded by users exist in the system after verification.
    • 1.2.1.4. The materials can have one or more images or sounds.
  • 1.2.2. Assignments and Exams
    • 1.2.2.1. Listening, reading, grammar and vocabulary categories of assignments or exams will be graded automatically by the system.
    • 1.2.2.2. A user should be able to pick the person who shall grade the writing assignment.
    • 1.2.2.3. System provides the answers after every question in exercises.
    • 1.2.2.4. Writing assignments should be uploaded by tags in order for the system to suggest reviewers.
  • 1.2.3. Languages
    • 1.2.3.1. The system shall support multiple languages.
  • 1.2.4. Recommendation
    • 1.2.4.1. For grading writing assignments, the system shall recommend a selection of users.
      • 1.2.4.1.1. the system shall provide a recommendation mechanism that recommends a set of users as potential evaluators of the writing exercises.
  • 1.2.5. Annotation
    • 1.2.5.1. The system shall provide an annotation mechanism for enabling users to annotate text and images.
  • 1.2.6. Rating
    • 1.2.6.1. The system shall support rating and comments only between interacting users.
  • 1.2.7. Contribution
    • 1.2.7.1. New learning materials should be suggested by the users who upload their suggested materials.
    • 1.2.7.2. The admin users shall be able to accept or reject the uploaded learning materials by the users.
  • 1.2.8. Searching
    • 1.2.8.1. The system shall provide a basic search mechanism based on the keywords entered by the users.
    • 1.2.8.2. The system shall provide an advanced search mechanism to filter the content by difficulty, tag, type and like count.
    • 1.2.8.3. The system shall provide an user search mechanism by their name, ratings' value and count, previously reviewed tags and language expertise.
  • 1.2.9. Tagging
    • 1.2.9.1 The system should support a set of tags with every writing assignment.
    • 1.2.9.2 The system should suggest reviewers for writing assignments considering tags of the assignment and the reviewer.
  • 1.2.10. Liking and Reporting
    • 1.2.10.1. Users should be able to report any content for inappropriate, offensive or other reasons.

2. Non-Functional Requirements

2.1. Security

  • 2.1.1. User data shall be protected and used according to LAW ON THE PROTECTION OF PERSONAL DATA
  • 2.1.2. The personal information, contact information, copyrighted contents, license issues and everything related to these paradigms should be respected and considered.
  • 2.1.3. System shall be protected against SQL injection.
  • 2.1.4. System should use encryption for personal messages between users.
  • 2.1.5. Storing of passwords should conform to security standards such as hashing.

2.2. Reliability

  • 2.2.1. The system shall serve to 300 users without breaking.

2.3. Availability

  • 2.3.1. Project shall be available on both Android and Web platforms.
  • 2.3.2. The application should be deployable on a manually configurable remote server.

2.4. Protocols & Standards

2.5. Performance

  • 2.5.1. The system shall respond to 100 requests per second.
  • 2.5.2. Maximum response time shall be at most 500 ms.

Change Log

26 February 2019

  • Added Glossary
  • Fixed requirements according to feedback
  • Updated requirements to match with the answers from customer meeting

27 February 2019

  • Added the requirement part 1.1.3. Further changes will be made to this section after determining the details.

3 March 2019

  • Updated non-functional requirements.

5 March 2019

  • Proof-read and made minor corrections.

14 March 2019

  • Guest user's access details are edited.
  • Added a part about approval of learning materials. (1.2.7 edited)
  • Updated registered users part about reviewing essays.

28 September 2019

  • Removed accessibility
  • Revised tags and reviews.
  • Every user can suggest content, admins accept or reject them.
  • Minor corrections.
  • User search added.
  • Liking and reporting content is added.

Design Documents

Use Case Diagram

Class Diagram

ClassDiagram


Sequence Diagram

  1. Login
  2. Register
  3. Ban User
  4. Comment User
  5. Rate User
  6. Exercise
  7. Review
  8. Verify Tag
  9. Basic Search
  10. Writing Assignment
  11. Writing Review

User Manuel

Content

  • Introduction to Kereviz
  • Select Your Language
  • Learn Your Level
  • Exercise
  • Interact With Other Learners
  • Contact Us

Introduction to Kereviz

Kereviz offers superior on-site language learning materials, providing the intercultural and communicative environment for the customers who love to interact with each other whilst learning and exercising with our unique learning materials. Our team will ensure that every one of our customers will get the necessary information on the languages that they like to learn and support with any problem on the site. Our clients are people who like to learn languages, teach languages and interact and communicate with each other while doing that.

Select Your Language

After logging in, you will be redirected to a page where you select the language you desire to learn or practice. For the time being, our system only supports three languages: English, Turkish and Italian. After the selection, you will be able to access the materials of that language.

Learn Your Level

After selecting your language, you can immediately take our free profocoency exam and our system analyzes your score and give you your level in that language. After that you can make exercises according to your level.

Exercise

We have five types of exercises:

  1. Reading
  2. Listening
  3. Grammer
  4. Vocabulary
  5. Writing

You can choose any kind of exercise you like to train on, learn and practice with our user-friendly teaching techniques. Other than writing, all of our exercise are made of multiple choice questions. To make a writing exercise, you have two options. You can write your essay on the web site and sed it to someone you like for getting feedback and corrections or you can write your essay with your pen on a paper and upload the picture of your writing to pur website and also send it to someone for feedback purposes. You can see your previous essays by clicking the "My Essays" button on the upper bar and also see the reviews of your essays by clicking "Essay Reviews".

Interact With Other Learners

In our platform, we value information exchange between individuals and we want our learners to learn together. Our users can folow, contact and chat with each other, share their experiences or can get feedback from each other.

You can search for a user, send invite to chat with her/him, leave comments after any interaction and rate them. So it is kind of fun and like social language learning :D

Contact Us

Please feel free to contact us with any question! We are at Bogazici University, Computer Engineering Building, A4 or you can mail us at [email protected]

System Manuel

Android

Installing The App

Download kereviz-android.apk file from the Github repository. Connect an Android device to the computer and send the kereviz-android.apk file to the Android device via the USB cable. On the Android device open the file. The installation of the app must start automatically.

Note: Android device must be in developer mode. To switch your device to Developer mode, click to the Android version in the Settings, seven times.

Minimum SDK version supported for Android app is 15.

Debugging The App

The Android app is developed on Android Studio and Android Studio is the IDE that is advised by Kereviz team to use if you want to see the code and debug.

After installing Android Studio, clone the repository using Git commands on the terminal of Android Studio. After cloning, Gradle build should be automatically configured. And the code will be visible on the Android Studio.

You can debug the app using a real Android device or Android emulator of Android Studio once the code is cloned. Simply click the green triangle on the top and select which device you want to use.

Front-End

You can use npm start after npm install and you are good to go!

You can also use npm test for running the unit tests.

You can also use npm cosmos for checking out / trying some of the components individually. (it's like storybook)

🏠 Home

📃 Assignments

👯 Team Members

📚 Resources

Clone this wiki locally