feat: implement tenant-side creator audit feature and update related tests and documentation

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-02-09 06:54:04 +08:00
parent 3126ed5e64
commit 05a0d07dbb
23 changed files with 7205 additions and 112 deletions

View File

@@ -592,3 +592,86 @@ func (s *CreatorTestSuite) Test_ExportReport() {
So(resp.Content, ShouldContainSubstring, "date,paid_orders,paid_amount,refund_orders,refund_amount,withdrawal_apply_orders,withdrawal_apply_amount,withdrawal_paid_orders,withdrawal_paid_amount,withdrawal_failed_orders,withdrawal_failed_amount,content_created,like_actions,favorite_actions,comment_count")
})
}
func (s *CreatorTestSuite) Test_ListAuditLogs() {
Convey("ListAuditLogs", s.T(), func() {
ctx := s.T().Context()
database.Truncate(ctx, s.DB,
models.TableNameAuditLog,
models.TableNameTenant,
models.TableNameUser,
)
owner := &models.User{Username: "owner_audit", Phone: "13900001013"}
operator := &models.User{Username: "operator_audit", Phone: "13900001014"}
outsider := &models.User{Username: "outsider_audit", Phone: "13900001015"}
models.UserQuery.WithContext(ctx).Create(owner, operator, outsider)
tenantA := &models.Tenant{
Name: "Tenant Audit A",
Code: "tenant_audit_a",
UserID: owner.ID,
Status: consts.TenantStatusVerified,
}
tenantB := &models.Tenant{
Name: "Tenant Audit B",
Code: "tenant_audit_b",
UserID: operator.ID,
Status: consts.TenantStatusVerified,
}
models.TenantQuery.WithContext(ctx).Create(tenantA, tenantB)
now := time.Now()
models.AuditLogQuery.WithContext(ctx).Create(
&models.AuditLog{
TenantID: tenantA.ID,
OperatorID: owner.ID,
Action: "update_settings",
TargetID: "setting_1",
Detail: "更新频道配置",
CreatedAt: now.Add(-1 * time.Hour),
},
&models.AuditLog{
TenantID: tenantA.ID,
OperatorID: operator.ID,
Action: "invite_member",
TargetID: "member_1",
Detail: "邀请成员",
CreatedAt: now,
},
&models.AuditLog{
TenantID: tenantB.ID,
OperatorID: operator.ID,
Action: "update_settings",
TargetID: "setting_999",
Detail: "跨租户数据",
CreatedAt: now,
},
)
pager, err := Creator.ListAuditLogs(ctx, tenantA.ID, owner.ID, &creator_dto.CreatorAuditLogListFilter{})
So(err, ShouldBeNil)
So(pager.Total, ShouldEqual, 2)
items, ok := pager.Items.([]creator_dto.CreatorAuditLogItem)
So(ok, ShouldBeTrue)
So(len(items), ShouldEqual, 2)
So(items[0].TargetID, ShouldEqual, "member_1")
So(items[1].TargetID, ShouldEqual, "setting_1")
operatorName := "operator_audit"
filtered, err := Creator.ListAuditLogs(ctx, tenantA.ID, owner.ID, &creator_dto.CreatorAuditLogListFilter{
OperatorName: &operatorName,
})
So(err, ShouldBeNil)
So(filtered.Total, ShouldEqual, 1)
filteredItems, ok := filtered.Items.([]creator_dto.CreatorAuditLogItem)
So(ok, ShouldBeTrue)
So(len(filteredItems), ShouldEqual, 1)
So(filteredItems[0].Action, ShouldEqual, "invite_member")
So(filteredItems[0].OperatorName, ShouldEqual, "operator_audit")
_, err = Creator.ListAuditLogs(ctx, tenantA.ID, outsider.ID, &creator_dto.CreatorAuditLogListFilter{})
So(err, ShouldNotBeNil)
})
}