feat(admin): wire instance health panel + settings instance (A9/A10)
AdminInstance shows backing-service health (db/redis/ml), read-only source status (env-configured), and a library reindex with graceful handling when no indexable source exists. InstanceSettings shows the active instance and offers switch/sign-out to /connect. Adds getServices/getSources/reindex endpoints. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
import { api } from '../index';
|
||||
import { toUser, type RawUser } from '../mappers';
|
||||
import type { User } from '../types';
|
||||
import type { User, ServicesStatus, SourceInfo } from '../types';
|
||||
|
||||
interface ReindexJob {
|
||||
source: string;
|
||||
jobId: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin user management. The backend models authorization as `is_superuser` /
|
||||
@@ -59,6 +64,20 @@ export const adminApi = api.injectEndpoints({
|
||||
body: { new_password: newPassword },
|
||||
}),
|
||||
}),
|
||||
// -- instance (§A9) -------------------------------------------------------
|
||||
getServices: build.query<ServicesStatus, void>({
|
||||
query: () => '/admin/services',
|
||||
}),
|
||||
getSources: build.query<SourceInfo[], void>({
|
||||
query: () => '/admin/sources',
|
||||
}),
|
||||
reindex: build.mutation<ReindexJob[], void>({
|
||||
query: () => ({ url: '/admin/reindex', method: 'POST' }),
|
||||
transformResponse: (raw: { jobs: { source: string; job_id: string }[] }) =>
|
||||
raw.jobs.map((j) => ({ source: j.source, jobId: j.job_id })),
|
||||
// A fresh scan changes the catalogue once the worker runs.
|
||||
invalidatesTags: ['Track', 'Album', 'Artist', 'Storage'],
|
||||
}),
|
||||
}),
|
||||
overrideExisting: false,
|
||||
});
|
||||
@@ -70,4 +89,7 @@ export const {
|
||||
useUpdateUserMutation,
|
||||
useDeleteUserMutation,
|
||||
useResetPasswordMutation,
|
||||
useGetServicesQuery,
|
||||
useGetSourcesQuery,
|
||||
useReindexMutation,
|
||||
} = adminApi;
|
||||
|
||||
@@ -140,6 +140,16 @@ export interface UploadResponse {
|
||||
already_exists: boolean;
|
||||
}
|
||||
|
||||
/** One backing-dependency probe result (GET /admin/services). `skipped` = the
|
||||
* dependency is optional and not configured (e.g. ML with no ML_SERVICE_URL). */
|
||||
export type ServiceStatus = 'ok' | 'down' | 'skipped';
|
||||
|
||||
export interface ServicesStatus {
|
||||
database: ServiceStatus;
|
||||
redis: ServiceStatus;
|
||||
ml: ServiceStatus;
|
||||
}
|
||||
|
||||
export interface StorageFormatBreakdown {
|
||||
fileFormat: string;
|
||||
trackCount: number;
|
||||
|
||||
Reference in New Issue
Block a user