org 模块: - tenants 表 (UUID PK, name, slug, status, settings) - 完整 CRUD API: /api/v1/org/tenants - 多租户隔离 audit 模块: - audit_logs 表 (actor, action, resource, IP, 时间) - 查询 API: /api/v1/audit/logs (支持分页+筛选) - 按 tenant_id/user_id/action/resource 过滤
47 lines
1.1 KiB
Go
47 lines
1.1 KiB
Go
package application
|
|
|
|
import (
|
|
"context"
|
|
|
|
"mengstack/internal/kernel/errors"
|
|
"mengstack/internal/modules/audit/domain"
|
|
)
|
|
|
|
type Service struct {
|
|
repo domain.AuditRepository
|
|
}
|
|
|
|
func NewService(repo domain.AuditRepository) *Service {
|
|
return &Service{repo: repo}
|
|
}
|
|
|
|
func (s *Service) Log(ctx context.Context, tenantID string, userID uint, action, resource, resourceID, detail, ip string) error {
|
|
log := &domain.AuditLog{
|
|
TenantID: tenantID,
|
|
UserID: userID,
|
|
Action: action,
|
|
Resource: resource,
|
|
ResourceID: resourceID,
|
|
Detail: detail,
|
|
IP: ip,
|
|
}
|
|
|
|
if err := s.repo.Create(ctx, log); err != nil {
|
|
return errors.Wrap(err, "AUDIT_LOG_FAILED", "failed to write audit log", 500)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *Service) Query(ctx context.Context, query domain.AuditQuery) ([]domain.AuditLogDTO, int64, error) {
|
|
logs, total, err := s.repo.Find(ctx, query)
|
|
if err != nil {
|
|
return nil, 0, errors.Wrap(err, "QUERY_AUDIT_FAILED", "failed to query audit logs", 500)
|
|
}
|
|
|
|
dtos := make([]domain.AuditLogDTO, len(logs))
|
|
for i, l := range logs {
|
|
dtos[i] = domain.ToAuditLogDTO(&l)
|
|
}
|
|
return dtos, total, nil
|
|
}
|