diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/TestRiskLevelCalculation.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/TestRiskLevelCalculation.kt
index 7c76a021c136143cfc24ea622e70770d00d10ff8..06ab72e5bd5d4db5c22262ebd42b247d9bdcf527 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/TestRiskLevelCalculation.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/TestRiskLevelCalculation.kt
@@ -123,6 +123,7 @@ class TestRiskLevelCalculation : Fragment() {
     private suspend fun retrieveDiagnosisKeys() {
         try {
             RetrieveDiagnosisKeysTransaction.start()
+            calculateRiskLevel()
         } catch (e: TransactionException) {
             e.report(ExceptionCategory.INTERNAL)
         }
@@ -210,7 +211,10 @@ class TestRiskLevelCalculation : Fragment() {
             Observer {
                 tracingViewModel.viewModelScope.launch {
                     val riskAsString = "Level: ${it.riskLevel}\n" +
-                            "Calc. Score: ${it.riskScore}\n" +
+                            "Last successful Level: " +
+                            "${LocalData.lastSuccessfullyCalculatedRiskLevel()}\n" +
+                            "Calculated Score: ${it.riskScore}\n" +
+                            "Last Time Server Fetch: ${LocalData.lastTimeDiagnosisKeysFromServerFetch()}\n" +
                             "Tracing Duration: " +
                             "${TimeUnit.MILLISECONDS.toDays(TimeVariables.getTimeActiveTracingDuration())} days \n" +
                             "Tracing Duration in last 14 days: " +
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevel.kt
index 0f521a9d18849bfbca2d8ee19306508047d05b64..68db8003d018a4d36a8613c42cafd614447b08f0 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/risk/RiskLevel.kt
@@ -42,6 +42,12 @@ enum class RiskLevel(val raw: Int) {
         }
 
         // risk level categories
+        val UNSUCCESSFUL_RISK_LEVELS =
+            arrayOf(
+                UNDETERMINED,
+                NO_CALCULATION_POSSIBLE_TRACING_OFF,
+                UNKNOWN_RISK_OUTDATED_RESULTS
+            )
         private val HIGH_RISK_LEVELS = arrayOf(INCREASED_RISK)
         private val LOW_RISK_LEVELS = arrayOf(
             UNKNOWN_RISK_INITIAL,
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/LocalData.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/LocalData.kt
index 192bf74d988e7093cae7bc93e369b877304fd940..7735bc4ced327496573f3297d5d3bf0e4941ba73 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/LocalData.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/LocalData.kt
@@ -4,6 +4,7 @@ import android.content.SharedPreferences
 import androidx.core.content.edit
 import de.rki.coronawarnapp.CoronaWarnApplication
 import de.rki.coronawarnapp.R
+import de.rki.coronawarnapp.risk.RiskLevel
 import de.rki.coronawarnapp.util.security.SecurityHelper.globalEncryptedSharedPreferencesInstance
 import java.util.Date
 
@@ -45,6 +46,33 @@ object LocalData {
         )
     }
 
+    /**
+     * Gets the time when the user has completed the onboarding
+     * from the EncryptedSharedPrefs
+     *
+     * @return
+     */
+    fun onboardingCompletedTimestamp(): Long? {
+        val timestamp = getSharedPreferenceInstance().getLong(
+            CoronaWarnApplication.getAppContext()
+                .getString(R.string.preference_onboarding_completed_timestamp), 0L
+        )
+
+        if (timestamp == 0L) return null
+        return timestamp
+    }
+
+    /**
+     * Sets the time when the user has completed the onboarding
+     * from the EncryptedSharedPrefs
+     * @param value
+     */
+    fun onboardingCompletedTimestamp(value: Long) = getSharedPreferenceInstance().edit(true) {
+        putLong(
+            CoronaWarnApplication.getAppContext()
+                .getString(R.string.preference_onboarding_completed_timestamp), value
+        )
+    }
     /****************************************************
      * TRACING DATA
      ****************************************************/
@@ -146,6 +174,78 @@ object LocalData {
         }
     }
 
+    /****************************************************
+     * RISK LEVEL
+     ****************************************************/
+
+    /**
+     * Gets the last calculated risk level
+     * from the EncryptedSharedPrefs
+     *
+     * @see RiskLevelRepository
+     *
+     * @return
+     */
+    fun lastCalculatedRiskLevel(): RiskLevel {
+        val rawRiskLevel = getSharedPreferenceInstance().getInt(
+            CoronaWarnApplication.getAppContext()
+                .getString(R.string.preference_risk_level_score),
+            RiskLevel.UNDETERMINED.raw
+        )
+        return RiskLevel.forValue(rawRiskLevel)
+    }
+
+    /**
+     * Sets the last calculated risk level
+     * from the EncryptedSharedPrefs
+     *
+     * @see RiskLevelRepository
+     *
+     * @param rawRiskLevel
+     */
+    fun lastCalculatedRiskLevel(rawRiskLevel: Int) =
+        getSharedPreferenceInstance().edit(true) {
+            putInt(
+                CoronaWarnApplication.getAppContext()
+                    .getString(R.string.preference_risk_level_score),
+                rawRiskLevel
+            )
+        }
+
+    /**
+     * Gets the last successfully calculated risk level
+     * from the EncryptedSharedPrefs
+     *
+     * @see RiskLevelRepository
+     *
+     * @return
+     */
+    fun lastSuccessfullyCalculatedRiskLevel(): RiskLevel {
+        val rawRiskLevel = getSharedPreferenceInstance().getInt(
+            CoronaWarnApplication.getAppContext()
+                .getString(R.string.preference_risk_level_score_successful),
+            RiskLevel.UNDETERMINED.raw
+        )
+        return RiskLevel.forValue(rawRiskLevel)
+    }
+
+    /**
+     * Sets the last calculated risk level
+     * from the EncryptedSharedPrefs
+     *
+     * @see RiskLevelRepository
+     *
+     * @param rawRiskLevel
+     */
+    fun lastSuccessfullyCalculatedRiskLevel(rawRiskLevel: Int) =
+        getSharedPreferenceInstance().edit(true) {
+            putInt(
+                CoronaWarnApplication.getAppContext()
+                    .getString(R.string.preference_risk_level_score_successful),
+                rawRiskLevel
+            )
+        }
+
     /****************************************************
      * SERVER FETCH DATA
      ****************************************************/
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/RiskLevelRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/RiskLevelRepository.kt
index d2ecaaa45a67e2f9755c7a82f08670657348306a..61f9627f2b6bf8e2a067026723db217e7e7d3ebe 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/RiskLevelRepository.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/storage/RiskLevelRepository.kt
@@ -1,33 +1,66 @@
 package de.rki.coronawarnapp.storage
 
 import androidx.lifecycle.MutableLiveData
-import de.rki.coronawarnapp.CoronaWarnApplication
-import de.rki.coronawarnapp.R
 import de.rki.coronawarnapp.risk.RiskLevel
-import de.rki.coronawarnapp.risk.RiskLevel.UNDETERMINED
 import de.rki.coronawarnapp.risk.RiskLevelConstants
 
 object RiskLevelRepository {
 
+    /**
+     * LiveData variable that can be consumed in a ViewModel to observe RiskLevel changes
+     */
     val riskLevelScore = MutableLiveData(RiskLevelConstants.UNKNOWN_RISK_INITIAL)
 
-    fun setRiskLevelScore(score: RiskLevel) {
-        val rawRiskLevel = score.raw
+    /**
+     * Set the new calculated [RiskLevel]
+     * Calculation happens in the [de.rki.coronawarnapp.transaction.RiskLevelTransaction]
+     *
+     * @see de.rki.coronawarnapp.transaction.RiskLevelTransaction
+     * @see de.rki.coronawarnapp.risk.RiskLevelCalculation
+     *
+     * @param riskLevel
+     */
+    fun setRiskLevelScore(riskLevel: RiskLevel) {
+        val rawRiskLevel = riskLevel.raw
         riskLevelScore.postValue(rawRiskLevel)
-        LocalData.getSharedPreferenceInstance()
-            .edit()
-            .putInt(
-                CoronaWarnApplication.getAppContext()
-                    .getString(R.string.preference_risk_level_score),
-                rawRiskLevel
-            ).apply()
+
+        setLastCalculatedScore(rawRiskLevel)
+        setLastSuccessfullyCalculatedScore(riskLevel)
     }
 
-    fun getLastCalculatedScore(): RiskLevel {
-        val riskLevelScoreRaw = LocalData.getSharedPreferenceInstance().getInt(
-            CoronaWarnApplication.getAppContext()
-                .getString(R.string.preference_risk_level_score), UNDETERMINED.raw
-        )
-        return RiskLevel.forValue(riskLevelScoreRaw)
+    /**
+     * Get the last calculated RiskLevel
+     *
+     * @return
+     */
+    fun getLastCalculatedScore(): RiskLevel = LocalData.lastCalculatedRiskLevel()
+
+    /**
+     * Set the last calculated RiskLevel
+     *
+     * @param rawRiskLevel
+     */
+    private fun setLastCalculatedScore(rawRiskLevel: Int) =
+        LocalData.lastCalculatedRiskLevel(rawRiskLevel)
+
+    /**
+     * Get the last successfully calculated [RiskLevel]
+     *
+     * @see RiskLevel
+     *
+     * @return
+     */
+    fun getLastSuccessfullyCalculatedScore(): RiskLevel =
+        LocalData.lastSuccessfullyCalculatedRiskLevel()
+
+    /**
+     * Set the last successfully calculated [RiskLevel]
+     *
+     * @param riskLevel
+     */
+    private fun setLastSuccessfullyCalculatedScore(riskLevel: RiskLevel) {
+        if (!RiskLevel.UNSUCCESSFUL_RISK_LEVELS.contains(riskLevel)) {
+            LocalData.lastSuccessfullyCalculatedRiskLevel(riskLevel.raw)
+        }
     }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingActivity.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingActivity.kt
index 871029e488c1e173473012e37a8f8c69d1d64796..bee511d98e39ba1566300da84fcf7fcdcc12f44a 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingActivity.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/onboarding/OnboardingActivity.kt
@@ -48,6 +48,7 @@ class OnboardingActivity : AppCompatActivity(), LifecycleObserver {
 
     fun completeOnboarding() {
         LocalData.isOnboarded(true)
+        LocalData.onboardingCompletedTimestamp(System.currentTimeMillis())
         startActivity(Intent(this, MainActivity::class.java))
         finish()
     }
diff --git a/Corona-Warn-App/src/main/res/layout/fragment_test_risk_level_calculation.xml b/Corona-Warn-App/src/main/res/layout/fragment_test_risk_level_calculation.xml
index de86e326eb36ded52f49cba93a3719ae9d60d120..64cadd0143537488cfcb6068dadea8435ac1c672 100644
--- a/Corona-Warn-App/src/main/res/layout/fragment_test_risk_level_calculation.xml
+++ b/Corona-Warn-App/src/main/res/layout/fragment_test_risk_level_calculation.xml
@@ -63,7 +63,7 @@
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_marginTop="@dimen/spacing_normal"
-                android:text="Retrieve Local QR Code" />
+                android:text="Scan Local QR Code" />
 
             <Button
                 android:id="@+id/button_calculate_risk_level"
diff --git a/Corona-Warn-App/src/main/res/values/strings.xml b/Corona-Warn-App/src/main/res/values/strings.xml
index 6474fed1f768505b1c588fafb9540005d4825b9e..0969b737219e643e15ab83253e1a259c0e82a28a 100644
--- a/Corona-Warn-App/src/main/res/values/strings.xml
+++ b/Corona-Warn-App/src/main/res/values/strings.xml
@@ -14,6 +14,10 @@
         <xliff:g id="preference">preference_onboarding_completed</xliff:g>
     </string>
     <!-- NOTR -->
+    <string name="preference_onboarding_completed_timestamp">
+        <xliff:g id="preference">preference_onboarding_completed_timestamp</xliff:g>
+    </string>
+    <!-- NOTR -->
     <string name="preference_reset_app">
         <xliff:g id="preference">preference_reset_app</xliff:g>
     </string>
@@ -77,6 +81,10 @@
         <xliff:g id="preference">preference_risk_level_score</xliff:g>
     </string>
     <!-- NOTR -->
+    <string name="preference_risk_level_score_successful">
+        <xliff:g id="preference">preference_risk_level_score_successful</xliff:g>
+    </string>
+    <!-- NOTR -->
     <string name="preference_test_guid">
         <xliff:g id="preference">preference_test_guid</xliff:g>
     </string>