feat(service): expand service layer with new domain operations

- Add IM service modules: audit, channel roles, custom emojis, forum
  tags, integrations, invitations, repo links, slash commands, stages,
  voice, webhooks
- Add PR service modules: review requests, templates
- Add repo service modules: contributors, release assets, git extras
  (archive, branch rename, commit extras, diff/merge, tag, tree)
- Add user service: social (follow/block)
- Add internal auth service
- Update existing service modules with expanded functionality
- Remove deleted IM modules: articles, delivery trace, drafts,
  follows, messages, polls, presence, reactions, threads
This commit is contained in:
zhenyi
2026-06-10 18:49:32 +08:00
parent cec6dce955
commit 420dedbc1e
100 changed files with 3797 additions and 3839 deletions
+20 -15
View File
@@ -9,8 +9,7 @@ use crate::service::ImService;
use super::session::ImSession;
use super::util::*;
use crate::immediate::{ChannelAction, ChannelEvent};
use crate::service::im::events::ImEvent;
use crate::service::im::events::{ChannelAction, ChannelEvent, ImEvent};
#[derive(Deserialize, Serialize, Clone, Debug, utoipa::ToSchema)]
pub struct CreateChannelParams {
@@ -159,6 +158,14 @@ impl ImService {
let now = chrono::Utc::now();
let channel_id = Uuid::now_v7();
let mut txn = self
.ctx
.db
.writer()
.begin()
.await
.map_err(|_| AppError::TxnError)?;
let channel = sqlx::query_as::<_, Channel>(
"INSERT INTO channel \
(id, workspace_id, repo_id, category_id, created_by, name, topic, description, \
@@ -189,7 +196,7 @@ impl ImService {
.bind(params.rate_limit_per_user)
.bind(params.parent_channel_id)
.bind(now)
.fetch_one(self.ctx.db.writer())
.fetch_one(&mut *txn)
.await
.map_err(AppError::Database)?;
@@ -203,10 +210,12 @@ impl ImService {
.bind(channel_id)
.bind(user_uid)
.bind(now)
.execute(self.ctx.db.writer())
.execute(&mut *txn)
.await
.map_err(AppError::Database)?;
txn.commit().await.map_err(|_| AppError::TxnError)?;
tracing::info!(channel_id = %channel_id, name = %name, "Channel created");
let event = ChannelEvent {
@@ -429,6 +438,7 @@ impl ImService {
Err(AppError::Unauthorized)
}
#[allow(dead_code)]
pub(crate) async fn ensure_channel_member(
&self,
user_uid: Uuid,
@@ -527,25 +537,20 @@ impl ImService {
.unwrap_or(Role::Unknown))
}
pub(crate) async fn update_channel_stats(
pub(crate) async fn increment_channel_stat(
&self,
channel_id: Uuid,
delta: i32,
now: chrono::DateTime<chrono::Utc>,
txn: &mut sqlx::Transaction<'_, sqlx::Postgres>,
) -> Result<(), AppError> {
sqlx::query(
"UPDATE channel_stats SET \
members_count = (SELECT COUNT(*) FROM channel_member WHERE channel_id = $1 AND status = 'active'), \
messages_count = (SELECT COUNT(*) FROM message WHERE channel_id = $1 AND deleted_at IS NULL), \
threads_count = (SELECT COUNT(*) FROM message_thread WHERE channel_id = $1), \
reactions_count = (SELECT COUNT(*) FROM message_reaction WHERE channel_id = $1), \
mentions_count = (SELECT COUNT(*) FROM message_mention WHERE channel_id = $1), \
files_count = (SELECT COUNT(*) FROM message_attachment WHERE channel_id = $1), \
last_activity_at = $2, updated_at = $2 \
WHERE channel_id = $1",
"UPDATE channel_stats SET members_count = members_count + $1, \
last_activity_at = $2, updated_at = $2 WHERE channel_id = $3",
)
.bind(channel_id)
.bind(delta)
.bind(now)
.bind(channel_id)
.execute(&mut **txn)
.await
.map_err(AppError::Database)?;