feat(webui): add aggregate Campaign reports

This commit is contained in:
2026-07-22 08:44:15 +02:00
parent 06125cc0e8
commit fc36aee6c0
4 changed files with 348 additions and 0 deletions

View File

@@ -458,6 +458,53 @@ export type CampaignReportEmailPayload = {
dry_run?: boolean;
};
export type AggregateReportCount = {
value: number | null;
suppressed: boolean;
};
export type AggregateReportCampaign = {
id: string;
name: string;
status: string;
};
export type AggregateReportCampaignListItem = AggregateReportCampaign & {
updated_at: string;
};
export type AggregateCampaignReport = {
generated_at: string;
campaign: AggregateReportCampaign;
version_number: number | null;
completion_state: "not_started" | "in_progress" | "completed" | "partially_completed" | "incomplete" | "outcome_unknown" | "suppressed";
population: {
denominator: AggregateReportCount;
denominator_definition: string;
inactive_source_entries: AggregateReportCount;
excluded_or_blocked_jobs: AggregateReportCount;
};
outcomes: {
smtp_accepted: AggregateReportCount;
failed: AggregateReportCount;
outcome_unknown: AggregateReportCount;
queued_or_active: AggregateReportCount;
cancelled: AggregateReportCount;
excluded: AggregateReportCount;
not_attempted: AggregateReportCount;
};
time_range: {
first_activity_at: string | null;
last_activity_at: string | null;
suppressed: boolean;
};
privacy: {
small_cell_threshold: number;
suppression_applied: boolean;
rule: string;
};
};
export async function listCampaigns(settings: ApiSettings): Promise<CampaignListItem[]> {
const response = await apiFetch<CampaignListResponse>(settings, "/api/v1/campaigns");
@@ -468,6 +515,13 @@ export async function listCampaigns(settings: ApiSettings): Promise<CampaignList
return response.campaigns ?? response.items ?? response.results ?? [];
}
export async function listAggregateReportCampaigns(
settings: ApiSettings)
: Promise<AggregateReportCampaignListItem[]> {
const response = await apiFetch<{campaigns: AggregateReportCampaignListItem[]}>(settings, "/api/v1/campaigns/aggregate-reports");
return response.campaigns;
}
export async function listCampaignsDelta(
settings: ApiSettings,
options: {since?: string | null;limit?: number;} = {})
@@ -833,6 +887,16 @@ versionId?: string)
return apiFetch<CampaignSummary>(settings, `/api/v1/campaigns/${campaignId}/report?${params.toString()}`);
}
export async function getAggregateCampaignReport(
settings: ApiSettings,
campaignId: string)
: Promise<AggregateCampaignReport> {
return apiFetch<AggregateCampaignReport>(
settings,
`/api/v1/campaigns/aggregate-reports/${encodeURIComponent(campaignId)}`
);
}
export async function downloadCampaignJobsCsv(
settings: ApiSettings,
campaignId: string,