Stage 10: external blocklist importer — backend + frontend
- blocklist_repo.py: CRUD for blocklist_sources table - import_log_repo.py: add/list/get-last log entries - blocklist_service.py: source CRUD, preview, import (download/validate/ban), import_all, schedule get/set/info - blocklist_import.py: APScheduler task (hourly/daily/weekly schedule triggers) - blocklist.py router: 9 endpoints (list/create/update/delete/preview/import/ schedule-get+put/log) - blocklist.py models: ScheduleFrequency (StrEnum), ScheduleConfig, ScheduleInfo, ImportSourceResult, ImportRunResult, PreviewResponse - 59 new tests (18 repo + 19 service + 22 router); 374 total pass - ruff clean, mypy clean for Stage 10 files - types/blocklist.ts, api/blocklist.ts, hooks/useBlocklist.ts - BlocklistsPage.tsx: source management, schedule picker, import log table - Frontend tsc + ESLint clean
This commit is contained in:
97
frontend/src/api/blocklist.ts
Normal file
97
frontend/src/api/blocklist.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* API functions for the blocklist management endpoints.
|
||||
*/
|
||||
|
||||
import { del, get, post, put } from "./client";
|
||||
import { ENDPOINTS } from "./endpoints";
|
||||
import type {
|
||||
BlocklistListResponse,
|
||||
BlocklistSource,
|
||||
BlocklistSourceCreate,
|
||||
BlocklistSourceUpdate,
|
||||
ImportLogListResponse,
|
||||
ImportRunResult,
|
||||
PreviewResponse,
|
||||
ScheduleConfig,
|
||||
ScheduleInfo,
|
||||
} from "../types/blocklist";
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Sources
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/** Fetch all configured blocklist sources. */
|
||||
export async function fetchBlocklists(): Promise<BlocklistListResponse> {
|
||||
return get<BlocklistListResponse>(ENDPOINTS.blocklists);
|
||||
}
|
||||
|
||||
/** Create a new blocklist source. */
|
||||
export async function createBlocklist(
|
||||
payload: BlocklistSourceCreate,
|
||||
): Promise<BlocklistSource> {
|
||||
return post<BlocklistSource>(ENDPOINTS.blocklists, payload);
|
||||
}
|
||||
|
||||
/** Update a blocklist source. */
|
||||
export async function updateBlocklist(
|
||||
id: number,
|
||||
payload: BlocklistSourceUpdate,
|
||||
): Promise<BlocklistSource> {
|
||||
return put<BlocklistSource>(ENDPOINTS.blocklist(id), payload);
|
||||
}
|
||||
|
||||
/** Delete a blocklist source. */
|
||||
export async function deleteBlocklist(id: number): Promise<void> {
|
||||
await del<undefined>(ENDPOINTS.blocklist(id));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Preview
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/** Preview the contents of a blocklist source URL. */
|
||||
export async function previewBlocklist(id: number): Promise<PreviewResponse> {
|
||||
return get<PreviewResponse>(ENDPOINTS.blocklistPreview(id));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Import
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/** Trigger a manual import of all enabled sources. */
|
||||
export async function runImportNow(): Promise<ImportRunResult> {
|
||||
return post<ImportRunResult>(ENDPOINTS.blocklistsImport, {});
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Schedule
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/** Fetch the current schedule config and next/last run times. */
|
||||
export async function fetchSchedule(): Promise<ScheduleInfo> {
|
||||
return get<ScheduleInfo>(ENDPOINTS.blocklistsSchedule);
|
||||
}
|
||||
|
||||
/** Update the import schedule. */
|
||||
export async function updateSchedule(config: ScheduleConfig): Promise<ScheduleInfo> {
|
||||
return put<ScheduleInfo>(ENDPOINTS.blocklistsSchedule, config);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Import log
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/** Fetch a paginated import log. */
|
||||
export async function fetchImportLog(
|
||||
page = 1,
|
||||
pageSize = 50,
|
||||
sourceId?: number,
|
||||
): Promise<ImportLogListResponse> {
|
||||
const params = new URLSearchParams();
|
||||
params.set("page", String(page));
|
||||
params.set("page_size", String(pageSize));
|
||||
if (sourceId !== undefined) params.set("source_id", String(sourceId));
|
||||
return get<ImportLogListResponse>(
|
||||
`${ENDPOINTS.blocklistsLog}?${params.toString()}`,
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user