use anyhow::Context; use deadpool_diesel::postgres::Connection; use diesel::{ dsl::{auto_type, insert_into, AsSelect}, pg::Pg, prelude::*, Connection as _, }; use serde::Serialize; use uuid::Uuid; use crate::{ app_error::AppError, schema::{channels, email_channels, slack_channels}, teams::Team, }; #[derive(Associations, Clone, Debug, Identifiable, Queryable, Selectable)] #[diesel(belongs_to(Team))] pub struct Channel { pub id: Uuid, pub team_id: Uuid, pub name: String, pub enable_by_default: bool, #[diesel(embed)] pub email_data: Option, #[diesel(embed)] pub slack_data: Option, } #[derive( Associations, Clone, Debug, Identifiable, Insertable, Queryable, Selectable, Serialize, )] #[diesel(belongs_to(Channel, foreign_key = id))] pub struct EmailChannel { pub id: Uuid, pub recipient: String, #[serde(skip_serializing)] pub verification_code: String, pub verification_code_guesses: i32, pub verified: bool, } #[derive(Associations, Clone, Debug, Identifiable, Insertable, Queryable, Selectable)] #[diesel(belongs_to(Channel, foreign_key = id))] pub struct SlackChannel { pub id: Uuid, pub oauth_state: String, pub access_token: String, pub conversation_id: String, } impl Channel { #[auto_type(no_type_alias)] pub fn all() -> _ { let select: AsSelect = Channel::as_select(); channels::table .left_join(email_channels::table) .left_join(slack_channels::table) .select(select) } #[auto_type(no_type_alias)] pub fn with_id(channel_id: Uuid) -> _ { channels::id.eq(channel_id) } #[auto_type(no_type_alias)] pub fn with_team(team_id: Uuid) -> _ { channels::team_id.eq(team_id) } pub async fn create_email_channel( db_conn: &Connection, team_id: Uuid, ) -> Result { let id = Uuid::now_v7(); db_conn .interact(move |conn| { conn.transaction(move |conn| { insert_into(channels::table) .values(( channels::id.eq(id.clone()), channels::team_id.eq(team_id), channels::name.eq("Untitled Email Channel"), )) .execute(conn)?; insert_into(email_channels::table) .values(email_channels::id.eq(id.clone())) .execute(conn)?; Self::all().filter(Self::with_id(id)).first(conn) }) }) .await .unwrap() .context("Failed to insert new EmailChannel.") .map_err(|err| err.into()) } }