fix(admin): repair system maintenance controls

Implement server-side searchable user filtering for usage records, including backend search parameters and a shared frontend selector with loading, empty, and pinned-selected states.

Fix announcement deletion by cascading announcement read rows through a Postgres migration and defensive repository cleanup across supported backends.

Wire admin system purge and cleanup endpoints to real data deletion/maintenance flows, improve DataManagement messages, rebuild stats after stats purge, and add runtime OAuth token refresh maintenance when enabled.

Verified with rust-ci equivalent checks: cargo fmt, split clippy, split cargo tests, SQLite/Postgres/MySQL smoke tests, plus frontend npm ci, build, pages build, type-check, and targeted usage selector tests.
This commit is contained in:
Entropy.Xu
2026-05-07 21:26:40 +08:00
parent 2b439094c5
commit dd8c2ebec6
37 changed files with 2836 additions and 103 deletions

View File

@@ -70,13 +70,38 @@ export interface UpsertUserApiKeyRequest {
export type UserSession = SessionRecord
export interface GetAllUsersOptions {
search?: string
skip?: number
limit?: number
cacheTtlMs?: number
}
export const usersApi = {
async getAllUsers(options: { cacheTtlMs?: number } = {}): Promise<User[]> {
async getAllUsers(options: GetAllUsersOptions = {}): Promise<User[]> {
const cacheTtlMs = options.cacheTtlMs ?? 0
const params: Record<string, string | number> = {}
const search = options.search?.trim()
if (search) params.search = search
if (options.skip !== undefined) params.skip = options.skip
if (options.limit !== undefined) params.limit = options.limit
const cacheKey = Object.keys(params).length === 0
? 'admin:users:list'
: [
'admin:users:list',
search ?? '',
options.skip ?? '',
options.limit ?? '',
].join(':')
return cachedRequest(
'admin:users:list',
cacheKey,
async () => {
const response = await apiClient.get<User[]>('/api/admin/users')
const response = await apiClient.get<User[]>('/api/admin/users', {
params: Object.keys(params).length > 0 ? params : undefined,
})
return response.data
},
cacheTtlMs,