Skip to content
Clone

feat(space): carry invite extras and ban expiry through the commands

The service layer could already persist an invite's email and extra roles and a
ban's expiry, but neither reached HTTP: `CreateInviteBody` was
`{role_id, target_user_id, max_uses, ttl_secs}` and `BanMemberBody` was
`{reason}`. The invite dialog collected an address and roles that were silently
dropped, and a ban configured with an expiry stayed permanent.

- `CreateInviteBody` gains `email` and `extra_role_ids`; the handler now calls
  `create_invite_with_extras` instead of the wrapper that hard-codes `None`.
- `BanMemberBody` gains the same three-state `expires_at` as `UpdateBanBody`;
  `ban_member` writes `ban_expires_at` in the insert, so one call is enough.
ZhenYi committed
parent 27b0264 commit 7f0e1a0 Browse files

3 files changed

+18 −2

File tree 3
Modified lib/service/space/src/handlers/space_admin.rs View lib/service/space/src/handlers/space_admin.rs
@@ -112,6 +112,11 @@
112112pub struct CreateInviteBody {
113113 pub role_id: Option<Uuid>,
114114 pub target_user_id: Option<i64>,
115 /// 定向邀请的收件邮箱;与 `target_user_id` 二选一,两者都空则是公开令牌。
116 pub email: Option<String>,
117 /// 兑换后一并授予的额外角色。
118 #[serde(default)]
119 pub extra_role_ids: Vec<Uuid>,
115120 #[serde(default)]
116121 pub max_uses: i32,
117122 pub ttl_secs: Option<u64>,
@@ -767,6 +772,7 @@
767772 space_id,
768773 path.member_id,
769774 body.reason.as_deref(),
775 body.expires_at.flatten(),
770776 Some(request_id.0.as_str()),
771777 )
772778 .await?;
@@ -1441,13 +1447,15 @@
14411447 let space_id = svc.space_id_by_name(user_id, &path.space_name).await?;
14421448 let body = body.into_inner();
14431449 let (invite, token) = svc
1444 .admin_create_invite(
1450 .create_invite_with_extras(
14451451 user_id,
14461452 space_id,
14471453 body.role_id,
14481454 body.target_user_id,
14491455 body.max_uses,
14501456 body.ttl_secs,
1457 body.email,
1458 &body.extra_role_ids,
14511459 Some(request_id.0.as_str()),
14521460 )
14531461 .await?;
Modified lib/service/space/src/services/member.rs View lib/service/space/src/services/member.rs
@@ -1,4 +1,4 @@
1use chrono::Utc;
1use chrono::{DateTime, Utc};
22use sea_orm::entity::Set;
33use sea_orm::sea_query::{Expr, ExprTrait};
44use sea_orm::{
@@ -438,6 +438,7 @@
438438 organization_id: Uuid,
439439 member_id: Uuid,
440440 reason: Option<&str>,
441 expires_at: Option<DateTime<Utc>>,
441442 request_id: Option<&str>,
442443 ) -> SpaceResult<MemberSummary> {
443444 self.require_permission(actor_user_id, organization_id, "member.ban", request_id)
@@ -465,6 +466,10 @@
465466 Expr::value(reason.clone()),
466467 )
467468 .col_expr(
469 space_members::Column::BanExpiresAt,
470 Expr::value(expires_at),
471 )
472 .col_expr(
468473 space_members::Column::Version,
469474 Expr::col(space_members::Column::Version).add(1),
470475 )
Modified lib/service/space/src/services/types.rs View lib/service/space/src/services/types.rs
@@ -281,6 +281,9 @@
281281#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]
282282pub struct BanMemberBody {
283283 pub reason: Option<String>,
284 /// 到期时间;缺省或 `null` 表示永久封禁。
285 #[serde(default, deserialize_with = "double_option")]
286 pub expires_at: Option<Option<DateTime<Utc>>>,
284287}
285288
286289#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)]