feat: Add logging and reporting capabilities with GDPR compliance

Agent-Logs-Url: https://github.com/christianlouis/pop_puller_to_gmail/sessions/d6e65ca9-f07f-43a2-bac2-09eb44588ded

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-03-26 18:12:22 +00:00
parent 276ef1f8b2
commit fd45c838fc
13 changed files with 977 additions and 20 deletions
+133 -4
View File
@@ -126,6 +126,64 @@ export interface ProcessingRun {
emails_failed: number;
status: string;
error_message?: string | null;
account_name?: string | null;
account_email?: string | null;
}
export interface ProcessingLog {
id: number;
timestamp: string;
level: string;
message: string;
email_subject?: string | null;
email_from?: string | null;
success: boolean;
mail_account_id: number;
processing_run_id?: number | null;
email_size_bytes?: number | null;
error_details?: Record<string, unknown> | null;
}
export interface PaginatedProcessingRuns {
items: ProcessingRun[];
total: number;
page: number;
page_size: number;
pages: number;
}
export interface PaginatedProcessingLogs {
items: ProcessingLog[];
total: number;
page: number;
page_size: number;
pages: number;
}
export interface AdminProcessingRun extends ProcessingRun {
user_id?: number | null;
user_email?: string | null;
}
export interface AdminProcessingLog extends ProcessingLog {
user_id: number;
user_email?: string | null;
}
export interface PaginatedAdminRuns {
items: AdminProcessingRun[];
total: number;
page: number;
page_size: number;
pages: number;
}
export interface PaginatedAdminLogsResponse {
items: AdminProcessingLog[];
total: number;
page: number;
page_size: number;
pages: number;
}
export interface AutoDetectSuggestion {
@@ -292,10 +350,54 @@ export const mailAccountsApi = {
// ── Processing Runs API ─────────────────────────────────────────────────
export const processingRunsApi = {
async list(): Promise<ProcessingRun[]> {
// TODO: Add a dedicated /processing-runs endpoint to the backend
// For now, return empty array since no user-facing endpoint exists yet
return [];
async list(params?: {
page?: number;
page_size?: number;
account_id?: number;
status?: string;
}): Promise<PaginatedProcessingRuns> {
const response = await api.get<PaginatedProcessingRuns>("/processing-runs", {
params,
});
return response.data;
},
async get(runId: number): Promise<ProcessingRun> {
const response = await api.get<ProcessingRun>(`/processing-runs/${runId}`);
return response.data;
},
async getLogs(
runId: number,
params?: { page?: number; page_size?: number }
): Promise<PaginatedProcessingLogs> {
const response = await api.get<PaginatedProcessingLogs>(
`/processing-runs/${runId}/logs`,
{ params }
);
return response.data;
},
async listForAccount(
accountId: number,
params?: { page?: number; page_size?: number; status?: string }
): Promise<PaginatedProcessingRuns> {
const response = await api.get<PaginatedProcessingRuns>(
`/mail-accounts/${accountId}/processing-runs`,
{ params }
);
return response.data;
},
async listLogsForAccount(
accountId: number,
params?: { page?: number; page_size?: number; level?: string }
): Promise<PaginatedProcessingLogs> {
const response = await api.get<PaginatedProcessingLogs>(
`/mail-accounts/${accountId}/logs`,
{ params }
);
return response.data;
},
};
@@ -483,6 +585,33 @@ export const adminApi = {
async deletePlan(id: number): Promise<void> {
await api.delete(`/admin/plans/${id}`);
},
async listProcessingRuns(params?: {
page?: number;
page_size?: number;
user_id?: number;
account_id?: number;
status?: string;
}): Promise<PaginatedAdminRuns> {
const response = await api.get<PaginatedAdminRuns>('/admin/processing-runs', {
params,
});
return response.data;
},
async listProcessingLogs(params?: {
page?: number;
page_size?: number;
user_id?: number;
account_id?: number;
run_id?: number;
level?: string;
}): Promise<PaginatedAdminLogsResponse> {
const response = await api.get<PaginatedAdminLogsResponse>('/admin/processing-logs', {
params,
});
return response.data;
},
};
export default api;