refactor(admin): remove auth migration reports
This commit is contained in:
@@ -1,148 +0,0 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type AuthIdentityMigrationReport struct {
|
||||
ID int64
|
||||
ReportType string
|
||||
ReportKey string
|
||||
Details map[string]any
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
type AuthIdentityMigrationReportQuery struct {
|
||||
ReportType string
|
||||
Limit int
|
||||
Offset int
|
||||
}
|
||||
|
||||
type AuthIdentityMigrationReportSummary struct {
|
||||
Total int64
|
||||
ByType map[string]int64
|
||||
}
|
||||
|
||||
func (r *userRepository) ListAuthIdentityMigrationReports(ctx context.Context, query AuthIdentityMigrationReportQuery) ([]AuthIdentityMigrationReport, error) {
|
||||
exec := txAwareSQLExecutor(ctx, r.sql, r.client)
|
||||
if exec == nil {
|
||||
return nil, fmt.Errorf("sql executor is not configured")
|
||||
}
|
||||
|
||||
limit := query.Limit
|
||||
if limit <= 0 {
|
||||
limit = 100
|
||||
}
|
||||
rows, err := exec.QueryContext(ctx, `
|
||||
SELECT id, report_type, report_key, details, created_at
|
||||
FROM auth_identity_migration_reports
|
||||
WHERE ($1 = '' OR report_type = $1)
|
||||
ORDER BY created_at DESC, id DESC
|
||||
LIMIT $2 OFFSET $3`,
|
||||
strings.TrimSpace(query.ReportType),
|
||||
limit,
|
||||
query.Offset,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() { _ = rows.Close() }()
|
||||
|
||||
reports := make([]AuthIdentityMigrationReport, 0)
|
||||
for rows.Next() {
|
||||
report, scanErr := scanAuthIdentityMigrationReport(rows)
|
||||
if scanErr != nil {
|
||||
return nil, scanErr
|
||||
}
|
||||
reports = append(reports, report)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return reports, nil
|
||||
}
|
||||
|
||||
func (r *userRepository) GetAuthIdentityMigrationReport(ctx context.Context, reportType, reportKey string) (*AuthIdentityMigrationReport, error) {
|
||||
exec := txAwareSQLExecutor(ctx, r.sql, r.client)
|
||||
if exec == nil {
|
||||
return nil, fmt.Errorf("sql executor is not configured")
|
||||
}
|
||||
|
||||
rows, err := exec.QueryContext(ctx, `
|
||||
SELECT id, report_type, report_key, details, created_at
|
||||
FROM auth_identity_migration_reports
|
||||
WHERE report_type = $1 AND report_key = $2
|
||||
LIMIT 1`,
|
||||
strings.TrimSpace(reportType),
|
||||
strings.TrimSpace(reportKey),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() { _ = rows.Close() }()
|
||||
|
||||
if !rows.Next() {
|
||||
return nil, sql.ErrNoRows
|
||||
}
|
||||
report, err := scanAuthIdentityMigrationReport(rows)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &report, rows.Err()
|
||||
}
|
||||
|
||||
func (r *userRepository) SummarizeAuthIdentityMigrationReports(ctx context.Context) (*AuthIdentityMigrationReportSummary, error) {
|
||||
exec := txAwareSQLExecutor(ctx, r.sql, r.client)
|
||||
if exec == nil {
|
||||
return nil, fmt.Errorf("sql executor is not configured")
|
||||
}
|
||||
|
||||
rows, err := exec.QueryContext(ctx, `
|
||||
SELECT report_type, COUNT(*)
|
||||
FROM auth_identity_migration_reports
|
||||
GROUP BY report_type
|
||||
ORDER BY report_type ASC`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() { _ = rows.Close() }()
|
||||
|
||||
summary := &AuthIdentityMigrationReportSummary{
|
||||
ByType: make(map[string]int64),
|
||||
}
|
||||
for rows.Next() {
|
||||
var reportType string
|
||||
var count int64
|
||||
if err := rows.Scan(&reportType, &count); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
summary.ByType[reportType] = count
|
||||
summary.Total += count
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return summary, nil
|
||||
}
|
||||
|
||||
func scanAuthIdentityMigrationReport(scanner interface{ Scan(dest ...any) error }) (AuthIdentityMigrationReport, error) {
|
||||
var (
|
||||
report AuthIdentityMigrationReport
|
||||
details []byte
|
||||
)
|
||||
if err := scanner.Scan(&report.ID, &report.ReportType, &report.ReportKey, &details, &report.CreatedAt); err != nil {
|
||||
return AuthIdentityMigrationReport{}, err
|
||||
}
|
||||
report.Details = map[string]any{}
|
||||
if len(details) > 0 {
|
||||
if err := json.Unmarshal(details, &report.Details); err != nil {
|
||||
return AuthIdentityMigrationReport{}, err
|
||||
}
|
||||
}
|
||||
return report, nil
|
||||
}
|
||||
@@ -36,7 +36,6 @@ TRUNCATE TABLE
|
||||
auth_identity_channels,
|
||||
auth_identities,
|
||||
pending_auth_sessions,
|
||||
auth_identity_migration_reports,
|
||||
user_provider_default_grants,
|
||||
user_avatars
|
||||
RESTART IDENTITY`)
|
||||
@@ -393,36 +392,6 @@ func (s *UserProfileIdentityRepoSuite) TestUserAvatarCRUDAndUserLookup() {
|
||||
s.Require().Nil(loadedAvatar)
|
||||
}
|
||||
|
||||
func (s *UserProfileIdentityRepoSuite) TestAuthIdentityMigrationReportHelpers_ListAndSummarize() {
|
||||
_, err := integrationDB.ExecContext(s.ctx, `
|
||||
INSERT INTO auth_identity_migration_reports (report_type, report_key, details, created_at)
|
||||
VALUES
|
||||
('wechat_openid_only_requires_remediation', 'u-1', '{"user_id":1}'::jsonb, '2026-04-20T10:00:00Z'),
|
||||
('wechat_openid_only_requires_remediation', 'u-2', '{"user_id":2}'::jsonb, '2026-04-20T11:00:00Z'),
|
||||
('oidc_synthetic_email_requires_manual_recovery', 'u-3', '{"user_id":3}'::jsonb, '2026-04-20T12:00:00Z')`)
|
||||
s.Require().NoError(err)
|
||||
|
||||
summary, err := s.repo.SummarizeAuthIdentityMigrationReports(s.ctx)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(int64(3), summary.Total)
|
||||
s.Require().Equal(int64(2), summary.ByType["wechat_openid_only_requires_remediation"])
|
||||
s.Require().Equal(int64(1), summary.ByType["oidc_synthetic_email_requires_manual_recovery"])
|
||||
|
||||
reports, err := s.repo.ListAuthIdentityMigrationReports(s.ctx, AuthIdentityMigrationReportQuery{
|
||||
ReportType: "wechat_openid_only_requires_remediation",
|
||||
Limit: 10,
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(reports, 2)
|
||||
s.Require().Equal("u-2", reports[0].ReportKey)
|
||||
s.Require().Equal(float64(2), reports[0].Details["user_id"])
|
||||
|
||||
report, err := s.repo.GetAuthIdentityMigrationReport(s.ctx, "oidc_synthetic_email_requires_manual_recovery", "u-3")
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal("u-3", report.ReportKey)
|
||||
s.Require().Equal(float64(3), report.Details["user_id"])
|
||||
}
|
||||
|
||||
func (s *UserProfileIdentityRepoSuite) TestUpdateUserLastLoginAndActiveAt_UsesDedicatedColumns() {
|
||||
user := s.mustCreateUser("activity")
|
||||
loginAt := time.Date(2026, 4, 20, 8, 0, 0, 0, time.UTC)
|
||||
|
||||
@@ -445,10 +445,6 @@ func userListOrder(params pagination.PaginationParams) []func(*entsql.Selector)
|
||||
case "created_at":
|
||||
field = dbuser.FieldCreatedAt
|
||||
defaultField = false
|
||||
case "last_login_at":
|
||||
field = dbuser.FieldLastLoginAt
|
||||
defaultField = false
|
||||
nullsLastField = true
|
||||
case "last_active_at":
|
||||
field = dbuser.FieldLastActiveAt
|
||||
defaultField = false
|
||||
|
||||
@@ -95,27 +95,6 @@ func (s *UserRepoSuite) TestUpdate_PersistsSignupSourceAndActivityTimestamps() {
|
||||
s.Require().True(got.LastActiveAt.Equal(lastActiveAt))
|
||||
}
|
||||
|
||||
func (s *UserRepoSuite) TestListWithFilters_SortByLastLoginAtDesc() {
|
||||
older := time.Now().Add(-4 * time.Hour).UTC().Truncate(time.Microsecond)
|
||||
newer := time.Now().Add(-1 * time.Hour).UTC().Truncate(time.Microsecond)
|
||||
|
||||
s.mustCreateUser(&service.User{Email: "nil-login@example.com"})
|
||||
s.mustCreateUser(&service.User{Email: "older-login@example.com", LastLoginAt: &older})
|
||||
s.mustCreateUser(&service.User{Email: "newer-login@example.com", LastLoginAt: &newer})
|
||||
|
||||
users, _, err := s.repo.ListWithFilters(s.ctx, pagination.PaginationParams{
|
||||
Page: 1,
|
||||
PageSize: 10,
|
||||
SortBy: "last_login_at",
|
||||
SortOrder: "desc",
|
||||
}, service.UserListFilters{})
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(users, 3)
|
||||
s.Require().Equal("newer-login@example.com", users[0].Email)
|
||||
s.Require().Equal("older-login@example.com", users[1].Email)
|
||||
s.Require().Equal("nil-login@example.com", users[2].Email)
|
||||
}
|
||||
|
||||
func (s *UserRepoSuite) TestListWithFilters_SortByLastActiveAtAsc() {
|
||||
earlier := time.Now().Add(-3 * time.Hour).UTC().Truncate(time.Microsecond)
|
||||
later := time.Now().Add(-45 * time.Minute).UTC().Truncate(time.Microsecond)
|
||||
|
||||
Reference in New Issue
Block a user