Skip to content
Clone
a06673b
109 lines 3.2 KB Rust
use db::channel::channels as channel_entity;
use db::conn::sea_orm::*;
use db::space::space_members as member_entity;
use db::space::spaces as space_entity;
use time::OffsetDateTime;
use uuid::Uuid;
use crate::error::{SpaceError, SpaceResult};
use crate::features::SpaceService;
use super::types::{ChannelPage, ChannelView};
async fn member_space(
svc: &SpaceService,
caller: Uuid,
space_id: Uuid,
) -> SpaceResult<space_entity::Model> {
let db = svc.db.reader();
let space = space_entity::Entity::find_by_id(space_id)
.one(&db)
.await?
.ok_or_else(|| SpaceError::NotFound(format!("space {space_id}")))?;
let member = member_entity::Entity::find_by_id((space_id, caller))
.one(&db)
.await?;
let active = member
.map(|m| m.status == member_entity::MemberStatus::Active)
.unwrap_or(false);
if !active {
return Err(SpaceError::Forbidden(
"caller is not an active member of this space".to_string(),
));
}
Ok(space)
}
pub async fn get_channel(
svc: &SpaceService,
caller: Uuid,
space_id: Uuid,
channel_id: Uuid,
) -> SpaceResult<ChannelView> {
member_space(svc, caller, space_id).await?;
let db = svc.db.reader();
let channel = channel_entity::Entity::find_by_id(channel_id)
.one(&db)
.await?
.ok_or_else(|| SpaceError::NotFound(format!("channel {channel_id}")))?;
if channel.space_id != Some(space_id) {
return Err(SpaceError::NotFound(format!("channel {channel_id}")));
}
Ok(ChannelView::from(channel))
}
pub async fn list_channels(
svc: &SpaceService,
caller: Uuid,
space_id: Uuid,
limit: u64,
offset: u64,
) -> SpaceResult<ChannelPage> {
member_space(svc, caller, space_id).await?;
let db = svc.db.reader();
let limit = std::cmp::max(std::cmp::min(limit, svc.config.max_pagination), 1);
let items = channel_entity::Entity::find()
.filter(channel_entity::Column::SpaceId.eq(space_id))
.order_by_asc(channel_entity::Column::Position)
.limit(Some(limit))
.offset(Some(offset))
.all(&db)
.await?
.into_iter()
.map(ChannelView::from)
.collect();
let total = channel_entity::Entity::find()
.filter(channel_entity::Column::SpaceId.eq(space_id))
.count(&db)
.await?;
Ok(ChannelPage { items, total: total as i64 })
}
pub async fn ensure_channel_for_resource(
svc: &SpaceService,
space_id: Uuid,
name: &str,
created_by: Uuid,
) -> SpaceResult<ChannelView> {
let db = svc.db.writer();
let now = OffsetDateTime::now_utc();
let active: channel_entity::ActiveModel = channel_entity::ActiveModel::builder()
.set_id(Uuid::new_v4())
.set_space_id(Some(space_id))
.set_name(name.to_string())
.set_parent_id(None)
.set_color(None)
.set_position(0)
.set_icon(None)
.set_topic(None)
.set_purpose(None)
.set_is_archived(false)
.set_archived_at(None)
.set_archived_by(None)
.set_created_at(now)
.set_updated_at(now)
.set_created_by(created_by)
.into();
let saved = active.insert(&db).await?;
Ok(ChannelView::from(saved))
}