collab: Remove unused feature flag queries (#38360)

Marshall Bowers created

This PR removes the feature flag queries, as they were no longer used.

Release Notes:

- N/A

Change summary

crates/collab/src/db/queries/users.rs            | 73 ------------------
crates/collab/src/db/tables.rs                   |  2 
crates/collab/src/db/tables/feature_flag.rs      | 41 ----------
crates/collab/src/db/tables/user.rs              | 23 -----
crates/collab/src/db/tables/user_feature.rs      | 42 ----------
crates/collab/src/db/tests.rs                    |  1 
crates/collab/src/db/tests/feature_flag_tests.rs | 66 ----------------
crates/collab/src/seed.rs                        | 58 ++-----------
8 files changed, 10 insertions(+), 296 deletions(-)

Detailed changes

crates/collab/src/db/queries/users.rs 🔗

@@ -342,79 +342,6 @@ impl Database {
         result
     }
 
-    /// Returns all feature flags.
-    pub async fn list_feature_flags(&self) -> Result<Vec<feature_flag::Model>> {
-        self.transaction(|tx| async move { Ok(feature_flag::Entity::find().all(&*tx).await?) })
-            .await
-    }
-
-    /// Creates a new feature flag.
-    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)
-            .await?
-            .last_insert_id;
-
-            Ok(flag)
-        })
-        .await
-    }
-
-    /// Add the given user to the feature flag
-    pub async fn add_user_flag(&self, user: UserId, flag: FlagId) -> Result<()> {
-        self.transaction(|tx| async move {
-            user_feature::Entity::insert(user_feature::ActiveModel {
-                user_id: ActiveValue::set(user),
-                feature_id: ActiveValue::set(flag),
-            })
-            .exec(&*tx)
-            .await?;
-
-            Ok(())
-        })
-        .await
-    }
-
-    /// Returns the active flags for the user.
-    pub async fn get_user_flags(&self, user: UserId) -> Result<Vec<String>> {
-        self.transaction(|tx| async move {
-            #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
-            enum QueryAs {
-                Flag,
-            }
-
-            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()
-            }
-            .find_linked(user::UserFlags)
-            .select_only()
-            .column(feature_flag::Column::Flag)
-            .into_values::<_, QueryAs>()
-            .all(&*tx)
-            .await?;
-
-            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
-    }
-
     pub async fn get_users_missing_github_user_created_at(&self) -> Result<Vec<user::Model>> {
         self.transaction(|tx| async move {
             Ok(user::Entity::find()

crates/collab/src/db/tables.rs 🔗

@@ -13,7 +13,6 @@ pub mod contributor;
 pub mod embedding;
 pub mod extension;
 pub mod extension_version;
-pub mod feature_flag;
 pub mod follower;
 pub mod language_server;
 pub mod notification;
@@ -29,7 +28,6 @@ pub mod room_participant;
 pub mod server;
 pub mod signup;
 pub mod user;
-pub mod user_feature;
 pub mod worktree;
 pub mod worktree_diagnostic_summary;
 pub mod worktree_entry;

crates/collab/src/db/tables/feature_flag.rs 🔗

@@ -1,41 +0,0 @@
-use sea_orm::entity::prelude::*;
-
-use crate::db::FlagId;
-
-#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
-#[sea_orm(table_name = "feature_flags")]
-pub struct Model {
-    #[sea_orm(primary_key)]
-    pub id: FlagId,
-    pub flag: String,
-    pub enabled_for_all: bool,
-}
-
-#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
-pub enum Relation {
-    #[sea_orm(has_many = "super::user_feature::Entity")]
-    UserFeature,
-}
-
-impl Related<super::user_feature::Entity> for Entity {
-    fn to() -> RelationDef {
-        Relation::UserFeature.def()
-    }
-}
-
-impl ActiveModelBehavior for ActiveModel {}
-
-pub struct FlaggedUsers;
-
-impl Linked for FlaggedUsers {
-    type FromEntity = Entity;
-
-    type ToEntity = super::user::Entity;
-
-    fn link(&self) -> Vec<RelationDef> {
-        vec![
-            super::user_feature::Relation::Flag.def().rev(),
-            super::user_feature::Relation::User.def(),
-        ]
-    }
-}

crates/collab/src/db/tables/user.rs 🔗

@@ -35,8 +35,6 @@ pub enum Relation {
     HostedProjects,
     #[sea_orm(has_many = "super::channel_member::Entity")]
     ChannelMemberships,
-    #[sea_orm(has_many = "super::user_feature::Entity")]
-    UserFeatures,
     #[sea_orm(has_one = "super::contributor::Entity")]
     Contributor,
 }
@@ -84,25 +82,4 @@ impl Related<super::channel_member::Entity> for Entity {
     }
 }
 
-impl Related<super::user_feature::Entity> for Entity {
-    fn to() -> RelationDef {
-        Relation::UserFeatures.def()
-    }
-}
-
 impl ActiveModelBehavior for ActiveModel {}
-
-pub struct UserFlags;
-
-impl Linked for UserFlags {
-    type FromEntity = Entity;
-
-    type ToEntity = super::feature_flag::Entity;
-
-    fn link(&self) -> Vec<RelationDef> {
-        vec![
-            super::user_feature::Relation::User.def().rev(),
-            super::user_feature::Relation::Flag.def(),
-        ]
-    }
-}

crates/collab/src/db/tables/user_feature.rs 🔗

@@ -1,42 +0,0 @@
-use sea_orm::entity::prelude::*;
-
-use crate::db::{FlagId, UserId};
-
-#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
-#[sea_orm(table_name = "user_features")]
-pub struct Model {
-    #[sea_orm(primary_key)]
-    pub user_id: UserId,
-    #[sea_orm(primary_key)]
-    pub feature_id: FlagId,
-}
-
-#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
-pub enum Relation {
-    #[sea_orm(
-        belongs_to = "super::feature_flag::Entity",
-        from = "Column::FeatureId",
-        to = "super::feature_flag::Column::Id"
-    )]
-    Flag,
-    #[sea_orm(
-        belongs_to = "super::user::Entity",
-        from = "Column::UserId",
-        to = "super::user::Column::Id"
-    )]
-    User,
-}
-
-impl Related<super::feature_flag::Entity> for Entity {
-    fn to() -> RelationDef {
-        Relation::Flag.def()
-    }
-}
-
-impl Related<super::user::Entity> for Entity {
-    fn to() -> RelationDef {
-        Relation::User.def()
-    }
-}
-
-impl ActiveModelBehavior for ActiveModel {}

