diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 64e87db574fa38013b822565221a91c122f718f0..e9c44110caa5304ff18326f5611ac6ad4cc06a34 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -31,8 +31,6 @@ android {
 
   buildTypes {
     getByName("release") {
-      isMinifyEnabled = true
-      isShrinkResources = true
 
       proguardFiles(
         getDefaultProguardFile("proguard-android.txt"),
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/di/DatabaseModule.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/di/DatabaseModule.kt
index c531e4c8ef1ef2fc291038aab8ba21e8c54ee72c..fc44d7da169b16b73cda524d0d04e4e4e9ca2a0c 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/di/DatabaseModule.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/di/DatabaseModule.kt
@@ -35,6 +35,7 @@ import de.chaosdorf.mete.model.MeteApiFactory
 import de.chaosdorf.mete.v1.MeteApiV1Factory
 import de.chaosdorf.meteroid.MeteroidDatabase
 import de.chaosdorf.meteroid.model.DrinkRepository
+import de.chaosdorf.meteroid.model.PinnedUserRepository
 import de.chaosdorf.meteroid.model.ServerRepository
 import de.chaosdorf.meteroid.model.TransactionRepository
 import de.chaosdorf.meteroid.model.UserRepository
@@ -62,6 +63,11 @@ object DatabaseModule {
     database: MeteroidDatabase
   ): UserRepository = database.users()
 
+  @Provides
+  fun providePinnedUserRepository(
+    database: MeteroidDatabase
+  ): PinnedUserRepository = database.pinnedUsers()
+
   @Provides
   fun provideTransactionRepository(
     database: MeteroidDatabase
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/sync/AccountProvider.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/sync/AccountProvider.kt
index 1fd925951ff0c5ddee10c012bb3dc2b72fd419d3..66c5b7311559271812d079b656dacc1bd8c0973b 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/sync/AccountProvider.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/sync/AccountProvider.kt
@@ -24,20 +24,25 @@
 
 package de.chaosdorf.meteroid.sync
 
+import de.chaosdorf.mete.model.UserId
 import de.chaosdorf.meteroid.model.AccountInfo
+import de.chaosdorf.meteroid.model.PinnedUser
+import de.chaosdorf.meteroid.model.PinnedUserRepository
+import de.chaosdorf.meteroid.model.ServerId
 import de.chaosdorf.meteroid.model.ServerRepository
 import de.chaosdorf.meteroid.model.UserRepository
 import de.chaosdorf.meteroid.storage.AccountPreferences
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.flow.mapLatest
 import javax.inject.Inject
 
 class AccountProvider @Inject constructor(
   accountPreferences: AccountPreferences,
   serverRepository: ServerRepository,
   userRepository: UserRepository,
+  private val pinnedUserRepository: PinnedUserRepository,
 ) {
   val account: Flow<AccountInfo?> =
     accountPreferences.state.flatMapLatest { preferences ->
@@ -48,12 +53,24 @@ class AccountProvider @Inject constructor(
           if (server == null) {
             flowOf(null)
           } else if (preferences.user == null) {
-            flowOf(AccountInfo(server, null))
+            flowOf(AccountInfo(server, null, false))
           } else {
-            userRepository.getFlow(server.serverId, preferences.user)
-              .mapLatest { user -> AccountInfo(server, user) }
+            combine(
+              userRepository.getFlow(server.serverId, preferences.user),
+              pinnedUserRepository.isPinnedFlow(server.serverId, preferences.user)
+            ) { user, pinned ->
+              AccountInfo(server, user, pinned)
+            }
           }
         }
       }
     }
+
+  suspend fun togglePin(serverId: ServerId, userId: UserId) {
+    if (pinnedUserRepository.isPinned(serverId, userId)) {
+      pinnedUserRepository.delete(serverId, userId)
+    } else {
+      pinnedUserRepository.save(PinnedUser(serverId, userId))
+    }
+  }
 }
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/sync/SyncHandler.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/sync/SyncHandler.kt
index 6bce3403a0f01c15166d0b1f67a99ecd70bccf4b..b7a61994adc21e850d8dc80cc570fe74de637ba6 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/sync/SyncHandler.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/sync/SyncHandler.kt
@@ -73,6 +73,7 @@ abstract class SyncHandler<Context, Entry, Key> {
           val loadedKeys = loadedEntries.map(::entryToKey).toSet()
           val removedKeys = storedKeys - loadedKeys
           for (removedKey in removedKeys) {
+            Log.e("SyncHandler", "deleting: $removedKey")
             delete(removedKey)
           }
           for (loadedEntry in loadedEntries) {
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/SyncManager.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/sync/SyncManager.kt
similarity index 93%
rename from app/src/main/kotlin/de/chaosdorf/meteroid/ui/SyncManager.kt
rename to app/src/main/kotlin/de/chaosdorf/meteroid/sync/SyncManager.kt
index 48276de223b25a2930a5d95c7a7185162f1e249d..cda175bb6c75bb5d0e04c16f26d472e2bc95b341 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/SyncManager.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/sync/SyncManager.kt
@@ -22,16 +22,13 @@
  * THE SOFTWARE.
  */
 
-package de.chaosdorf.meteroid.ui
+package de.chaosdorf.meteroid.sync
 
 import de.chaosdorf.mete.model.MeteApiFactory
 import de.chaosdorf.meteroid.model.AccountInfo
 import de.chaosdorf.meteroid.model.Drink
 import de.chaosdorf.meteroid.model.Server
 import de.chaosdorf.meteroid.model.User
-import de.chaosdorf.meteroid.sync.DrinkSyncHandler
-import de.chaosdorf.meteroid.sync.TransactionSyncHandler
-import de.chaosdorf.meteroid.sync.UserSyncHandler
 import java.math.BigDecimal
 import javax.inject.Inject
 
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/AppRouter.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/AppRouter.kt
index 6b2e6540131ebd72501e8060defaa00c878ef57b..f7237af875345c6e1c6bb1e58c2d3e5207e6e2cc 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/AppRouter.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/AppRouter.kt
@@ -116,6 +116,8 @@ fun AppRouter(viewModel: AppViewModel = viewModel()) {
       composable(Routes.Servers.Add) { _ ->
         AddServerScreen(
           hiltViewModel(),
+          isFirst = initState == AppViewModel.InitState.CREATE_SERVER,
+          onBack = { navController.navigate(Routes.Servers.List) },
           onAdd = { navController.navigate(Routes.Servers.List) }
         )
       }
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/AppViewModel.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/AppViewModel.kt
index 751902f50c52a6588f40ba9236367a68a61bebd5..853744c36968967346db957c350110449dc7b3c9 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/AppViewModel.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/AppViewModel.kt
@@ -33,9 +33,7 @@ import de.chaosdorf.meteroid.model.ServerId
 import de.chaosdorf.meteroid.model.ServerRepository
 import de.chaosdorf.meteroid.storage.AccountPreferences
 import de.chaosdorf.meteroid.sync.AccountProvider
-import de.chaosdorf.meteroid.sync.DrinkSyncHandler
-import de.chaosdorf.meteroid.sync.TransactionSyncHandler
-import de.chaosdorf.meteroid.sync.UserSyncHandler
+import de.chaosdorf.meteroid.sync.SyncManager
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.distinctUntilChanged
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/drinks/DrinkListScreen.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/drinks/DrinkListScreen.kt
index b872aef201dbb3264ce068cb1b82c92d86c360ac..b69910067205b42baad8237a68506e47ad05a325 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/drinks/DrinkListScreen.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/drinks/DrinkListScreen.kt
@@ -37,12 +37,14 @@ import androidx.compose.material3.Scaffold
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.collectAsState
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.unit.dp
 import androidx.navigation.NavOptions
 import de.chaosdorf.meteroid.ui.navigation.HomeSections
 import de.chaosdorf.meteroid.ui.navigation.MeteroidBottomBar
 import de.chaosdorf.meteroid.ui.navigation.MeteroidTopBar
+import de.chaosdorf.meteroid.ui.navigation.Routes
 
 @OptIn(ExperimentalLayoutApi::class)
 @Composable
@@ -50,12 +52,20 @@ fun DrinkListScreen(
   viewModel: DrinkListViewModel,
   onNavigate: (String, NavOptions) -> Unit
 ) {
+  val onBack = remember {
+    {
+      onNavigate(
+        Routes.Users.List,
+        NavOptions.Builder().setPopUpTo(Routes.Users.List, false).build()
+      )
+    }
+  }
   val account by viewModel.account.collectAsState()
   val drinks by viewModel.drinks.collectAsState()
   val filters by viewModel.filters.collectAsState()
 
   Scaffold(
-    topBar = { MeteroidTopBar(account, onNavigate) },
+    topBar = { MeteroidTopBar(account, onNavigate, viewModel::togglePin) },
     bottomBar = {
       MeteroidBottomBar(
         currentRoute = HomeSections.PURCHASE,
@@ -85,7 +95,7 @@ fun DrinkListScreen(
         modifier = Modifier.padding(horizontal = 8.dp)
       ) {
         items(drinks) { drink ->
-          DrinkTile(drink, viewModel::purchase)
+          DrinkTile(drink) { viewModel.purchase(it, onBack) }
         }
       }
     }
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/drinks/DrinkListViewModel.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/drinks/DrinkListViewModel.kt
index 045d3757633f910dcec4f91aa6ae76b29371e698..162323de9ad50bf1c953685aa13fe66a21eb9952 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/drinks/DrinkListViewModel.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/drinks/DrinkListViewModel.kt
@@ -32,7 +32,7 @@ import de.chaosdorf.meteroid.model.AccountInfo
 import de.chaosdorf.meteroid.model.Drink
 import de.chaosdorf.meteroid.model.DrinkRepository
 import de.chaosdorf.meteroid.sync.AccountProvider
-import de.chaosdorf.meteroid.ui.SyncManager
+import de.chaosdorf.meteroid.sync.SyncManager
 import de.chaosdorf.meteroid.util.update
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
@@ -45,7 +45,7 @@ import javax.inject.Inject
 
 @HiltViewModel
 class DrinkListViewModel @Inject constructor(
-  accountProvider: AccountProvider,
+  private val accountProvider: AccountProvider,
   repository: DrinkRepository,
   private val syncManager: SyncManager,
   private val savedStateHandle: SavedStateHandle
@@ -76,10 +76,23 @@ class DrinkListViewModel @Inject constructor(
     }
   }
 
-  fun purchase(item: Drink) {
+  fun purchase(item: Drink, onBack: () -> Unit) {
     account.value?.let { account ->
       viewModelScope.launch {
         syncManager.purchase(account, item)
+        if (!account.pinned) {
+          onBack()
+        }
+      }
+    }
+  }
+
+  fun togglePin() {
+    account.value?.let { account ->
+      account.user?.let { user ->
+        viewModelScope.launch {
+          accountProvider.togglePin(account.server.serverId, user.userId)
+        }
       }
     }
   }
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/money/MoneyListScreen.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/money/MoneyListScreen.kt
index 78b8d667b6ae4abe6dc5577ea427d696e9eec2fb..42d4837b4001f1988f1d62b04fae51da67365397 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/money/MoneyListScreen.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/money/MoneyListScreen.kt
@@ -35,22 +35,32 @@ import androidx.compose.material3.Scaffold
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.collectAsState
 import androidx.compose.runtime.getValue
+import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.unit.dp
 import androidx.navigation.NavOptions
 import de.chaosdorf.meteroid.ui.navigation.HomeSections
 import de.chaosdorf.meteroid.ui.navigation.MeteroidBottomBar
 import de.chaosdorf.meteroid.ui.navigation.MeteroidTopBar
+import de.chaosdorf.meteroid.ui.navigation.Routes
 
 @Composable
 fun MoneyListScreen(
   viewModel: MoneyListViewModel,
   onNavigate: (String, NavOptions) -> Unit
 ) {
+  val onBack = remember {
+    {
+      onNavigate(
+        Routes.Users.List,
+        NavOptions.Builder().setPopUpTo(Routes.Users.List, false).build()
+      )
+    }
+  }
   val account by viewModel.account.collectAsState()
 
   Scaffold(
-    topBar = { MeteroidTopBar(account, onNavigate) },
+    topBar = { MeteroidTopBar(account, onNavigate, viewModel::togglePin) },
     bottomBar = {
       MeteroidBottomBar(
         currentRoute = HomeSections.DEPOSIT,
@@ -67,7 +77,7 @@ fun MoneyListScreen(
         horizontalArrangement = Arrangement.SpaceBetween,
       ) {
         items(viewModel.money) { monetaryAmount ->
-          MoneyTile(monetaryAmount, viewModel::deposit)
+          MoneyTile(monetaryAmount) { viewModel.deposit(it, onBack) }
         }
       }
     }
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/money/MoneyListViewModel.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/money/MoneyListViewModel.kt
index 7ba2e82985c2c5dd2dbf348d2263fcca492ca4c5..b568029242142dda2ad81ff71133ea290ab16c2f 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/money/MoneyListViewModel.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/money/MoneyListViewModel.kt
@@ -28,11 +28,10 @@ import androidx.annotation.DrawableRes
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
 import dagger.hilt.android.lifecycle.HiltViewModel
-import de.chaosdorf.mete.model.MeteApiFactory
 import de.chaosdorf.meteroid.R
 import de.chaosdorf.meteroid.model.AccountInfo
 import de.chaosdorf.meteroid.sync.AccountProvider
-import de.chaosdorf.meteroid.ui.SyncManager
+import de.chaosdorf.meteroid.sync.SyncManager
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.stateIn
@@ -52,7 +51,7 @@ enum class MonetaryAmount(val amount: BigDecimal, @DrawableRes val image: Int) {
 
 @HiltViewModel
 class MoneyListViewModel @Inject constructor(
-  accountProvider: AccountProvider,
+  private val accountProvider: AccountProvider,
   private val syncManager: SyncManager
 ) : ViewModel() {
   val account: StateFlow<AccountInfo?> = accountProvider.account
@@ -60,10 +59,23 @@ class MoneyListViewModel @Inject constructor(
 
   val money: List<MonetaryAmount> = MonetaryAmount.entries
 
-  fun deposit(item: MonetaryAmount) {
+  fun deposit(item: MonetaryAmount, onBack: () -> Unit) {
     account.value?.let { account ->
       viewModelScope.launch {
         syncManager.deposit(account, item.amount)
+        if (!account.pinned) {
+          onBack()
+        }
+      }
+    }
+  }
+
+  fun togglePin() {
+    account.value?.let { account ->
+      account.user?.let { user ->
+        viewModelScope.launch {
+          accountProvider.togglePin(account.server.serverId, user.userId)
+        }
       }
     }
   }
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/navigation/MeteroidTopBar.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/navigation/MeteroidTopBar.kt
index 3a5d95e85a3da122ca99cf6b4287be9c20cd99ba..5cc575b87cb1c33b52c0d42a6e544d277cdf2cfb 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/navigation/MeteroidTopBar.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/navigation/MeteroidTopBar.kt
@@ -33,6 +33,12 @@ import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.shape.CircleShape
 import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.PushPin
+import androidx.compose.material.icons.outlined.PushPin
+import androidx.compose.material.icons.twotone.PushPin
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Surface
 import androidx.compose.material3.Text
@@ -53,7 +59,8 @@ import okhttp3.internal.toCanonicalHost
 @Composable
 fun MeteroidTopBar(
   account: AccountInfo?,
-  onNavigate: (String, NavOptions) -> Unit
+  onNavigate: (String, NavOptions) -> Unit,
+  onTogglePin: () -> Unit,
 ) {
   Surface(
     modifier = Modifier.padding(8.dp),
@@ -67,7 +74,7 @@ fun MeteroidTopBar(
   ) {
     Row(modifier = Modifier.padding(8.dp)) {
       AsyncImage(
-        account?.user?.gravatarUrl(),
+        account?.user?.gravatarUrl,
         contentDescription = "User List",
         contentScale = ContentScale.Crop,
         modifier = Modifier
@@ -105,6 +112,14 @@ fun MeteroidTopBar(
         Modifier
           .weight(1.0f)
           .width(16.dp))
+      IconButton(onClick = onTogglePin) {
+        Icon(
+          if (account?.pinned == true) Icons.Filled.PushPin
+          else Icons.Outlined.PushPin,
+          contentDescription = null
+        )
+      }
+      Spacer(Modifier.width(8.dp))
       account?.user?.let { user ->
         PriceBadge(
           user.balance,
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/servers/AddServerScreen.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/servers/AddServerScreen.kt
index be30261b9bb53f15c2c4ed953a5626945083ad51..1860019658ec6730255b3fe66339b5d1a19f67c7 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/servers/AddServerScreen.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/servers/AddServerScreen.kt
@@ -24,47 +24,141 @@
 
 package de.chaosdorf.meteroid.ui.servers
 
+import androidx.compose.foundation.Image
 import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.automirrored.filled.ArrowBack
+import androidx.compose.material.icons.filled.Add
 import androidx.compose.material3.Button
+import androidx.compose.material3.Card
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Surface
 import androidx.compose.material3.Text
 import androidx.compose.material3.TextField
+import androidx.compose.material3.TopAppBar
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.collectAsState
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.shadow
+import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.unit.dp
 import androidx.lifecycle.viewmodel.compose.viewModel
 import coil.compose.AsyncImage
+import de.chaosdorf.meteroid.R
 import kotlinx.coroutines.launch
+import okhttp3.HttpUrl.Companion.toHttpUrl
 
 @Composable
 fun AddServerScreen(
   viewModel: AddServerViewModel = viewModel(),
+  isFirst: Boolean = false,
+  onBack: () -> Unit = {},
   onAdd: () -> Unit = {}
 ) {
   val scope = rememberCoroutineScope()
   val url by viewModel.url.collectAsState()
   val server by viewModel.server.collectAsState()
 
-  Column {
-    TextField(
-      label = { Text("Server URL") },
-      value = url,
-      onValueChange = { viewModel.url.value = it }
-    )
+  Scaffold(
+    topBar = {
+      TopAppBar(
+        title = {
+          Row {
+            Image(
+              painterResource(R.mipmap.ic_launcher),
+              contentDescription = null,
+              contentScale = ContentScale.Crop,
+              modifier = Modifier.size(48.dp)
+            )
+            Spacer(Modifier.width(16.dp))
+            Column(modifier = Modifier.align(Alignment.CenterVertically)) {
+              Text(
+                "Meteroid",
+                fontWeight = FontWeight.SemiBold,
+                style = MaterialTheme.typography.bodyMedium
+              )
+            }
+          }
+        },
+        navigationIcon = {
+          if (!isFirst) {
+            IconButton(onClick = { onBack() }) {
+              Icon(Icons.AutoMirrored.Default.ArrowBack, contentDescription = null)
+            }
+          }
+        },
+        modifier = Modifier.shadow(4.dp)
+      )
+    },
+  ) { paddingValues ->
+    Column(
+      Modifier
+        .padding(paddingValues)
+        .padding(16.dp, 8.dp)) {
+      TextField(
+        label = { Text("Server URL") },
+        value = url,
+        onValueChange = { viewModel.url.value = it },
+        modifier = Modifier.fillMaxWidth()
+      )
 
-    Button(onClick = {
-      scope.launch {
-        viewModel.addServer()
-        onAdd()
-      }
-    }) {
-      Text("Add Server")
-    }
+      server?.let { server ->
+        Card(
+          modifier = Modifier.padding(vertical = 8.dp)
+        ) {
+          Row(modifier = Modifier.padding(16.dp, 8.dp)) {
+            AsyncImage(
+              server.logoUrl,
+              contentDescription = null,
+              contentScale = ContentScale.Crop,
+              modifier = Modifier.size(48.dp)
+            )
+            Spacer(Modifier.width(16.dp))
+            Column(modifier = Modifier.align(Alignment.CenterVertically)) {
+              Text(
+                server.name!!,
+                fontWeight = FontWeight.SemiBold,
+                style = MaterialTheme.typography.bodyMedium
+              )
+              Text(
+                server.url.toHttpUrl().host,
+                color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.67f),
+                fontWeight = FontWeight.Medium,
+                style = MaterialTheme.typography.bodyMedium
+              )
+            }
 
-    server?.let { server ->
-      Text(server.url)
-      Text(server.name ?: "null1")
-      AsyncImage(model = server.logoUrl, contentDescription = null)
+            Spacer(
+              Modifier
+                .width(16.dp)
+                .weight(1.0f))
+
+            IconButton(onClick = {
+              scope.launch {
+                viewModel.addServer()
+                onAdd()
+              }
+            }) {
+              Icon(Icons.Default.Add, contentDescription = "Add Server")
+            }
+          }
+        }
+      }
     }
   }
 }
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/servers/ServerListScreen.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/servers/ServerListScreen.kt
index ff0c99bb0f4780eef72be228c453163238036b59..937756bf4e3e9d43cc9f02a10555a1f294928bb3 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/servers/ServerListScreen.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/servers/ServerListScreen.kt
@@ -24,24 +24,37 @@
 
 package de.chaosdorf.meteroid.ui.servers
 
+import androidx.compose.foundation.Image
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.lazy.LazyColumn
 import androidx.compose.foundation.lazy.items
 import androidx.compose.material3.ListItem
+import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Scaffold
 import androidx.compose.material3.Text
 import androidx.compose.material3.TopAppBar
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.collectAsState
 import androidx.compose.runtime.getValue
+import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.shadow
+import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.font.FontWeight
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import androidx.lifecycle.viewmodel.compose.viewModel
+import coil.compose.AsyncImage
+import de.chaosdorf.meteroid.R
 import de.chaosdorf.meteroid.model.ServerId
+import okhttp3.HttpUrl.Companion.toHttpUrl
 
 @Preview
 @Composable
@@ -55,7 +68,24 @@ fun ServerListScreen(
   Scaffold(
     topBar = {
       TopAppBar(
-        title = { Text("Meteroid") },
+        title = {
+          Row {
+            Image(
+              painterResource(R.mipmap.ic_launcher),
+              contentDescription = null,
+              contentScale = ContentScale.Crop,
+              modifier = Modifier.size(48.dp)
+            )
+            Spacer(Modifier.width(16.dp))
+            Column(modifier = Modifier.align(Alignment.CenterVertically)) {
+              Text(
+                "Meteroid",
+                fontWeight = FontWeight.SemiBold,
+                style = MaterialTheme.typography.bodyMedium
+              )
+            }
+          }
+        },
         modifier = Modifier.shadow(4.dp)
       )
     }
@@ -65,7 +95,15 @@ fun ServerListScreen(
         items(servers) { server ->
           ListItem(
             headlineContent = { Text(server.name ?: server.url) },
-            supportingContent = { if (server.name != null) Text(server.url) },
+            supportingContent = { if (server.name != null) Text(server.url.toHttpUrl().host) },
+            leadingContent = {
+              AsyncImage(
+                server.logoUrl,
+                contentDescription = null,
+                contentScale = ContentScale.Crop,
+                modifier = Modifier.size(48.dp)
+              )
+            },
             modifier = Modifier.clickable { onSelect(server.serverId) }
           )
         }
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/transactions/PurchaseListScreen.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/transactions/PurchaseListScreen.kt
index d6ceedbf2aa979303fb700761e513fc192a9a620..73ecb0ce9a7c36ca9226b4174b5db88e00493b52 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/transactions/PurchaseListScreen.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/transactions/PurchaseListScreen.kt
@@ -49,7 +49,7 @@ fun TransactionListScreen(
   val transactions by viewModel.transactions.collectAsState()
 
   Scaffold(
-    topBar = { MeteroidTopBar(account, onNavigate) },
+    topBar = { MeteroidTopBar(account, onNavigate, viewModel::togglePin) },
     bottomBar = {
       MeteroidBottomBar(
         currentRoute = HomeSections.HISTORY,
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/transactions/PurchaseViewModel.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/transactions/PurchaseViewModel.kt
index 8c053ee161ae6d11ec671834086164a549df2494..14a88535bcabeb3d6077289754cca962ae539b57 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/transactions/PurchaseViewModel.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/transactions/PurchaseViewModel.kt
@@ -40,13 +40,14 @@ import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.mapLatest
 import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.launch
 import java.math.BigDecimal
 import javax.inject.Inject
 import kotlin.time.Duration.Companion.minutes
 
 @HiltViewModel
 class TransactionViewModel @Inject constructor(
-  accountProvider: AccountProvider,
+  private val accountProvider: AccountProvider,
   repository: TransactionRepository,
   drinkRepository: DrinkRepository
 ) : ViewModel() {
@@ -74,6 +75,16 @@ class TransactionViewModel @Inject constructor(
       list.mergeAdjecentDeposits()
         .filter { it.drink != null || it.transaction.difference != BigDecimal.ZERO }
     }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList())
+
+  fun togglePin() {
+    account.value?.let { account ->
+      account.user?.let { user ->
+        viewModelScope.launch {
+          accountProvider.togglePin(account.server.serverId, user.userId)
+        }
+      }
+    }
+  }
 }
 
 fun List<TransactionInfo>.mergeAdjecentDeposits(): List<TransactionInfo> {
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/users/UserListScreen.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/users/UserListScreen.kt
index a6890ee323a8d65496333ce696ced87a530c2699..56aba29775041f6cfe124db213461a2715af9ce5 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/users/UserListScreen.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/users/UserListScreen.kt
@@ -24,15 +24,21 @@
 
 package de.chaosdorf.meteroid.ui.users
 
-import androidx.compose.foundation.background
-import androidx.compose.foundation.border
 import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.foundation.lazy.items
-import androidx.compose.foundation.shape.CircleShape
-import androidx.compose.material3.ListItem
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.lazy.grid.GridCells
+import androidx.compose.foundation.lazy.grid.GridItemSpan
+import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
+import androidx.compose.foundation.lazy.grid.items
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.automirrored.filled.ArrowBack
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Scaffold
 import androidx.compose.material3.Text
@@ -40,14 +46,16 @@ import androidx.compose.material3.TopAppBar
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.collectAsState
 import androidx.compose.runtime.getValue
+import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clip
 import androidx.compose.ui.draw.shadow
-import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.font.FontWeight
 import androidx.compose.ui.unit.dp
 import coil.compose.AsyncImage
 import de.chaosdorf.mete.model.UserId
+import okhttp3.HttpUrl.Companion.toHttpUrl
 
 @Composable
 fun UserListScreen(
@@ -58,27 +66,55 @@ fun UserListScreen(
 ) {
   val server by viewModel.account.collectAsState()
   val users by viewModel.users.collectAsState()
+  val pinnedUsers by viewModel.pinnedUsers.collectAsState()
 
   Scaffold(
     topBar = {
       TopAppBar(
         title = {
-          Text(
-            server?.server?.name
-              ?: "Meteroid"
-          )
+          Row {
+            AsyncImage(
+              server?.server?.logoUrl,
+              contentDescription = null,
+              contentScale = ContentScale.Crop,
+              modifier = Modifier.size(48.dp)
+            )
+            Spacer(Modifier.width(16.dp))
+            Column(modifier = Modifier.align(Alignment.CenterVertically)) {
+              if (server?.server != null) {
+                if (server?.server?.name != null) {
+                  Text(
+                    server!!.server.name!!,
+                    fontWeight = FontWeight.SemiBold,
+                    style = MaterialTheme.typography.bodyMedium
+                  )
+                  Text(
+                    server!!.server.url.toHttpUrl().host,
+                    color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.67f),
+                    fontWeight = FontWeight.Medium,
+                    style = MaterialTheme.typography.bodyMedium
+                  )
+                } else {
+                  Text(
+                    server!!.server.url,
+                    fontWeight = FontWeight.SemiBold,
+                    style = MaterialTheme.typography.bodyMedium
+                  )
+                }
+              } else {
+                Text(
+                  "Meteroid",
+                  fontWeight = FontWeight.SemiBold,
+                  style = MaterialTheme.typography.bodyMedium
+                )
+              }
+            }
+          }
         },
         navigationIcon = {
-          AsyncImage(
-            server?.server?.logoUrl,
-            contentDescription = "User List",
-            contentScale = ContentScale.Crop,
-            modifier = Modifier
-              .size(48.dp)
-              .clip(CircleShape)
-              .border(1.dp, Color.White, CircleShape)
-              .background(MaterialTheme.colorScheme.primaryContainer)
-          )
+          IconButton(onClick = { onBack() }) {
+            Icon(Icons.AutoMirrored.Default.ArrowBack, contentDescription = null)
+          }
         },
         modifier = Modifier
           .shadow(4.dp)
@@ -86,19 +122,40 @@ fun UserListScreen(
       )
     }
   ) { paddingValues ->
-    LazyColumn(modifier = Modifier.padding(paddingValues)) {
-      items(users) { user ->
-        ListItem(
-          headlineContent = { Text(user.name) },
-          supportingContent = { Text(user.email) },
-          modifier = Modifier.clickable { onSelect(user.userId) }
-        )
+    LazyVerticalGrid(
+      GridCells.Adaptive(80.dp),
+      modifier = Modifier.padding(horizontal = 8.dp),
+      contentPadding = paddingValues
+    ) {
+      if (pinnedUsers.isNotEmpty()) {
+        item("pinned", span = { GridItemSpan(maxLineSpan) }) {
+          Text(
+            "Pinned",
+            style = MaterialTheme.typography.labelMedium,
+            modifier = Modifier.padding(start = 8.dp, end = 8.dp, top = 16.dp, bottom = 4.dp)
+          )
+        }
+
+        items(pinnedUsers) { user ->
+          UserTile(user, onSelect)
+        }
       }
-      item {
-        ListItem(
-          headlineContent = { Text("Add User") },
-          modifier = Modifier.clickable { onAdd() }
-        )
+
+      for (character in 'A'..'Z') {
+        val group = users.filter { it.name.startsWith(character, ignoreCase = true) }
+        if (group.isNotEmpty()) {
+          item(character.toString(), span = { GridItemSpan(maxLineSpan) }) {
+            Text(
+              "$character",
+              style = MaterialTheme.typography.labelMedium,
+              modifier = Modifier.padding(start = 8.dp, end = 8.dp, top = 16.dp, bottom = 4.dp)
+            )
+          }
+
+          items(group) { user ->
+            UserTile(user, onSelect)
+          }
+        }
       }
     }
   }
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/users/UserListViewModel.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/users/UserListViewModel.kt
index 74029fd8617672231a6a33a36615c34b30941317..112dfe646c361dd20a9533e5505c2e3c2ced251b 100644
--- a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/users/UserListViewModel.kt
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/users/UserListViewModel.kt
@@ -28,21 +28,26 @@ import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
 import dagger.hilt.android.lifecycle.HiltViewModel
 import de.chaosdorf.meteroid.model.AccountInfo
+import de.chaosdorf.meteroid.model.PinnedUserRepository
+import de.chaosdorf.meteroid.model.ServerId
 import de.chaosdorf.meteroid.model.User
 import de.chaosdorf.meteroid.model.UserRepository
 import de.chaosdorf.meteroid.sync.AccountProvider
 import de.chaosdorf.meteroid.sync.UserSyncHandler
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.flow.mapLatest
 import kotlinx.coroutines.flow.stateIn
 import javax.inject.Inject
 
 @HiltViewModel
 class UserListViewModel @Inject constructor(
   accountProvider: AccountProvider,
-  repository: UserRepository
+  userRepository: UserRepository,
+  pinnedUserRepository: PinnedUserRepository,
 ) : ViewModel() {
   val account: StateFlow<AccountInfo?> = accountProvider.account
     .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
@@ -50,7 +55,19 @@ class UserListViewModel @Inject constructor(
   val users: StateFlow<List<User>> = accountProvider.account
     .flatMapLatest { account ->
       account?.let { (server, _) ->
-        repository.getAllFlow(server.serverId)
+        userRepository.getAllFlow(server.serverId)
+      } ?: flowOf(emptyList())
+    }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList())
+
+  val pinnedUsers = accountProvider.account
+    .flatMapLatest { account ->
+      account?.let { (server, _) ->
+        combine(
+          userRepository.getAllFlow(server.serverId),
+          pinnedUserRepository.getAllFlow(server.serverId)
+        ) { users, pinned ->
+          users.filter { pinned.contains(it.userId) }
+        }
       } ?: flowOf(emptyList())
     }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList())
 }
diff --git a/app/src/main/kotlin/de/chaosdorf/meteroid/ui/users/UserTile.kt b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/users/UserTile.kt
new file mode 100644
index 0000000000000000000000000000000000000000..16a5f7ca550009d8661bf584636f5532c362da8f
--- /dev/null
+++ b/app/src/main/kotlin/de/chaosdorf/meteroid/ui/users/UserTile.kt
@@ -0,0 +1,102 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013-2023 Chaosdorf e.V.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package de.chaosdorf.meteroid.ui.users
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.IntrinsicSize
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.aspectRatio
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.paddingFromBaseline
+import androidx.compose.foundation.shape.CircleShape
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.alpha
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.PreviewParameter
+import androidx.compose.ui.unit.dp
+import coil.compose.rememberAsyncImagePainter
+import de.chaosdorf.mete.model.UserId
+import de.chaosdorf.meteroid.model.Drink
+import de.chaosdorf.meteroid.model.User
+import de.chaosdorf.meteroid.sample.SampleDrinkProvider
+import de.chaosdorf.meteroid.ui.PriceBadge
+
+@Composable
+fun UserTile(
+  item: User,
+  onSelect: (UserId) -> Unit = {}
+) {
+  val avatarPainter = rememberAsyncImagePainter(
+    item.gravatarUrl
+  )
+
+  Column(
+    modifier = Modifier
+      .height(IntrinsicSize.Max)
+      .alpha(if (item.active) 1.0f else 0.67f)
+      .clip(RoundedCornerShape(8.dp))
+      .clickable { onSelect(item.userId) }
+      .padding(8.dp)
+  ) {
+    Box {
+      Image(
+        avatarPainter,
+        contentDescription = null,
+        contentScale = ContentScale.Fit,
+        modifier = Modifier
+          .aspectRatio(1.0f)
+          .clip(CircleShape)
+          .background(MaterialTheme.colorScheme.primaryContainer)
+      )
+    }
+    Spacer(Modifier.height(4.dp))
+    Text(
+      item.name,
+      modifier = Modifier
+        .fillMaxWidth()
+        .padding(horizontal = 8.dp),
+      textAlign = TextAlign.Center,
+      fontWeight = FontWeight.SemiBold,
+      style = MaterialTheme.typography.labelLarge,
+    )
+  }
+}
diff --git a/persistence/room/schemas/de.chaosdorf.meteroid.MeteroidDatabase/1.json b/persistence/room/schemas/de.chaosdorf.meteroid.MeteroidDatabase/1.json
index 9efb6d66778c527a3cf0e91a61123aa799eca474..315971c57694c8ba40ca571ae15663f067952a65 100644
--- a/persistence/room/schemas/de.chaosdorf.meteroid.MeteroidDatabase/1.json
+++ b/persistence/room/schemas/de.chaosdorf.meteroid.MeteroidDatabase/1.json
@@ -2,11 +2,11 @@
   "formatVersion": 1,
   "database": {
     "version": 1,
-    "identityHash": "7aca7cdc33cbadb81643b32c5838f2a9",
+    "identityHash": "f794acceadd9ed28da1b218972b5e530",
     "entities": [
       {
         "tableName": "Drink",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` INTEGER NOT NULL, `drinkId` INTEGER NOT NULL, `active` INTEGER NOT NULL, `name` TEXT NOT NULL, `volume` TEXT NOT NULL, `caffeine` INTEGER, `price` TEXT NOT NULL, `logoUrl` TEXT NOT NULL, PRIMARY KEY(`serverId`, `drinkId`), FOREIGN KEY(`serverId`) REFERENCES `Server`(`serverId`) ON UPDATE NO ACTION ON DELETE CASCADE )",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` INTEGER NOT NULL, `drinkId` INTEGER NOT NULL, `active` INTEGER NOT NULL, `name` TEXT NOT NULL, `volume` TEXT NOT NULL, `caffeine` INTEGER, `price` TEXT NOT NULL, `logoUrl` TEXT NOT NULL, PRIMARY KEY(`serverId`, `drinkId`), FOREIGN KEY(`serverId`) REFERENCES `Server`(`serverId`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
         "fields": [
           {
             "fieldPath": "serverId",
@@ -68,7 +68,7 @@
         "foreignKeys": [
           {
             "table": "Server",
-            "onDelete": "CASCADE",
+            "onDelete": "NO ACTION",
             "onUpdate": "NO ACTION",
             "columns": [
               "serverId"
@@ -119,7 +119,7 @@
       },
       {
         "tableName": "User",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` INTEGER NOT NULL, `userId` INTEGER NOT NULL, `active` INTEGER NOT NULL, `name` TEXT NOT NULL, `email` TEXT NOT NULL, `balance` TEXT NOT NULL, `audit` INTEGER NOT NULL, `redirect` INTEGER NOT NULL, PRIMARY KEY(`serverId`, `userId`), FOREIGN KEY(`serverId`) REFERENCES `Server`(`serverId`) ON UPDATE NO ACTION ON DELETE CASCADE )",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` INTEGER NOT NULL, `userId` INTEGER NOT NULL, `active` INTEGER NOT NULL, `name` TEXT NOT NULL, `email` TEXT NOT NULL, `balance` TEXT NOT NULL, `audit` INTEGER NOT NULL, `redirect` INTEGER NOT NULL, PRIMARY KEY(`serverId`, `userId`), FOREIGN KEY(`serverId`) REFERENCES `Server`(`serverId`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
         "fields": [
           {
             "fieldPath": "serverId",
@@ -181,7 +181,46 @@
         "foreignKeys": [
           {
             "table": "Server",
-            "onDelete": "CASCADE",
+            "onDelete": "NO ACTION",
+            "onUpdate": "NO ACTION",
+            "columns": [
+              "serverId"
+            ],
+            "referencedColumns": [
+              "serverId"
+            ]
+          }
+        ]
+      },
+      {
+        "tableName": "PinnedUser",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` INTEGER NOT NULL, `userId` INTEGER NOT NULL, PRIMARY KEY(`serverId`, `userId`), FOREIGN KEY(`serverId`) REFERENCES `Server`(`serverId`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`serverId`, `userId`) REFERENCES `User`(`serverId`, `userId`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
+        "fields": [
+          {
+            "fieldPath": "serverId",
+            "columnName": "serverId",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "userId",
+            "columnName": "userId",
+            "affinity": "INTEGER",
+            "notNull": true
+          }
+        ],
+        "primaryKey": {
+          "autoGenerate": false,
+          "columnNames": [
+            "serverId",
+            "userId"
+          ]
+        },
+        "indices": [],
+        "foreignKeys": [
+          {
+            "table": "Server",
+            "onDelete": "NO ACTION",
             "onUpdate": "NO ACTION",
             "columns": [
               "serverId"
@@ -189,12 +228,25 @@
             "referencedColumns": [
               "serverId"
             ]
+          },
+          {
+            "table": "User",
+            "onDelete": "NO ACTION",
+            "onUpdate": "NO ACTION",
+            "columns": [
+              "serverId",
+              "userId"
+            ],
+            "referencedColumns": [
+              "serverId",
+              "userId"
+            ]
           }
         ]
       },
       {
         "tableName": "Transaction",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` INTEGER NOT NULL, `transactionId` INTEGER NOT NULL, `userId` INTEGER NOT NULL, `drinkId` INTEGER, `difference` TEXT NOT NULL, `timestamp` INTEGER NOT NULL, PRIMARY KEY(`serverId`, `transactionId`), FOREIGN KEY(`serverId`) REFERENCES `Server`(`serverId`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`serverId`, `userId`) REFERENCES `User`(`serverId`, `userId`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`serverId`, `drinkId`) REFERENCES `Drink`(`serverId`, `drinkId`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` INTEGER NOT NULL, `transactionId` INTEGER NOT NULL, `userId` INTEGER NOT NULL, `drinkId` INTEGER, `difference` TEXT NOT NULL, `timestamp` INTEGER NOT NULL, PRIMARY KEY(`serverId`, `transactionId`), FOREIGN KEY(`serverId`) REFERENCES `Server`(`serverId`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`serverId`, `userId`) REFERENCES `User`(`serverId`, `userId`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`serverId`, `drinkId`) REFERENCES `Drink`(`serverId`, `drinkId`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
         "fields": [
           {
             "fieldPath": "serverId",
@@ -265,7 +317,7 @@
         "foreignKeys": [
           {
             "table": "Server",
-            "onDelete": "CASCADE",
+            "onDelete": "NO ACTION",
             "onUpdate": "NO ACTION",
             "columns": [
               "serverId"
@@ -276,7 +328,7 @@
           },
           {
             "table": "User",
-            "onDelete": "CASCADE",
+            "onDelete": "NO ACTION",
             "onUpdate": "NO ACTION",
             "columns": [
               "serverId",
@@ -306,7 +358,7 @@
     "views": [],
     "setupQueries": [
       "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
-      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '7aca7cdc33cbadb81643b32c5838f2a9')"
+      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f794acceadd9ed28da1b218972b5e530')"
     ]
   }
 }
\ No newline at end of file
diff --git a/persistence/room/schemas/de.chaosdorf.meteroid.MeteroidDatabase/2.json b/persistence/room/schemas/de.chaosdorf.meteroid.MeteroidDatabase/2.json
new file mode 100644
index 0000000000000000000000000000000000000000..9432b0b4678b1451c484d27bc989754fb4b5c105
--- /dev/null
+++ b/persistence/room/schemas/de.chaosdorf.meteroid.MeteroidDatabase/2.json
@@ -0,0 +1,364 @@
+{
+  "formatVersion": 1,
+  "database": {
+    "version": 2,
+    "identityHash": "f794acceadd9ed28da1b218972b5e530",
+    "entities": [
+      {
+        "tableName": "Drink",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` INTEGER NOT NULL, `drinkId` INTEGER NOT NULL, `active` INTEGER NOT NULL, `name` TEXT NOT NULL, `volume` TEXT NOT NULL, `caffeine` INTEGER, `price` TEXT NOT NULL, `logoUrl` TEXT NOT NULL, PRIMARY KEY(`serverId`, `drinkId`), FOREIGN KEY(`serverId`) REFERENCES `Server`(`serverId`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
+        "fields": [
+          {
+            "fieldPath": "serverId",
+            "columnName": "serverId",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "drinkId",
+            "columnName": "drinkId",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "active",
+            "columnName": "active",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "name",
+            "columnName": "name",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "volume",
+            "columnName": "volume",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "caffeine",
+            "columnName": "caffeine",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "price",
+            "columnName": "price",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "logoUrl",
+            "columnName": "logoUrl",
+            "affinity": "TEXT",
+            "notNull": true
+          }
+        ],
+        "primaryKey": {
+          "autoGenerate": false,
+          "columnNames": [
+            "serverId",
+            "drinkId"
+          ]
+        },
+        "indices": [],
+        "foreignKeys": [
+          {
+            "table": "Server",
+            "onDelete": "NO ACTION",
+            "onUpdate": "NO ACTION",
+            "columns": [
+              "serverId"
+            ],
+            "referencedColumns": [
+              "serverId"
+            ]
+          }
+        ]
+      },
+      {
+        "tableName": "Server",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` INTEGER NOT NULL, `name` TEXT, `url` TEXT NOT NULL, `logoUrl` TEXT, PRIMARY KEY(`serverId`))",
+        "fields": [
+          {
+            "fieldPath": "serverId",
+            "columnName": "serverId",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "name",
+            "columnName": "name",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "url",
+            "columnName": "url",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "logoUrl",
+            "columnName": "logoUrl",
+            "affinity": "TEXT",
+            "notNull": false
+          }
+        ],
+        "primaryKey": {
+          "autoGenerate": false,
+          "columnNames": [
+            "serverId"
+          ]
+        },
+        "indices": [],
+        "foreignKeys": []
+      },
+      {
+        "tableName": "User",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` INTEGER NOT NULL, `userId` INTEGER NOT NULL, `active` INTEGER NOT NULL, `name` TEXT NOT NULL, `email` TEXT NOT NULL, `balance` TEXT NOT NULL, `audit` INTEGER NOT NULL, `redirect` INTEGER NOT NULL, PRIMARY KEY(`serverId`, `userId`), FOREIGN KEY(`serverId`) REFERENCES `Server`(`serverId`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
+        "fields": [
+          {
+            "fieldPath": "serverId",
+            "columnName": "serverId",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "userId",
+            "columnName": "userId",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "active",
+            "columnName": "active",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "name",
+            "columnName": "name",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "email",
+            "columnName": "email",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "balance",
+            "columnName": "balance",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "audit",
+            "columnName": "audit",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "redirect",
+            "columnName": "redirect",
+            "affinity": "INTEGER",
+            "notNull": true
+          }
+        ],
+        "primaryKey": {
+          "autoGenerate": false,
+          "columnNames": [
+            "serverId",
+            "userId"
+          ]
+        },
+        "indices": [],
+        "foreignKeys": [
+          {
+            "table": "Server",
+            "onDelete": "NO ACTION",
+            "onUpdate": "NO ACTION",
+            "columns": [
+              "serverId"
+            ],
+            "referencedColumns": [
+              "serverId"
+            ]
+          }
+        ]
+      },
+      {
+        "tableName": "PinnedUser",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` INTEGER NOT NULL, `userId` INTEGER NOT NULL, PRIMARY KEY(`serverId`, `userId`), FOREIGN KEY(`serverId`) REFERENCES `Server`(`serverId`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`serverId`, `userId`) REFERENCES `User`(`serverId`, `userId`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
+        "fields": [
+          {
+            "fieldPath": "serverId",
+            "columnName": "serverId",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "userId",
+            "columnName": "userId",
+            "affinity": "INTEGER",
+            "notNull": true
+          }
+        ],
+        "primaryKey": {
+          "autoGenerate": false,
+          "columnNames": [
+            "serverId",
+            "userId"
+          ]
+        },
+        "indices": [],
+        "foreignKeys": [
+          {
+            "table": "Server",
+            "onDelete": "NO ACTION",
+            "onUpdate": "NO ACTION",
+            "columns": [
+              "serverId"
+            ],
+            "referencedColumns": [
+              "serverId"
+            ]
+          },
+          {
+            "table": "User",
+            "onDelete": "NO ACTION",
+            "onUpdate": "NO ACTION",
+            "columns": [
+              "serverId",
+              "userId"
+            ],
+            "referencedColumns": [
+              "serverId",
+              "userId"
+            ]
+          }
+        ]
+      },
+      {
+        "tableName": "Transaction",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` INTEGER NOT NULL, `transactionId` INTEGER NOT NULL, `userId` INTEGER NOT NULL, `drinkId` INTEGER, `difference` TEXT NOT NULL, `timestamp` INTEGER NOT NULL, PRIMARY KEY(`serverId`, `transactionId`), FOREIGN KEY(`serverId`) REFERENCES `Server`(`serverId`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`serverId`, `userId`) REFERENCES `User`(`serverId`, `userId`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`serverId`, `drinkId`) REFERENCES `Drink`(`serverId`, `drinkId`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
+        "fields": [
+          {
+            "fieldPath": "serverId",
+            "columnName": "serverId",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "transactionId",
+            "columnName": "transactionId",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "userId",
+            "columnName": "userId",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "drinkId",
+            "columnName": "drinkId",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "difference",
+            "columnName": "difference",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "timestamp",
+            "columnName": "timestamp",
+            "affinity": "INTEGER",
+            "notNull": true
+          }
+        ],
+        "primaryKey": {
+          "autoGenerate": false,
+          "columnNames": [
+            "serverId",
+            "transactionId"
+          ]
+        },
+        "indices": [
+          {
+            "name": "index_Transaction_serverId_userId",
+            "unique": false,
+            "columnNames": [
+              "serverId",
+              "userId"
+            ],
+            "orders": [],
+            "createSql": "CREATE INDEX IF NOT EXISTS `index_Transaction_serverId_userId` ON `${TABLE_NAME}` (`serverId`, `userId`)"
+          },
+          {
+            "name": "index_Transaction_serverId_drinkId",
+            "unique": false,
+            "columnNames": [
+              "serverId",
+              "drinkId"
+            ],
+            "orders": [],
+            "createSql": "CREATE INDEX IF NOT EXISTS `index_Transaction_serverId_drinkId` ON `${TABLE_NAME}` (`serverId`, `drinkId`)"
+          }
+        ],
+        "foreignKeys": [
+          {
+            "table": "Server",
+            "onDelete": "NO ACTION",
+            "onUpdate": "NO ACTION",
+            "columns": [
+              "serverId"
+            ],
+            "referencedColumns": [
+              "serverId"
+            ]
+          },
+          {
+            "table": "User",
+            "onDelete": "NO ACTION",
+            "onUpdate": "NO ACTION",
+            "columns": [
+              "serverId",
+              "userId"
+            ],
+            "referencedColumns": [
+              "serverId",
+              "userId"
+            ]
+          },
+          {
+            "table": "Drink",
+            "onDelete": "NO ACTION",
+            "onUpdate": "NO ACTION",
+            "columns": [
+              "serverId",
+              "drinkId"
+            ],
+            "referencedColumns": [
+              "serverId",
+              "drinkId"
+            ]
+          }
+        ]
+      }
+    ],
+    "views": [],
+    "setupQueries": [
+      "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f794acceadd9ed28da1b218972b5e530')"
+    ]
+  }
+}
\ No newline at end of file
diff --git a/persistence/room/schemas/de.chaosdorf.meteroid.MeteroidDatabase/3.json b/persistence/room/schemas/de.chaosdorf.meteroid.MeteroidDatabase/3.json
new file mode 100644
index 0000000000000000000000000000000000000000..fdcae6c5d6232018e113ffbf6490f692f6773f46
--- /dev/null
+++ b/persistence/room/schemas/de.chaosdorf.meteroid.MeteroidDatabase/3.json
@@ -0,0 +1,364 @@
+{
+  "formatVersion": 1,
+  "database": {
+    "version": 3,
+    "identityHash": "f794acceadd9ed28da1b218972b5e530",
+    "entities": [
+      {
+        "tableName": "Drink",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` INTEGER NOT NULL, `drinkId` INTEGER NOT NULL, `active` INTEGER NOT NULL, `name` TEXT NOT NULL, `volume` TEXT NOT NULL, `caffeine` INTEGER, `price` TEXT NOT NULL, `logoUrl` TEXT NOT NULL, PRIMARY KEY(`serverId`, `drinkId`), FOREIGN KEY(`serverId`) REFERENCES `Server`(`serverId`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
+        "fields": [
+          {
+            "fieldPath": "serverId",
+            "columnName": "serverId",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "drinkId",
+            "columnName": "drinkId",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "active",
+            "columnName": "active",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "name",
+            "columnName": "name",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "volume",
+            "columnName": "volume",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "caffeine",
+            "columnName": "caffeine",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "price",
+            "columnName": "price",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "logoUrl",
+            "columnName": "logoUrl",
+            "affinity": "TEXT",
+            "notNull": true
+          }
+        ],
+        "primaryKey": {
+          "autoGenerate": false,
+          "columnNames": [
+            "serverId",
+            "drinkId"
+          ]
+        },
+        "indices": [],
+        "foreignKeys": [
+          {
+            "table": "Server",
+            "onDelete": "NO ACTION",
+            "onUpdate": "NO ACTION",
+            "columns": [
+              "serverId"
+            ],
+            "referencedColumns": [
+              "serverId"
+            ]
+          }
+        ]
+      },
+      {
+        "tableName": "Server",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` INTEGER NOT NULL, `name` TEXT, `url` TEXT NOT NULL, `logoUrl` TEXT, PRIMARY KEY(`serverId`))",
+        "fields": [
+          {
+            "fieldPath": "serverId",
+            "columnName": "serverId",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "name",
+            "columnName": "name",
+            "affinity": "TEXT",
+            "notNull": false
+          },
+          {
+            "fieldPath": "url",
+            "columnName": "url",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "logoUrl",
+            "columnName": "logoUrl",
+            "affinity": "TEXT",
+            "notNull": false
+          }
+        ],
+        "primaryKey": {
+          "autoGenerate": false,
+          "columnNames": [
+            "serverId"
+          ]
+        },
+        "indices": [],
+        "foreignKeys": []
+      },
+      {
+        "tableName": "User",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` INTEGER NOT NULL, `userId` INTEGER NOT NULL, `active` INTEGER NOT NULL, `name` TEXT NOT NULL, `email` TEXT NOT NULL, `balance` TEXT NOT NULL, `audit` INTEGER NOT NULL, `redirect` INTEGER NOT NULL, PRIMARY KEY(`serverId`, `userId`), FOREIGN KEY(`serverId`) REFERENCES `Server`(`serverId`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
+        "fields": [
+          {
+            "fieldPath": "serverId",
+            "columnName": "serverId",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "userId",
+            "columnName": "userId",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "active",
+            "columnName": "active",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "name",
+            "columnName": "name",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "email",
+            "columnName": "email",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "balance",
+            "columnName": "balance",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "audit",
+            "columnName": "audit",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "redirect",
+            "columnName": "redirect",
+            "affinity": "INTEGER",
+            "notNull": true
+          }
+        ],
+        "primaryKey": {
+          "autoGenerate": false,
+          "columnNames": [
+            "serverId",
+            "userId"
+          ]
+        },
+        "indices": [],
+        "foreignKeys": [
+          {
+            "table": "Server",
+            "onDelete": "NO ACTION",
+            "onUpdate": "NO ACTION",
+            "columns": [
+              "serverId"
+            ],
+            "referencedColumns": [
+              "serverId"
+            ]
+          }
+        ]
+      },
+      {
+        "tableName": "PinnedUser",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` INTEGER NOT NULL, `userId` INTEGER NOT NULL, PRIMARY KEY(`serverId`, `userId`), FOREIGN KEY(`serverId`) REFERENCES `Server`(`serverId`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`serverId`, `userId`) REFERENCES `User`(`serverId`, `userId`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
+        "fields": [
+          {
+            "fieldPath": "serverId",
+            "columnName": "serverId",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "userId",
+            "columnName": "userId",
+            "affinity": "INTEGER",
+            "notNull": true
+          }
+        ],
+        "primaryKey": {
+          "autoGenerate": false,
+          "columnNames": [
+            "serverId",
+            "userId"
+          ]
+        },
+        "indices": [],
+        "foreignKeys": [
+          {
+            "table": "Server",
+            "onDelete": "NO ACTION",
+            "onUpdate": "NO ACTION",
+            "columns": [
+              "serverId"
+            ],
+            "referencedColumns": [
+              "serverId"
+            ]
+          },
+          {
+            "table": "User",
+            "onDelete": "NO ACTION",
+            "onUpdate": "NO ACTION",
+            "columns": [
+              "serverId",
+              "userId"
+            ],
+            "referencedColumns": [
+              "serverId",
+              "userId"
+            ]
+          }
+        ]
+      },
+      {
+        "tableName": "Transaction",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` INTEGER NOT NULL, `transactionId` INTEGER NOT NULL, `userId` INTEGER NOT NULL, `drinkId` INTEGER, `difference` TEXT NOT NULL, `timestamp` INTEGER NOT NULL, PRIMARY KEY(`serverId`, `transactionId`), FOREIGN KEY(`serverId`) REFERENCES `Server`(`serverId`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`serverId`, `userId`) REFERENCES `User`(`serverId`, `userId`) ON UPDATE NO ACTION ON DELETE NO ACTION , FOREIGN KEY(`serverId`, `drinkId`) REFERENCES `Drink`(`serverId`, `drinkId`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
+        "fields": [
+          {
+            "fieldPath": "serverId",
+            "columnName": "serverId",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "transactionId",
+            "columnName": "transactionId",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "userId",
+            "columnName": "userId",
+            "affinity": "INTEGER",
+            "notNull": true
+          },
+          {
+            "fieldPath": "drinkId",
+            "columnName": "drinkId",
+            "affinity": "INTEGER",
+            "notNull": false
+          },
+          {
+            "fieldPath": "difference",
+            "columnName": "difference",
+            "affinity": "TEXT",
+            "notNull": true
+          },
+          {
+            "fieldPath": "timestamp",
+            "columnName": "timestamp",
+            "affinity": "INTEGER",
+            "notNull": true
+          }
+        ],
+        "primaryKey": {
+          "autoGenerate": false,
+          "columnNames": [
+            "serverId",
+            "transactionId"
+          ]
+        },
+        "indices": [
+          {
+            "name": "index_Transaction_serverId_userId",
+            "unique": false,
+            "columnNames": [
+              "serverId",
+              "userId"
+            ],
+            "orders": [],
+            "createSql": "CREATE INDEX IF NOT EXISTS `index_Transaction_serverId_userId` ON `${TABLE_NAME}` (`serverId`, `userId`)"
+          },
+          {
+            "name": "index_Transaction_serverId_drinkId",
+            "unique": false,
+            "columnNames": [
+              "serverId",
+              "drinkId"
+            ],
+            "orders": [],
+            "createSql": "CREATE INDEX IF NOT EXISTS `index_Transaction_serverId_drinkId` ON `${TABLE_NAME}` (`serverId`, `drinkId`)"
+          }
+        ],
+        "foreignKeys": [
+          {
+            "table": "Server",
+            "onDelete": "NO ACTION",
+            "onUpdate": "NO ACTION",
+            "columns": [
+              "serverId"
+            ],
+            "referencedColumns": [
+              "serverId"
+            ]
+          },
+          {
+            "table": "User",
+            "onDelete": "NO ACTION",
+            "onUpdate": "NO ACTION",
+            "columns": [
+              "serverId",
+              "userId"
+            ],
+            "referencedColumns": [
+              "serverId",
+              "userId"
+            ]
+          },
+          {
+            "table": "Drink",
+            "onDelete": "NO ACTION",
+            "onUpdate": "NO ACTION",
+            "columns": [
+              "serverId",
+              "drinkId"
+            ],
+            "referencedColumns": [
+              "serverId",
+              "drinkId"
+            ]
+          }
+        ]
+      }
+    ],
+    "views": [],
+    "setupQueries": [
+      "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f794acceadd9ed28da1b218972b5e530')"
+    ]
+  }
+}
\ No newline at end of file
diff --git a/persistence/src/main/kotlin/de/chaosdorf/meteroid/MeteroidDatabase.kt b/persistence/src/main/kotlin/de/chaosdorf/meteroid/MeteroidDatabase.kt
index 8cf5fac65c306c37e61882c2a458597da1c18c95..63251aedabdef9726f662283626f9524c46fd7a0 100644
--- a/persistence/src/main/kotlin/de/chaosdorf/meteroid/MeteroidDatabase.kt
+++ b/persistence/src/main/kotlin/de/chaosdorf/meteroid/MeteroidDatabase.kt
@@ -24,11 +24,14 @@
 
 package de.chaosdorf.meteroid
 
+import androidx.room.AutoMigration
 import androidx.room.Database
 import androidx.room.RoomDatabase
 import androidx.room.TypeConverters
 import de.chaosdorf.meteroid.model.Drink
 import de.chaosdorf.meteroid.model.DrinkRepository
+import de.chaosdorf.meteroid.model.PinnedUser
+import de.chaosdorf.meteroid.model.PinnedUserRepository
 import de.chaosdorf.meteroid.model.Server
 import de.chaosdorf.meteroid.model.ServerRepository
 import de.chaosdorf.meteroid.model.Transaction
@@ -44,6 +47,7 @@ import de.chaosdorf.meteroid.util.KotlinDatetimeTypeConverter
     Drink::class,
     Server::class,
     User::class,
+    PinnedUser::class,
     Transaction::class
   ],
   autoMigrations = [],
@@ -58,5 +62,6 @@ abstract class MeteroidDatabase : RoomDatabase() {
   abstract fun drinks(): DrinkRepository
   abstract fun server(): ServerRepository
   abstract fun users(): UserRepository
+  abstract fun pinnedUsers(): PinnedUserRepository
   abstract fun transactions(): TransactionRepository
 }
diff --git a/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/AccountInfo.kt b/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/AccountInfo.kt
index 581d020209ce703f670e6c144ec0d425c104c0fe..cd9af862ae68d104fcaa82745f783db2226ba16a 100644
--- a/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/AccountInfo.kt
+++ b/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/AccountInfo.kt
@@ -26,5 +26,6 @@ package de.chaosdorf.meteroid.model
 
 data class AccountInfo(
   val server: Server,
-  val user: User?
+  val user: User?,
+  val pinned: Boolean
 )
diff --git a/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/Drink.kt b/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/Drink.kt
index 6ea48860e6b2ff82b43e85f391aff1db39e75022..fe82de5c3c428098d6ae2c2bc708ac28eeee1e25 100644
--- a/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/Drink.kt
+++ b/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/Drink.kt
@@ -39,7 +39,7 @@ import java.net.URI
 @Entity(
   primaryKeys = ["serverId", "drinkId"],
   foreignKeys = [
-    ForeignKey(Server::class, ["serverId"], ["serverId"], onDelete = ForeignKey.CASCADE)
+    ForeignKey(Server::class, ["serverId"], ["serverId"])
   ]
 )
 data class Drink(
diff --git a/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/PinnedUser.kt b/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/PinnedUser.kt
new file mode 100644
index 0000000000000000000000000000000000000000..dae71d6133e85300e2d58640d763633fedfa2972
--- /dev/null
+++ b/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/PinnedUser.kt
@@ -0,0 +1,70 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013-2023 Chaosdorf e.V.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package de.chaosdorf.meteroid.model
+
+import androidx.room.Dao
+import androidx.room.Entity
+import androidx.room.ForeignKey
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import de.chaosdorf.mete.model.UserId
+import kotlinx.coroutines.flow.Flow
+
+@Entity(
+  primaryKeys = ["serverId", "userId"],
+  foreignKeys = [
+    ForeignKey(Server::class, ["serverId"], ["serverId"]),
+    ForeignKey(User::class, ["serverId", "userId"], ["serverId", "userId"])
+  ]
+)
+data class PinnedUser(
+  val serverId: ServerId,
+  val userId: UserId
+)
+
+@Dao
+interface PinnedUserRepository {
+  @Query("SELECT 1 FROM PinnedUser WHERE serverId = :serverId AND userId = :userId LIMIT 1")
+  suspend fun isPinned(serverId: ServerId, userId: UserId): Boolean
+
+  @Query("SELECT 1 FROM PinnedUser WHERE serverId = :serverId AND userId = :userId LIMIT 1")
+  fun isPinnedFlow(serverId: ServerId, userId: UserId): Flow<Boolean>
+
+  @Query("SELECT userId FROM PinnedUser WHERE serverId = :serverId")
+  suspend fun getAll(serverId: ServerId): List<UserId>
+
+  @Query("SELECT userId FROM PinnedUser WHERE serverId = :serverId")
+  fun getAllFlow(serverId: ServerId): Flow<List<UserId>>
+
+  @Insert(onConflict = OnConflictStrategy.REPLACE)
+  suspend fun save(user: PinnedUser)
+
+  @Query("DELETE FROM PinnedUser WHERE serverId = :serverId AND userId = :userId")
+  suspend fun delete(serverId: ServerId, userId: UserId)
+
+  @Query("DELETE FROM PinnedUser WHERE serverId = :serverId")
+  suspend fun deleteAll(serverId: ServerId)
+}
diff --git a/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/Transaction.kt b/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/Transaction.kt
index c564bbdfb01c9543f815cd373b9384e64d1af3e1..ac662512f36498378124d296e93df268c076d18c 100644
--- a/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/Transaction.kt
+++ b/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/Transaction.kt
@@ -42,18 +42,16 @@ import java.math.BigDecimal
 @Entity(
   primaryKeys = ["serverId", "transactionId"],
   foreignKeys = [
-    ForeignKey(Server::class, ["serverId"], ["serverId"], onDelete = ForeignKey.CASCADE),
+    ForeignKey(Server::class, ["serverId"], ["serverId"]),
     ForeignKey(
       User::class,
       ["serverId", "userId"],
-      ["serverId", "userId"],
-      onDelete = ForeignKey.CASCADE
+      ["serverId", "userId"]
     ),
     ForeignKey(
       Drink::class,
       ["serverId", "drinkId"],
-      ["serverId", "drinkId"],
-      onDelete = ForeignKey.NO_ACTION
+      ["serverId", "drinkId"]
     )
   ],
   indices = [
diff --git a/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/User.kt b/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/User.kt
index 60561680db069844b9498cba1ef618947febd417..8d06a2d44f5738eb2664688b399b365fa79cbe8c 100644
--- a/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/User.kt
+++ b/persistence/src/main/kotlin/de/chaosdorf/meteroid/model/User.kt
@@ -40,7 +40,7 @@ import java.util.Locale
 @Entity(
   primaryKeys = ["serverId", "userId"],
   foreignKeys = [
-    ForeignKey(Server::class, ["serverId"], ["serverId"], onDelete = ForeignKey.CASCADE)
+    ForeignKey(Server::class, ["serverId"], ["serverId"])
   ]
 )
 data class User(
@@ -53,6 +53,15 @@ data class User(
   val audit: Boolean,
   val redirect: Boolean,
 ) {
+  @OptIn(ExperimentalStdlibApi::class)
+  val gravatarUrl: String by lazy {
+    val normalised: String = email.lowercase(Locale.ROOT)
+    val binaryData: ByteArray = normalised.toByteArray(Charsets.UTF_8)
+    val binaryHash: ByteArray = MessageDigest.getInstance("MD5").digest(binaryData)
+    val hash: String = binaryHash.toHexString()
+    "https://www.gravatar.com/avatar/$hash?d=404&s=640"
+  }
+
   companion object {
     fun fromModel(server: Server, value: UserModel) = User(
       server.serverId,
@@ -65,15 +74,6 @@ data class User(
       value.redirect,
     )
   }
-
-  @OptIn(ExperimentalStdlibApi::class)
-  fun gravatarUrl(): String {
-    val normalised: String = email.lowercase(Locale.ROOT)
-    val binaryData: ByteArray = normalised.toByteArray(Charsets.UTF_8)
-    val binaryHash: ByteArray = MessageDigest.getInstance("MD5").digest(binaryData)
-    val hash: String = binaryHash.toHexString()
-    return "https://www.gravatar.com/avatar/$hash?d=404"
-  }
 }
 
 @Dao