Scert/backend/internal/repository/project_audit_reader.go
xuans 413a0e66a9 完成手动续期后台任务及权限隔离并更新回归进度
保留管理与业务续期调度,增加系统级幂等任务、取消传播和统计审计原子收尾;前端跟踪真实任务状态。原生 Linux 全后端、静态检查、相关专项二十次重复及前端二百七十二项测试和生产构建通过,未进行正式生产部署。
2026-10-02 21:32:30 +08:00

59 lines
2.2 KiB
Go

package repository
import (
"context"
"fmt"
"git.pcux.cn/xuans/Scert/backend/internal/domain"
)
// ProjectAuditReader 只返回当前账户有权查看的项目审计记录。
type ProjectAuditReader interface {
ListVisibleAuditLogs(context.Context, string, int) ([]AuditLog, error)
}
var _ ProjectAuditReader = (*SQLProjectMemberRepository)(nil)
func (r *SQLProjectMemberRepository) ListVisibleAuditLogs(ctx context.Context, actorID string, limit int) ([]AuditLog, error) {
if err := r.resourceReaderReady(actorID); err != nil {
return nil, err
}
if limit <= 0 || limit > 200 {
limit = 50
}
rows, err := r.db.QueryContext(ctx, Rebind(r.driver, `SELECT logs.id, logs.action,
logs.resource_type, logs.resource_id, logs.status, logs.message, logs.created_at,
logs.scope_type, logs.project_id, logs.task_id, logs.operator_id
FROM audit_logs logs WHERE EXISTS (
SELECT 1 FROM users actor WHERE actor.id = ? AND actor.status = 'active'
AND (actor.role = 'super_admin' OR NOT EXISTS (
SELECT 1 FROM tasks restricted_task WHERE restricted_task.id = logs.task_id
AND restricted_task.task_type = 'renewal_check'))
AND (actor.role IN ('super_admin', 'admin') OR (actor.role = 'user'
AND logs.scope_type = 'project' AND EXISTS (
SELECT 1 FROM project_members member
WHERE member.project_id = logs.project_id AND member.user_id = actor.id
AND member.role IN (?, ?)))))
ORDER BY logs.created_at DESC, logs.id DESC LIMIT ?`),
actorID, string(domain.ProjectRoleAdmin), string(domain.ProjectRoleAuditViewer), limit)
if err != nil {
return nil, fmt.Errorf("查询项目审计日志失败:%w", err)
}
defer rows.Close()
items := make([]AuditLog, 0)
for rows.Next() {
var item AuditLog
if err := rows.Scan(&item.ID, &item.Action, &item.ResourceType, &item.ResourceID,
&item.Status, &item.Message, &item.CreatedAt, &item.ScopeType, &item.ProjectID,
&item.TaskID, &item.OperatorID); err != nil {
return nil, fmt.Errorf("读取项目审计日志失败:%w", err)
}
item.CreatedAt = item.CreatedAt.UTC()
items = append(items, item)
}
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("读取项目审计日志列表失败:%w", err)
}
return items, nil
}