feat: harden campaign delivery and editing

This commit is contained in:
2026-07-30 14:27:04 +02:00
parent 4a120e8009
commit cd223cbb95
34 changed files with 3370 additions and 165 deletions
+18 -4
View File
@@ -60,6 +60,8 @@ export type CampaignVersionListItem = {
id: string;
campaign_id: string;
version_number: number;
edit_revision: number;
strong_etag: string;
schema_version?: string;
source_filename?: string | null;
source_base_path?: string | null;
@@ -274,6 +276,9 @@ export type CampaignVersionUpdatePayload = {
source_filename?: string | null;
source_base_path?: string | null;
migrate_legacy_mail_settings?: boolean;
base_revision?: number;
reconciliation_kind?: "none" | "auto_merge" | "manual";
resolved_conflict_paths?: string[];
};
export type CampaignPartialValidationPayload = {
@@ -330,6 +335,7 @@ export type CampaignSummary = {
issues?: Record<string, unknown>;
attachments?: Record<string, unknown>;
attempts?: Record<string, unknown>;
postbox_receipts?: Record<string, unknown>;
delivery?: Record<string, unknown>;
recent_failures?: Record<string, unknown>[];
};
@@ -468,8 +474,11 @@ export type CampaignReviewStatePayload = {
};
export type CampaignSendJobPayload = {
kind: "test" | "single_send" | "single_resend";
idempotency_key: string;
reason?: string;
context?: Record<string, unknown>;
include_warnings?: boolean;
dry_run?: boolean;
use_rate_limit?: boolean;
enqueue_imap_task?: boolean;
};
@@ -520,6 +529,7 @@ export type CampaignReportEmailPayload = {
attach_jobs_csv?: boolean;
attach_report_json?: boolean;
dry_run?: boolean;
idempotency_key?: string;
};
export type AggregateReportCount = {
@@ -797,10 +807,12 @@ export async function updateCampaignVersion(
settings: ApiSettings,
campaignId: string,
versionId: string,
payload: CampaignVersionUpdatePayload)
payload: CampaignVersionUpdatePayload,
ifMatch: string)
: Promise<CampaignVersionDetail> {
return apiFetch<CampaignVersionDetail>(settings, `/api/v1/campaigns/${campaignId}/versions/${versionId}`, {
method: "PUT",
headers: { "If-Match": ifMatch },
body: JSON.stringify(payload)
});
}
@@ -821,10 +833,12 @@ export async function autosaveCampaignVersion(
settings: ApiSettings,
campaignId: string,
versionId: string,
payload: CampaignVersionUpdatePayload)
payload: CampaignVersionUpdatePayload,
ifMatch: string)
: Promise<CampaignVersionDetail> {
return apiFetch<CampaignVersionDetail>(settings, `/api/v1/campaigns/${campaignId}/versions/${versionId}/autosave`, {
method: "POST",
headers: { "If-Match": ifMatch },
body: JSON.stringify(payload)
});
}
@@ -1021,7 +1035,7 @@ export async function sendCampaignJob(
settings: ApiSettings,
campaignId: string,
jobId: string,
payload: CampaignSendJobPayload = {})
payload: CampaignSendJobPayload)
: Promise<Record<string, unknown>> {
return apiFetch<Record<string, unknown>>(settings, `/api/v1/campaigns/${campaignId}/jobs/${jobId}/send`, {
method: "POST",