Detailed changes
@@ -295,7 +295,8 @@ CREATE UNIQUE INDEX "index_channel_buffer_collaborators_on_channel_id_connection
CREATE TABLE "feature_flags" (
"id" INTEGER PRIMARY KEY AUTOINCREMENT,
- "flag" TEXT NOT NULL UNIQUE
+ "flag" TEXT NOT NULL UNIQUE,
+ "enabled_for_all" BOOLEAN NOT NULL DEFAULT false
);
CREATE INDEX "index_feature_flags" ON "feature_flags" ("id");
@@ -0,0 +1 @@
+alter table feature_flags add column enabled_for_all boolean not null default false;
@@ -312,10 +312,11 @@ impl Database {
}
/// Creates a new feature flag.
- pub async fn create_user_flag(&self, flag: &str) -> Result<FlagId> {
+ pub async fn create_user_flag(&self, flag: &str, enabled_for_all: bool) -> Result<FlagId> {
self.transaction(|tx| async move {
let flag = feature_flag::Entity::insert(feature_flag::ActiveModel {
flag: ActiveValue::set(flag.to_string()),
+ enabled_for_all: ActiveValue::set(enabled_for_all),
..Default::default()
})
.exec(&*tx)
@@ -350,7 +351,15 @@ impl Database {
Flag,
}
- let flags = user::Model {
+ let flags_enabled_for_all = feature_flag::Entity::find()
+ .filter(feature_flag::Column::EnabledForAll.eq(true))
+ .select_only()
+ .column(feature_flag::Column::Flag)
+ .into_values::<_, QueryAs>()
+ .all(&*tx)
+ .await?;
+
+ let flags_enabled_for_user = user::Model {
id: user,
..Default::default()
}
@@ -361,7 +370,10 @@ impl Database {
.all(&*tx)
.await?;
- Ok(flags)
+ let mut all_flags = HashSet::from_iter(flags_enabled_for_all);
+ all_flags.extend(flags_enabled_for_user);
+
+ Ok(all_flags.into_iter().collect())
})
.await
}
@@ -8,6 +8,7 @@ pub struct Model {
#[sea_orm(primary_key)]
pub id: FlagId,
pub flag: String,
+ pub enabled_for_all: bool,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
@@ -2,6 +2,7 @@ use crate::{
db::{Database, NewUserParams},
test_both_dbs,
};
+use pretty_assertions::assert_eq;
use std::sync::Arc;
test_both_dbs!(
@@ -37,22 +38,27 @@ async fn test_get_user_flags(db: &Arc<Database>) {
.unwrap()
.user_id;
- const CHANNELS_ALPHA: &str = "channels-alpha";
- const NEW_SEARCH: &str = "new-search";
+ const FEATURE_FLAG_ONE: &str = "brand-new-ux";
+ const FEATURE_FLAG_TWO: &str = "cool-feature";
+ const FEATURE_FLAG_THREE: &str = "feature-enabled-for-everyone";
- let channels_flag = db.create_user_flag(CHANNELS_ALPHA).await.unwrap();
- let search_flag = db.create_user_flag(NEW_SEARCH).await.unwrap();
+ let feature_flag_one = db.create_user_flag(FEATURE_FLAG_ONE, false).await.unwrap();
+ let feature_flag_two = db.create_user_flag(FEATURE_FLAG_TWO, false).await.unwrap();
+ db.create_user_flag(FEATURE_FLAG_THREE, true).await.unwrap();
- db.add_user_flag(user_1, channels_flag).await.unwrap();
- db.add_user_flag(user_1, search_flag).await.unwrap();
+ db.add_user_flag(user_1, feature_flag_one).await.unwrap();
+ db.add_user_flag(user_1, feature_flag_two).await.unwrap();
- db.add_user_flag(user_2, channels_flag).await.unwrap();
+ db.add_user_flag(user_2, feature_flag_one).await.unwrap();
let mut user_1_flags = db.get_user_flags(user_1).await.unwrap();
user_1_flags.sort();
- assert_eq!(user_1_flags, &[CHANNELS_ALPHA, NEW_SEARCH]);
+ assert_eq!(
+ user_1_flags,
+ &[FEATURE_FLAG_ONE, FEATURE_FLAG_TWO, FEATURE_FLAG_THREE]
+ );
let mut user_2_flags = db.get_user_flags(user_2).await.unwrap();
user_2_flags.sort();
- assert_eq!(user_2_flags, &[CHANNELS_ALPHA]);
+ assert_eq!(user_2_flags, &[FEATURE_FLAG_ONE, FEATURE_FLAG_THREE]);
}