feat: implement course change auditing with time-series metrics endpoint

This commit is contained in:
2026-01-29 14:19:36 -06:00
parent 4deeef2f00
commit 98a6d978c6
4 changed files with 703 additions and 86 deletions
+34
View File
@@ -72,6 +72,29 @@ export interface AuditLogResponse {
entries: AuditLogEntry[];
}
export interface MetricEntry {
id: number;
courseId: number;
timestamp: string;
enrollment: number;
waitCount: number;
seatsAvailable: number;
}
export interface MetricsResponse {
metrics: MetricEntry[];
count: number;
timestamp: string;
}
export interface MetricsParams {
course_id?: number;
term?: string;
crn?: string;
range?: "1h" | "6h" | "24h" | "7d" | "30d";
limit?: number;
}
export interface SearchParams {
term: string;
subjects?: string[];
@@ -161,6 +184,17 @@ export class BannerApiClient {
async getAdminAuditLog(): Promise<AuditLogResponse> {
return this.request<AuditLogResponse>("/admin/audit-log");
}
async getMetrics(params?: MetricsParams): Promise<MetricsResponse> {
const query = new URLSearchParams();
if (params?.course_id !== undefined) query.set("course_id", String(params.course_id));
if (params?.term) query.set("term", params.term);
if (params?.crn) query.set("crn", params.crn);
if (params?.range) query.set("range", params.range);
if (params?.limit !== undefined) query.set("limit", String(params.limit));
const qs = query.toString();
return this.request<MetricsResponse>(`/metrics${qs ? `?${qs}` : ""}`);
}
}
export const client = new BannerApiClient();