diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/storage/CheckInDatabaseData.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/storage/CheckInDatabaseData.kt
index 3434c4b92a59aa021ebd9c10f7269c716608845b..0a208c73332cfb9f026c11e5044228406b655d25 100644
--- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/storage/CheckInDatabaseData.kt
+++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/storage/CheckInDatabaseData.kt
@@ -2,6 +2,7 @@ package de.rki.coronawarnapp.eventregistration.storage
 
 import de.rki.coronawarnapp.eventregistration.storage.entity.TraceLocationCheckInEntity
 import de.rki.coronawarnapp.server.protocols.internal.pt.TraceLocationOuterClass
+import okio.ByteString.Companion.toByteString
 import org.joda.time.Instant
 
 object CheckInDatabaseData {
@@ -17,7 +18,7 @@ object CheckInDatabaseData {
         traceLocationEnd = Instant.parse("2021-01-01T15:00:00.000Z"),
         defaultCheckInLengthInMinutes = 15,
         traceLocationBytesBase64 = "",
-        signatureBase64 = "Signature",
+        signatureBase64 = "Signature".toByteArray().toByteString().base64(),
         checkInStart = Instant.parse("2021-01-01T12:30:00.000Z"),
         checkInEnd = Instant.parse("2021-01-01T14:00:00.000Z"),
         completed = false,
@@ -35,7 +36,7 @@ object CheckInDatabaseData {
         traceLocationEnd = null,
         defaultCheckInLengthInMinutes = null,
         traceLocationBytesBase64 = "",
-        signatureBase64 = "Signature",
+        signatureBase64 = "Signature".toByteArray().toByteString().base64(),
         checkInStart = Instant.parse("2021-01-01T12:30:00.000Z"),
         checkInEnd = Instant.parse("2021-01-01T14:00:00.000Z"),
         completed = false,
diff --git a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/storage/TraceLocationCheckInDaoTest.kt b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/storage/TraceLocationCheckInDaoTest.kt
index 60223bea5e51e2caba73607eb59fa01dabca3b01..b98dafcd84700ec2df653da9586fc160b72b78da 100644
--- a/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/storage/TraceLocationCheckInDaoTest.kt
+++ b/Corona-Warn-App/src/androidTest/java/de/rki/coronawarnapp/eventregistration/storage/TraceLocationCheckInDaoTest.kt
@@ -4,7 +4,10 @@ import androidx.room.Room
 import androidx.test.core.app.ApplicationProvider
 import de.rki.coronawarnapp.eventregistration.storage.CheckInDatabaseData.testCheckIn
 import de.rki.coronawarnapp.eventregistration.storage.CheckInDatabaseData.testCheckInWithoutCheckOutTime
+import io.kotest.assertions.throwables.shouldThrow
 import io.kotest.matchers.shouldBe
+import io.kotest.matchers.shouldNotBe
+import io.mockk.mockk
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.runBlocking
 import org.joda.time.Instant
@@ -82,4 +85,42 @@ class TraceLocationCheckInDaoTest : BaseTestInstrumentation() {
 
         checkInsFlow.first() shouldBe emptyList()
     }
+
+    @Test
+    fun traceLocationCheckInDaoRetrieveById() = runBlocking {
+        val generatedId1 = checkInDao.insert(testCheckIn)
+        val generatedId2 = checkInDao.insert(testCheckIn)
+
+        checkInDao.entryForId(generatedId1)!!.id shouldBe generatedId1
+        checkInDao.entryForId(generatedId2)!!.id shouldBe generatedId2
+    }
+
+    @Test
+    fun traceLocationCheckInDaoDeleteById() = runBlocking {
+        val generatedId1 = checkInDao.insert(testCheckIn)
+        val generatedId2 = checkInDao.insert(testCheckIn)
+
+        checkInDao.deleteByIds(listOf(generatedId1))
+        checkInDao.entryForId(generatedId1) shouldBe null
+        checkInDao.entryForId(generatedId2) shouldNotBe null
+    }
+
+    @Test
+    fun traceLocationCheckInDaoUpdateById() = runBlocking {
+        val generatedId1 = checkInDao.insert(testCheckIn)
+
+        checkInDao.updateEntityById(generatedId1) {
+            it.copy(address = "test")
+        }
+        checkInDao.entryForId(generatedId1)!!.address shouldBe "test"
+    }
+
+    @Test
+    fun traceLocationCheckInDaoUpdateById_raceCondition1(): Unit = runBlocking {
+        shouldThrow<IllegalStateException> {
+            checkInDao.updateEntityById(123) {
+                mockk()
+            }
+        }
+    }
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckIn.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckIn.kt
index 0c3b0f922f67193953e2b5341eabe4562ad8fb11..373561208c44432afa1d60cef6d004665a5e8772 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckIn.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckIn.kt
@@ -1,5 +1,6 @@
 package de.rki.coronawarnapp.eventregistration.checkins
 
+import de.rki.coronawarnapp.eventregistration.storage.entity.TraceLocationCheckInEntity
 import okio.ByteString
 import org.joda.time.Instant
 
@@ -22,3 +23,22 @@ data class CheckIn(
     val completed: Boolean,
     val createJournalEntry: Boolean
 )
+
+fun CheckIn.toEntity() = TraceLocationCheckInEntity(
+    id = id,
+    guid = guid,
+    guidHashBase64 = guidHash.base64(),
+    version = version,
+    type = type,
+    description = description,
+    address = address,
+    traceLocationStart = traceLocationStart,
+    traceLocationEnd = traceLocationEnd,
+    defaultCheckInLengthInMinutes = defaultCheckInLengthInMinutes,
+    traceLocationBytesBase64 = traceLocationBytes.base64(),
+    signatureBase64 = signature.base64(),
+    checkInStart = checkInStart,
+    checkInEnd = checkInEnd,
+    completed = completed,
+    createJournalEntry = createJournalEntry
+)
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRepository.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRepository.kt
index 78e8305820c7c805182367627cb39576fd898345..e4e7c5618f09ede87d3696bd2fb146f15e5c1011 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRepository.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRepository.kt
@@ -2,18 +2,16 @@ package de.rki.coronawarnapp.eventregistration.checkins
 
 import de.rki.coronawarnapp.eventregistration.storage.TraceLocationDatabase
 import de.rki.coronawarnapp.eventregistration.storage.dao.CheckInDao
-import de.rki.coronawarnapp.eventregistration.storage.entity.TraceLocationCheckInEntity
-import de.rki.coronawarnapp.util.coroutine.AppScope
-import kotlinx.coroutines.CoroutineScope
+import de.rki.coronawarnapp.eventregistration.storage.entity.toCheckIn
+import kotlinx.coroutines.NonCancellable
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.launch
-import okio.ByteString.Companion.decodeBase64
+import kotlinx.coroutines.withContext
+import timber.log.Timber
 import javax.inject.Inject
 
 class CheckInRepository @Inject constructor(
-    traceLocationDatabaseFactory: TraceLocationDatabase.Factory,
-    @AppScope private val appScope: CoroutineScope
+    traceLocationDatabaseFactory: TraceLocationDatabase.Factory
 ) {
 
     private val traceLocationDatabase: TraceLocationDatabase by lazy {
@@ -29,59 +27,25 @@ class CheckInRepository @Inject constructor(
             .allEntries()
             .map { list -> list.map { it.toCheckIn() } }
 
-    fun addCheckIn(checkIn: CheckIn) {
-        appScope.launch {
-            checkInDao.insert(checkIn.toEntity())
-        }
-    }
+    suspend fun addCheckIn(checkIn: CheckIn) = withContext(NonCancellable) {
+        Timber.d("addCheckIn(checkIn=%s)", checkIn)
+        if (checkIn.id == 0L) throw IllegalArgumentException("ID will be set by DB, ID should be 0!")
 
-    fun updateCheckIn(checkIn: CheckIn) {
-        appScope.launch {
-            checkInDao.update(checkIn.toEntity())
-        }
+        checkInDao.insert(checkIn.toEntity())
     }
 
-    fun clear() {
-        appScope.launch {
-            checkInDao.deleteAll()
-        }
+    suspend fun updateCheckIn(checkInId: Long, update: (CheckIn) -> CheckIn) = withContext(NonCancellable) {
+        Timber.d("updateCheckIn(checkInId=%d, update=%s)", checkInId, update)
+        checkInDao.updateEntityById(checkInId, update)
     }
-}
 
-private fun TraceLocationCheckInEntity.toCheckIn() = CheckIn(
-    id = id,
-    guid = guid,
-    guidHash = guidHashBase64.decodeBase64()!!,
-    version = version,
-    type = type,
-    description = description,
-    address = address,
-    traceLocationStart = traceLocationStart,
-    traceLocationEnd = traceLocationEnd,
-    defaultCheckInLengthInMinutes = defaultCheckInLengthInMinutes,
-    traceLocationBytes = traceLocationBytesBase64.decodeBase64()!!,
-    signature = signatureBase64.decodeBase64()!!,
-    checkInStart = checkInStart,
-    checkInEnd = checkInEnd,
-    completed = completed,
-    createJournalEntry = createJournalEntry
-)
+    suspend fun deleteCheckIns(checkIns: Collection<CheckIn>) = withContext(NonCancellable) {
+        Timber.d("deleteCheckIns(checkIns=%s)", checkIns)
+        checkInDao.deleteByIds(checkIns.map { it.id })
+    }
 
-private fun CheckIn.toEntity() = TraceLocationCheckInEntity(
-    id = id,
-    guid = guid,
-    guidHashBase64 = guidHash.base64(),
-    version = version,
-    type = type,
-    description = description,
-    address = address,
-    traceLocationStart = traceLocationStart,
-    traceLocationEnd = traceLocationEnd,
-    defaultCheckInLengthInMinutes = defaultCheckInLengthInMinutes,
-    traceLocationBytesBase64 = traceLocationBytes.base64(),
-    signatureBase64 = signature.base64(),
-    checkInStart = checkInStart,
-    checkInEnd = checkInEnd,
-    completed = completed,
-    createJournalEntry = createJournalEntry
-)
+    suspend fun clear() = withContext(NonCancellable) {
+        Timber.d("clear()")
+        checkInDao.deleteAll()
+    }
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/dao/CheckInDao.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/dao/CheckInDao.kt
index 75f5cbd8987f0d8172c5217cc03154afe0b02984..b45d75d1b09df3dd21f4967411f32e9e4f8c7ef4 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/dao/CheckInDao.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/dao/CheckInDao.kt
@@ -3,8 +3,12 @@ package de.rki.coronawarnapp.eventregistration.storage.dao
 import androidx.room.Dao
 import androidx.room.Insert
 import androidx.room.Query
+import androidx.room.Transaction
 import androidx.room.Update
+import de.rki.coronawarnapp.eventregistration.checkins.CheckIn
+import de.rki.coronawarnapp.eventregistration.checkins.toEntity
 import de.rki.coronawarnapp.eventregistration.storage.entity.TraceLocationCheckInEntity
+import de.rki.coronawarnapp.eventregistration.storage.entity.toCheckIn
 import kotlinx.coroutines.flow.Flow
 
 @Dao
@@ -13,12 +17,29 @@ interface CheckInDao {
     @Query("SELECT * FROM checkin")
     fun allEntries(): Flow<List<TraceLocationCheckInEntity>>
 
+    @Query("SELECT * FROM checkin WHERE id = :id")
+    suspend fun entryForId(id: Long): TraceLocationCheckInEntity?
+
     @Insert
     suspend fun insert(entity: TraceLocationCheckInEntity): Long
 
     @Update
     suspend fun update(entity: TraceLocationCheckInEntity)
 
+    @Transaction
+    suspend fun updateEntityById(checkInId: Long, update: (CheckIn) -> CheckIn) {
+        val current = entryForId(checkInId) ?: throw IllegalStateException("Entity $checkInId no longer exists.")
+
+        val updated = update(current.toCheckIn()).also {
+            if (it.id != checkInId) throw UnsupportedOperationException("Can't change entity id: $it")
+        }.toEntity()
+
+        update(updated)
+    }
+
     @Query("DELETE FROM checkin")
     suspend fun deleteAll()
+
+    @Query("DELETE FROM checkin WHERE id in (:idList)")
+    suspend fun deleteByIds(idList: List<Long>)
 }
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/entity/TraceLocationCheckInEntity.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/entity/TraceLocationCheckInEntity.kt
index 493fd68ae7bd23eca7beac95203e7467e02ef912..ab868da7e00bb20b3959be5d47c7d2f85fdc4004 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/entity/TraceLocationCheckInEntity.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/eventregistration/storage/entity/TraceLocationCheckInEntity.kt
@@ -3,6 +3,8 @@ package de.rki.coronawarnapp.eventregistration.storage.entity
 import androidx.room.ColumnInfo
 import androidx.room.Entity
 import androidx.room.PrimaryKey
+import de.rki.coronawarnapp.eventregistration.checkins.CheckIn
+import okio.ByteString.Companion.decodeBase64
 import org.joda.time.Instant
 
 @Entity(tableName = "checkin")
@@ -24,3 +26,22 @@ data class TraceLocationCheckInEntity(
     @ColumnInfo(name = "completed") val completed: Boolean,
     @ColumnInfo(name = "createJournalEntry") val createJournalEntry: Boolean
 )
+
+fun TraceLocationCheckInEntity.toCheckIn() = CheckIn(
+    id = id,
+    guid = guid,
+    guidHash = guidHashBase64.decodeBase64()!!,
+    version = version,
+    type = type,
+    description = description,
+    address = address,
+    traceLocationStart = traceLocationStart,
+    traceLocationEnd = traceLocationEnd,
+    defaultCheckInLengthInMinutes = defaultCheckInLengthInMinutes,
+    traceLocationBytes = traceLocationBytesBase64.decodeBase64()!!,
+    signature = signatureBase64.decodeBase64()!!,
+    checkInStart = checkInStart,
+    checkInEnd = checkInEnd,
+    completed = completed,
+    createJournalEntry = createJournalEntry
+)
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInEvent.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInEvent.kt
new file mode 100644
index 0000000000000000000000000000000000000000..8a775e5622bc1ddb7f2fa7710bb3629eb47795d6
--- /dev/null
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInEvent.kt
@@ -0,0 +1,13 @@
+package de.rki.coronawarnapp.ui.eventregistration.attendee.checkins
+
+import de.rki.coronawarnapp.eventregistration.checkins.CheckIn
+import de.rki.coronawarnapp.eventregistration.checkins.qrcode.TraceLocationVerifyResult
+
+sealed class CheckInEvent {
+
+    data class ConfirmRemoveItem(val checkIn: CheckIn) : CheckInEvent()
+
+    object ConfirmRemoveAll : CheckInEvent()
+
+    data class ConfirmCheckIn(val result: TraceLocationVerifyResult) : CheckInEvent()
+}
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsFragment.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsFragment.kt
index aadf44c7c54b4124555c852377e8de1c71d3ea7b..18273cb8a0965ff325d7b8ce98c34d6cc49e19d0 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsFragment.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsFragment.kt
@@ -4,6 +4,7 @@ import android.net.Uri
 import android.os.Bundle
 import android.view.View
 import android.widget.Toast
+import androidx.appcompat.app.AlertDialog
 import androidx.appcompat.widget.Toolbar
 import androidx.core.net.toUri
 import androidx.core.view.isGone
@@ -16,6 +17,7 @@ import androidx.recyclerview.widget.DefaultItemAnimator
 import com.google.android.material.transition.Hold
 import de.rki.coronawarnapp.R
 import de.rki.coronawarnapp.databinding.TraceLocationAttendeeCheckinsFragmentBinding
+import de.rki.coronawarnapp.eventregistration.checkins.CheckIn
 import de.rki.coronawarnapp.util.CWADebug
 import de.rki.coronawarnapp.util.di.AutoInject
 import de.rki.coronawarnapp.util.lists.decorations.TopBottomPaddingDecorator
@@ -87,13 +89,37 @@ class CheckInsFragment : Fragment(R.layout.trace_location_attendee_checkins_frag
             }
         }
 
-        viewModel.confirmationEvent.observe2(this) {
-            doNavigate(
-                CheckInsFragmentDirections.actionCheckInsFragmentToConfirmCheckInFragment(it.verifiedTraceLocation)
-            )
+        viewModel.events.observe2(this) {
+            when (it) {
+                is CheckInEvent.ConfirmCheckIn -> {
+                    doNavigate(
+                        CheckInsFragmentDirections.actionCheckInsFragmentToConfirmCheckInFragment(
+                            it.result.verifiedTraceLocation
+                        )
+                    )
+                }
+                is CheckInEvent.ConfirmRemoveItem -> {
+                    showRemovalConfirmation(it.checkIn)
+                }
+                is CheckInEvent.ConfirmRemoveAll -> {
+                    showRemovalConfirmation(null)
+                }
+            }
         }
     }
 
+    private fun showRemovalConfirmation(checkIn: CheckIn?) = AlertDialog.Builder(requireContext()).apply {
+        setTitle(
+            if (checkIn == null) R.string.trace_location_checkins_remove_all_title
+            else R.string.trace_location_checkins_remove_single_title
+        )
+        setMessage(R.string.trace_location_checkins_remove_message)
+        setPositiveButton(R.string.generic_action_remove) { _, _ ->
+            viewModel.onRemoveCheckInConfirmed(checkIn)
+        }
+        setNegativeButton(R.string.generic_action_abort) { _, _ -> /* NOOP */ }
+    }.show()
+
     private fun setupMenu(toolbar: Toolbar) = toolbar.apply {
         inflateMenu(R.menu.menu_trace_location_attendee_checkins)
         setOnMenuItemClickListener {
@@ -103,7 +129,7 @@ class CheckInsFragment : Fragment(R.layout.trace_location_attendee_checkins_frag
                     true
                 }
                 R.id.menu_remove_all -> {
-                    Toast.makeText(requireContext(), "Remove all // TODO", Toast.LENGTH_SHORT).show()
+                    viewModel.onRemoveAllCheckIns()
                     true
                 }
                 else -> onOptionsItemSelected(it)
diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsViewModel.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsViewModel.kt
index a4495a2ef096e1afa4e836422defeba1037349fa..da69a6ca520377209567c60001e2f7e389935047 100644
--- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsViewModel.kt
+++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ui/eventregistration/attendee/checkins/CheckInsViewModel.kt
@@ -6,17 +6,20 @@ import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 import de.rki.coronawarnapp.eventregistration.checkins.CheckIn
+import de.rki.coronawarnapp.eventregistration.checkins.CheckInRepository
 import de.rki.coronawarnapp.eventregistration.checkins.qrcode.QRCodeUriParser
 import de.rki.coronawarnapp.eventregistration.checkins.qrcode.TraceLocationQRCodeVerifier
-import de.rki.coronawarnapp.eventregistration.checkins.qrcode.TraceLocationVerifyResult
 import de.rki.coronawarnapp.exception.ExceptionCategory
 import de.rki.coronawarnapp.exception.reporting.report
 import de.rki.coronawarnapp.ui.eventregistration.attendee.checkins.items.ActiveCheckInVH
 import de.rki.coronawarnapp.ui.eventregistration.attendee.checkins.items.PastCheckInVH
+import de.rki.coronawarnapp.util.coroutine.AppScope
 import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
 import de.rki.coronawarnapp.util.ui.SingleLiveEvent
 import de.rki.coronawarnapp.util.viewmodel.CWAViewModel
 import de.rki.coronawarnapp.util.viewmodel.CWAViewModelFactory
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.flow
 import kotlinx.coroutines.flow.map
 import okio.ByteString.Companion.EMPTY
@@ -29,13 +32,18 @@ class CheckInsViewModel @AssistedInject constructor(
     @Assisted private val savedState: SavedStateHandle,
     @Assisted private val deepLink: String?,
     dispatcherProvider: DispatcherProvider,
+    @AppScope private val appScope: CoroutineScope,
     private val traceLocationQRCodeVerifier: TraceLocationQRCodeVerifier,
-    private val qrCodeUriParser: QRCodeUriParser
+    private val qrCodeUriParser: QRCodeUriParser,
+    private val checkInsRepository: CheckInRepository,
 ) : CWAViewModel(dispatcherProvider) {
 
-    val confirmationEvent = SingleLiveEvent<TraceLocationVerifyResult>()
+    val events = SingleLiveEvent<CheckInEvent>()
 
-    val checkins = FAKE_CHECKIN_SOURCE
+    val checkins = combine(
+        FAKE_CHECKIN_SOURCE,
+        checkInsRepository.allCheckIns
+    ) { fake: List<CheckIn>, real: List<CheckIn> -> fake + real }
         .map { checkins -> checkins.sortedBy { it.checkInEnd } }
         .map { checkins ->
             checkins.map { checkin ->
@@ -43,13 +51,13 @@ class CheckInsViewModel @AssistedInject constructor(
                     checkin.checkInEnd == null -> ActiveCheckInVH.Item(
                         checkin = checkin,
                         onCardClicked = { /* TODO */ },
-                        onRemoveItem = { /* TODO */ },
+                        onRemoveItem = { events.postValue(CheckInEvent.ConfirmRemoveItem(it)) },
                         onCheckout = { /* TODO */ }
                     )
                     else -> PastCheckInVH.Item(
                         checkin = checkin,
                         onCardClicked = { /* TODO */ },
-                        onRemoveItem = { /* TODO */ }
+                        onRemoveItem = { events.postValue(CheckInEvent.ConfirmRemoveItem(it)) }
                     )
                 }
             }
@@ -68,6 +76,22 @@ class CheckInsViewModel @AssistedInject constructor(
         savedState.set(SKEY_LAST_DEEPLINK, deepLink)
     }
 
+    fun onRemoveCheckInConfirmed(checkIn: CheckIn?) {
+        Timber.d("removeCheckin(checkIn=%s)", checkIn)
+        launch(scope = appScope) {
+            if (checkIn == null) {
+                checkInsRepository.clear()
+            } else {
+                checkInsRepository.deleteCheckIns(listOf(checkIn))
+            }
+        }
+    }
+
+    fun onRemoveAllCheckIns() {
+        Timber.d("onRemovaAllCheckIns()")
+        events.postValue(CheckInEvent.ConfirmRemoveAll)
+    }
+
     private fun verifyUri(uri: String) = launch {
         try {
             Timber.i("uri: $uri")
@@ -76,7 +100,7 @@ class CheckInsViewModel @AssistedInject constructor(
 
             val verifyResult = traceLocationQRCodeVerifier.verify(signedTraceLocation.toByteArray())
             Timber.i("verifyResult: $verifyResult")
-            confirmationEvent.postValue(verifyResult)
+            events.postValue(CheckInEvent.ConfirmCheckIn(verifyResult))
         } catch (e: Exception) {
             Timber.d(e, "TraceLocation verification failed")
             e.report(ExceptionCategory.INTERNAL)
@@ -104,7 +128,7 @@ private val FAKE_CHECKINS = listOf(
         version = 1,
         type = 1,
         description = "Jahrestreffen der deutschen SAP Anwendergruppe",
-        address = "Hauptstr. 3, 69115 Heidelberg",
+        address = "Hauptstr. 3, 69115 Heidelberg (FakeEntry)",
         traceLocationStart = null,
         traceLocationEnd = null,
         defaultCheckInLengthInMinutes = 3 * 60,
@@ -122,7 +146,7 @@ private val FAKE_CHECKINS = listOf(
         version = 1,
         type = 2,
         description = "CWA Launch Party",
-        address = "At home! Do you want the 'rona?",
+        address = "At home! Do you want the 'rona? (FakeEntry)",
         traceLocationStart = Instant.parse("2021-01-01T12:00:00.000Z"),
         traceLocationEnd = Instant.parse("2021-01-01T15:00:00.000Z"),
         defaultCheckInLengthInMinutes = 15,
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRepositoryTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRepositoryTest.kt
index ebd8bcd9bca9a76c21f49f3cb3a360e68a6f4776..0399a7d972ebffd55541b9a571ad17e42a5110fe 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRepositoryTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/eventregistration/checkins/CheckInRepositoryTest.kt
@@ -3,12 +3,15 @@ package de.rki.coronawarnapp.eventregistration.checkins
 import de.rki.coronawarnapp.eventregistration.storage.TraceLocationDatabase
 import de.rki.coronawarnapp.eventregistration.storage.dao.CheckInDao
 import de.rki.coronawarnapp.eventregistration.storage.entity.TraceLocationCheckInEntity
+import io.kotest.assertions.throwables.shouldThrow
 import io.kotest.matchers.shouldBe
 import io.mockk.MockKAnnotations
 import io.mockk.coEvery
 import io.mockk.coVerify
 import io.mockk.every
 import io.mockk.impl.annotations.MockK
+import io.mockk.mockk
+import io.mockk.slot
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.first
@@ -32,12 +35,37 @@ class CheckInRepositoryTest : BaseTest() {
         every { factory.create() } returns database
         every { database.eventCheckInDao() } returns checkInDao
         every { checkInDao.allEntries() } returns allEntriesFlow
+        coEvery { checkInDao.entryForId(any()) } coAnswers {
+            allEntriesFlow.first().singleOrNull { it.id == arg(0) }
+        }
     }
 
-    private fun createInstance(scope: CoroutineScope) = CheckInRepository(
-        factory,
-        scope
-    )
+    private fun createInstance(scope: CoroutineScope) = CheckInRepository(factory)
+
+    @Test
+    fun `new entities should have ID 0`() = runBlockingTest {
+        shouldThrow<IllegalArgumentException> {
+            val checkIn = CheckIn(
+                id = 0L,
+                guid = "41da2115-eba2-49bd-bf17-adb3d635ddaf",
+                guidHash = EMPTY,
+                version = 1,
+                type = 2,
+                description = "brothers birthday",
+                address = "Malibu",
+                traceLocationStart = Instant.EPOCH,
+                traceLocationEnd = null,
+                defaultCheckInLengthInMinutes = null,
+                traceLocationBytes = EMPTY,
+                signature = EMPTY,
+                checkInStart = Instant.EPOCH,
+                checkInEnd = Instant.EPOCH,
+                completed = false,
+                createJournalEntry = false
+            )
+            createInstance(scope = this).addCheckIn(checkIn)
+        }
+    }
 
     @Test
     fun `add new check in`() {
@@ -47,7 +75,7 @@ class CheckInRepositoryTest : BaseTest() {
             val end = Instant.ofEpochMilli(1397210400001)
             createInstance(scope = this).addCheckIn(
                 CheckIn(
-                    id = 0L,
+                    id = 1L,
                     guid = "41da2115-eba2-49bd-bf17-adb3d635ddaf",
                     guidHash = EMPTY,
                     version = 1,
@@ -68,7 +96,7 @@ class CheckInRepositoryTest : BaseTest() {
             coVerify {
                 checkInDao.insert(
                     TraceLocationCheckInEntity(
-                        id = 0L,
+                        id = 1L,
                         guid = "41da2115-eba2-49bd-bf17-adb3d635ddaf",
                         guidHashBase64 = "",
                         version = 1,
@@ -91,53 +119,19 @@ class CheckInRepositoryTest : BaseTest() {
     }
 
     @Test
-    fun `update new check in`() {
-        coEvery { checkInDao.update(any()) } returns Unit
-        runBlockingTest {
-            val start = Instant.ofEpochMilli(1397210400000)
-            val end = Instant.ofEpochMilli(1615796487)
-            createInstance(scope = this).updateCheckIn(
-                CheckIn(
-                    id = 0L,
-                    guid = "6e5530ce-1afc-4695-a4fc-572e6443eacd",
-                    guidHash = EMPTY,
-                    version = 1,
-                    type = 2,
-                    description = "sisters birthday",
-                    address = "Long Beach",
-                    traceLocationStart = start,
-                    traceLocationEnd = end,
-                    defaultCheckInLengthInMinutes = null,
-                    traceLocationBytes = EMPTY,
-                    signature = EMPTY,
-                    checkInStart = start,
-                    checkInEnd = end,
-                    completed = false,
-                    createJournalEntry = false
-                )
-            )
-            coVerify {
-                checkInDao.update(
-                    TraceLocationCheckInEntity(
-                        id = 0L,
-                        guid = "6e5530ce-1afc-4695-a4fc-572e6443eacd",
-                        guidHashBase64 = "",
-                        version = 1,
-                        type = 2,
-                        description = "sisters birthday",
-                        address = "Long Beach",
-                        traceLocationStart = start,
-                        traceLocationEnd = end,
-                        defaultCheckInLengthInMinutes = null,
-                        traceLocationBytesBase64 = "",
-                        signatureBase64 = "",
-                        checkInStart = start,
-                        checkInEnd = end,
-                        completed = false,
-                        createJournalEntry = false
-                    )
-                )
-            }
+    fun `update new check in`() = runBlockingTest {
+        val slot = slot<(CheckIn) -> CheckIn>()
+        coEvery { checkInDao.updateEntityById(any(), capture(slot)) } returns Unit
+
+        val checkIn = mockk<CheckIn>()
+        createInstance(scope = this).updateCheckIn(1L) {
+            checkIn
+        }
+
+        slot.captured.invoke(mockk()) shouldBe checkIn
+
+        coVerify {
+            checkInDao.updateEntityById(1L, any())
         }
     }
 
diff --git a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/submission/task/SubmissionTaskTest.kt b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/submission/task/SubmissionTaskTest.kt
index 81e9e2f5354fdaf9503bc2c27cb43a118fef4f68..f1514ebd9a61926d303dff9ed372b82331395e47 100644
--- a/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/submission/task/SubmissionTaskTest.kt
+++ b/Corona-Warn-App/src/test/java/de/rki/coronawarnapp/submission/task/SubmissionTaskTest.kt
@@ -115,7 +115,7 @@ class SubmissionTaskTest : BaseTest() {
         every { timeStamper.nowUTC } returns Instant.EPOCH.plus(Duration.standardHours(1))
 
         every { checkInRepository.allCheckIns } returns flowOf(emptyList())
-        every { checkInRepository.clear() } just Runs
+        coEvery { checkInRepository.clear() } just Runs
         every { checkInsTransformer.transform(any()) } returns emptyList()
     }