crates/collab/src/db/tests.rs 🔗

@@ -6,7 +6,6 @@ mod db_tests;
 #[cfg(target_os = "macos")]
 mod embedding_tests;
 mod extension_tests;
-mod feature_flag_tests;
 mod user_tests;
 
 use crate::migrations::run_database_migrations;

crates/collab/src/db/tests/feature_flag_tests.rs 🔗

@@ -1,66 +0,0 @@
-use crate::{
-    db::{Database, NewUserParams},
-    test_both_dbs,
-};
-use pretty_assertions::assert_eq;
-use std::sync::Arc;
-
-test_both_dbs!(
-    test_get_user_flags,
-    test_get_user_flags_postgres,
-    test_get_user_flags_sqlite
-);
-
-async fn test_get_user_flags(db: &Arc<Database>) {
-    let user_1 = db
-        .create_user(
-            "user1@example.com",
-            None,
-            false,
-            NewUserParams {
-                github_login: "user1".to_string(),
-                github_user_id: 1,
-            },
-        )
-        .await
-        .unwrap()
-        .user_id;
-
-    let user_2 = db
-        .create_user(
-            "user2@example.com",
-            None,
-            false,
-            NewUserParams {
-                github_login: "user2".to_string(),
-                github_user_id: 2,
-            },
-        )
-        .await
-        .unwrap()
-        .user_id;
-
-    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 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, feature_flag_one).await.unwrap();
-    db.add_user_flag(user_1, feature_flag_two).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,
-        &[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, &[FEATURE_FLAG_ONE, FEATURE_FLAG_THREE]);
-}

crates/collab/src/seed.rs 🔗

@@ -46,27 +46,6 @@ pub async fn seed(config: &Config, db: &Database, force: bool) -> anyhow::Result
     let mut first_user = None;
     let mut others = vec![];
 
-    let flag_names = ["language-models"];
-    let mut flags = Vec::new();
-
-    let existing_feature_flags = db.list_feature_flags().await?;
-
-    for flag_name in flag_names {
-        if existing_feature_flags
-            .iter()
-            .any(|flag| flag.flag == flag_name)
-        {
-            log::info!("Flag {flag_name:?} already exists");
-            continue;
-        }
-
-        let flag = db
-            .create_user_flag(flag_name, false)
-            .await
-            .unwrap_or_else(|err| panic!("failed to create flag: '{flag_name}': {err}"));
-        flags.push(flag);
-    }
-
     for admin_login in seed_config.admins {
         let user = fetch_github::<GithubUser>(
             &client,
@@ -90,15 +69,6 @@ pub async fn seed(config: &Config, db: &Database, force: bool) -> anyhow::Result
         } else {
             others.push(user.user_id)
         }
-
-        for flag in &flags {
-            db.add_user_flag(user.user_id, *flag)
-                .await
-                .context(format!(
-                    "Unable to enable flag '{}' for user '{}'",
-                    flag, user.user_id
-                ))?;
-        }
     }
 
     for channel in seed_config.channels {
@@ -126,24 +96,16 @@ pub async fn seed(config: &Config, db: &Database, force: bool) -> anyhow::Result
     for github_user in github_users {
         log::info!("Seeding {:?} from GitHub", github_user.login);
 
-        let user = db
-            .update_or_create_user_by_github_account(
-                &github_user.login,
-                github_user.id,
-                github_user.email.as_deref(),
-                github_user.name.as_deref(),
-                github_user.created_at,
-                None,
-            )
-            .await
-            .expect("failed to insert user");
-
-        for flag in &flags {
-            db.add_user_flag(user.id, *flag).await.context(format!(
-                "Unable to enable flag '{}' for user '{}'",
-                flag, user.id
-            ))?;
-        }
+        db.update_or_create_user_by_github_account(
+            &github_user.login,
+            github_user.id,
+            github_user.email.as_deref(),
+            github_user.name.as_deref(),
+            github_user.created_at,
+            None,
+        )
+        .await
+        .expect("failed to insert user");
     }
 
     Ok(())