darkwing/database/team/model.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
//! Team-related database models and types.
//!
//! This module contains the core data structures for representing teams and
//! their settings in the database, including plan types and team configuration.
#![allow(
non_snake_case,
reason = "sqlx query_as macro does not support FromRow trait, so we cant use renamed fields. see https://github.com/launchbadge/sqlx/issues/1372 and https://github.com/launchbadge/sqlx/issues/514"
)]
use sqlx::types::time::PrimitiveDateTime;
use sqlx::FromRow;
/// Represents the simplified plan status of a team.
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
pub enum Plan {
/// Free tier with limited features
Free,
/// Paid tier
Paid,
}
impl From<Team> for Plan {
/// Converts a Team instance into its corresponding Plan status.
///
/// # Arguments
///
/// * `value` - The team instance to convert from
///
/// # Returns
///
/// Returns `Plan::Free` for beta, unknown, and free plans with default
/// limits. Returns `Plan::Paid` for all other combinations.
fn from(value: Team) -> Self {
match (value.plan, value.browserProfilesLimit) {
(DbPlan::Beta | DbPlan::Unknown, _) => Self::Free,
(DbPlan::Free, 10) => Self::Free,
_ => Self::Paid,
}
}
}
/// Represents the detailed plan type stored in the database.
#[derive(sqlx::Type, Debug, Clone)]
#[sqlx(rename_all = "lowercase")]
pub enum DbPlan {
/// Beta testing plan (stopped being in use, but still present as enum
/// variant in DB)
Beta,
/// Trial period plan
Trial,
/// Free tier plan
Free,
/// Base paid plan
Base,
/// Team plan
Team,
/// Enterprise plan
Enterprise,
/// Custom configured plan
Custom,
/// Unknown plan type (fallback)
Unknown,
}
impl From<String> for DbPlan {
/// Converts a string into its corresponding DbPlan variant.
///
/// # Returns
///
/// Returns the matching DbPlan variant, or DbPlan::Unknown if no match is
/// found. Unknown plans are reported to Sentry for monitoring.
fn from(value: String) -> Self {
match value.to_lowercase().as_str() {
"beta" => Self::Beta,
"trial" => Self::Trial,
"free" => Self::Free,
"base" => Self::Base,
"team" => Self::Team,
"enterprise" => Self::Enterprise,
"custom" => Self::Custom,
_ => {
sentry::capture_message(
&format!("Unknown plan: {value}"),
sentry::Level::Warning,
);
Self::Unknown
}
}
}
}
/// Represents a team entity in the database.
#[derive(FromRow, Debug, Clone)]
#[allow(unused)]
pub struct Team {
/// Unique identifier for the team
pub id: u64,
/// ID of the user who owns this team
pub userId: i64,
/// Name of the team
pub name: String,
/// Current plan type of the team
pub plan: DbPlan,
/// Maximum number of users allowed in the team
pub usersLimit: u64,
/// Maximum number of browser profiles allowed for the team
pub browserProfilesLimit: u64,
/// Timestamp when the current subscription expires
pub subscriptionExpiration: PrimitiveDateTime,
/// Flag indicating if sync is enabled for the team
pub syncEnabled: i8,
}
impl Team {
/// Returns the simplified plan status for this team.
///
/// # Returns
///
/// Returns either Plan::Free or Plan::Paid based on the team's configuration.
pub fn get_plan(&self) -> Plan {
Plan::from(self.clone())
}
}
/// Represents a team setting in the database.
#[derive(FromRow, Debug)]
#[allow(unused)]
pub struct Setting {
/// The scope level of the setting
pub level: String,
/// Category of the setting
pub category: String,
/// Parameter name
pub param: String,
/// Value to use when deleted
pub deletedValue: String,
/// Encrypted value of the setting
pub valueCrypt: Option<Vec<u8>>,
/// ID of the encryption key used
pub cryptoKeyId: u32,
}