fix: resolve E2E audit findings and add Phase C frontend pages

- Fix audit_log handler multi-tenant bug: use Extension<TenantContext>
  instead of hardcoded default_tenant_id
- Fix sendMessage route mismatch: frontend /messages/send → /messages
- Add POST /users/{id}/roles backend route for role assignment
- Add task.completed event payload: started_by + instance_id for
  notification delivery
- Add audit log viewer frontend page (AuditLogViewer.tsx)
- Add language management frontend page (LanguageManager.tsx)
- Add api/auditLogs.ts and api/languages.ts modules
This commit is contained in:
iven
2026-04-12 15:57:33 +08:00
parent 14f431efff
commit 3b41e73f82
11 changed files with 567 additions and 12 deletions

View File

@@ -1,7 +1,7 @@
use axum::Extension;
use axum::extract::{FromRef, Path, Query, State};
use axum::response::Json;
use serde::Deserialize;
use serde::{Deserialize, Serialize};
use validator::Validate;
use erp_core::error::AppError;
@@ -9,7 +9,7 @@ use erp_core::types::{ApiResponse, PaginatedResponse, Pagination, TenantContext}
use uuid::Uuid;
use crate::auth_state::AuthState;
use crate::dto::{CreateUserReq, UpdateUserReq, UserResp};
use crate::dto::{CreateUserReq, RoleResp, UpdateUserReq, UserResp};
use erp_core::rbac::require_permission;
use crate::service::user_service::UserService;
@@ -151,3 +151,38 @@ where
message: Some("用户已删除".to_string()),
}))
}
/// Assign roles request body.
#[derive(Debug, Deserialize)]
pub struct AssignRolesReq {
pub role_ids: Vec<Uuid>,
}
/// Assign roles response.
#[derive(Debug, Serialize)]
pub struct AssignRolesResp {
pub roles: Vec<RoleResp>,
}
/// POST /api/v1/users/:id/roles
///
/// Replace all role assignments for a user within the current tenant.
/// Requires the `user.update` permission.
pub async fn assign_roles<S>(
State(state): State<AuthState>,
Extension(ctx): Extension<TenantContext>,
Path(id): Path<Uuid>,
Json(req): Json<AssignRolesReq>,
) -> Result<Json<ApiResponse<AssignRolesResp>>, AppError>
where
AuthState: FromRef<S>,
S: Clone + Send + Sync + 'static,
{
require_permission(&ctx, "user.update")?;
let roles =
UserService::assign_roles(id, ctx.tenant_id, ctx.user_id, &req.role_ids, &state.db)
.await?;
Ok(Json(ApiResponse::ok(AssignRolesResp { roles })))
}