Skip to content
Snippets Groups Projects

This section explain all the functionnalities in the challenge part

Quiz

A quiz includes 4 basic questions and one custom question.

Basic Question

All basics Questions are created in the quizEntity.json. We have to add :

  • questionLabel => Label of the question
  • Answers => An array of three answers (answerLabel, isTrue)
  • description => Explain the question
  • source => Source of the explanation

This questions and answers are in random order.

In the question page the user have to select an answer and click validate. Then, he sees the right answer and a modal with the explanation and the source. After this modal, he goes to the next question. Depends on the answer, the question result state is set either correct or incorrect. If it is a right answer, the quiz result is incremented by one.

Custom Question

At the end of every quiz, we're creating a custom question. Here are the fields used to create a custom question

Field Type Description
type CustomQuestionType Type of custom qusetion: DATA or CALCULATION.
timeStep TimeStep Time step of the result value (DAY / WEEK / MONTH / YEAR). For CALCULATION type it's represent daily / weekly / monthly / yearly average.
interval TimeStep Interval in which the data will be searched (DAY / WEEK / MONTH / YEAR)
period CustomPeriod Use to define a specific period for the interval { day? / month? / year? }. If not assigned the period will be the last interval (example: last week)
result UserQuizState Indicate the state of the custom question (UNLOCKED, CORRECT, UNCORRECT)

Calculation of custom question is done by conbinaison of all parameters:

Type DATA

  • If period is empty.

Retrieve the max load of day/month/year (define by timeStep) from the last week, month, year (define by interval). => example: What day did I consumme the most on the last week ? type = CustomQuestionType.DATA timeStep = TimeStep.DAY interval = TimeStep.WEEK period = {}

  • If period is not empty

Retrieve the max load of day/month/year (define by timeStep) from week, month, year (define by interval) of period => example: What month did I consumme the most on year 2020 ? type = CustomQuestionType.DATA timeStep = TimeStep.MONTH interval = TimeStep.YEAR period = {year: 2020}

Type CALCULATION

  • If period is empty

Retrieve the average of day/month/year (define by timeStep) from the last week, month, year (define by interval). => example: Which is your daily average consumption on last week ? type = CustomQuestionType.CALCULATION timeStep = TimeStep.DAY interval = TimeStep.WEEK period = {}

  • If period is not empty

Retrieve the average of day/month/year (define by timeStep) from week, month, year (define by interval) of period => example: Which is your daily average consumption on january ? type = CustomQuestionType.DATA timeStep = TimeStep.DAY interval = TimeStep.MONTH period = {month: 1}

Then, two randoms answers are generated after defining the right answer.

A user can stop during a quiz and picks up where he left off. To define where the user left off, we have to check if at least one of the question result status is unlocked.

Once the custom question is answered, the quiz state is set to done. Then, the user sees his result and his earned stars. He can also retry or go back to the challenge page.

Exploration

Exploration is a feature where the user has to do an action in order to help him discover all features from ecolyo. They are 4 types of actions:

  • DECLARATIVE : The user has to do something outside of the app => No way for the app to know if the user did it so we trust him.
  • ACTION : Action whitin the app. When the user finishes he gets a notification.
  • CONSUMPTION : He has to do something in his consumption view.
  • ECOGESTURE : He needs to look at a specific Ecogesture.

In order to check if an exploration (which is not declarative) is done, a hook called useExploration is used.It is called on component that has to check if an exploration is done.

This hook called exploration service to check exploration by passing two parameters (the current challenge and the user exploration id associated with the exploration id of the current challenge). This check is done only if:

  • There is a current challenge
  • exploration.id of the current challenge is equal to the user exploration id
  • exploration.state is ONGOING

Depends on the type of an exploration, either the exploration remains in progress until it is fully done or it ends.

When the user finish the exploration, he gets a success message and five more stars are added to his challenge progression.

Duel

On launch

In order to find a valid reference period we search for a period which is defined by the duel duration.

We check the most recent period first if it's complete and then we go farther and farther in time if the ones before got missing values.
We also define a threshold for a maximum old period

!!! note "6 months for the moment - hardcoded." If the thresold is reached and no valid period was found, we alert the user that he can't launch the duel and have to wait before he can retry this process.

On going

Every time the user goes into the duel mode, we are checking if the duel is finished. if we have retrieved all data to calculate the user consumption on the duel duration, the duel is done.

!!! info "In order to not block the user if a value is mising, we are also setting the duel as done when we reach the startDate + delay in day to retrieve the data (based on the fluid) + 1 day. In this case the user consumption is done on known values."

On finish

Once the state of the duel is set to DONE, we save the user result and determine if he wins (userComsumption < threshold of the reference period) or if he loses. Then the user sees his earned badge.

Challenges

We can find the file challengeEntity.json in the /db folder. This file contains an array of challenges, and each of them includes relationships to duels, quiz, missions and actions.

UserData creation

Once a user launch a challenge in the Ecolyo app, we create a userChallenge and store it in the couchDB under the doctype 'com.grandlyon.ecolyo.userchallenge'. During this process, the objects related to the challenge (quiz, duel, mission, action) will be be converted to an user version which contains informations about the user progress, the fluids connected and so on. So we have now a userChallenge that contains a userQuiz, a userDuel, etc. instead of relations.

To illustrate this, let's show the conversion of quizEntity to userQuiz :

DuelEntity {
  id: string
  title: string
  description: string
  duration: Duration
}

Becomes :

UserQuiz {
  id: string
  title: string
  description: string
	duration: Duration
  threshold: number
  state: UserDuelState
  startDate: string | null
  fluidTypes: FluidType[]
  userConsumption: number
}

Data managment schema

Data Scheme