Release govoplan-campaign v0.1.28: stabilize saving, review and delivery recovery
Module Package Release / publish-packages (push) Successful in 12s

This commit is contained in:
2026-09-08 01:32:26 +02:00
parent 1b32427813
commit c51fc180fb
111 changed files with 6905 additions and 980 deletions
@@ -0,0 +1,45 @@
import type { CampaignRecoveryChannel } from "../../../api/deliveryRecovery";
import { asRecord } from "../utils/campaignView";
export type ReportReconciliation = {
jobId: string;
kind: "outcome";
decision: "smtp_accepted" | "not_sent" | "imap_appended" | "imap_not_appended";
} | {
jobId: string;
kind: "claim";
channel: CampaignRecoveryChannel;
revision: string;
};
export function reportClaimRecovery(row: Record<string, unknown>, channel: CampaignRecoveryChannel): { eligible: boolean; revision: string } {
const metadata = asRecord(asRecord(row.recovery)[channel]);
const revision = typeof metadata.revision === "string" ? metadata.revision : "";
const state = String(channel === "smtp" ? row.send_status ?? "" : row.imap_status ?? "");
return { eligible: metadata.eligible === true && Boolean(revision) &&
(channel === "smtp" ? ["claimed", "sending"].includes(state) : state === "appending"), revision };
}
export function reportRetryableFailure(row: Record<string, unknown>): boolean {
return ["failed_temporary", "failed_permanent", "partially_accepted"].includes(String(row.send_status ?? ""));
}
export function reportUnattempted(row: Record<string, unknown>): boolean {
return ["not_queued", "cancelled", "queued"].includes(String(row.send_status ?? "")) &&
Number(row.attempt_count ?? 0) === 0 && Number(row.postbox_attempt_count ?? 0) === 0 &&
Number(row.print_attempt_count ?? 0) === 0 &&
row.build_status === "built" && ["ready", "warning", "needs_review"].includes(String(row.validation_status ?? ""));
}
export function reportRecoveryHints(row: Record<string, unknown>): string[] {
const activeChannels = [
...(["claimed", "sending"].includes(String(row.send_status ?? "")) ? ["smtp"] : []),
...(row.imap_status === "appending" ? ["imap"] : [])
];
return [...new Set(activeChannels.flatMap(channel => {
const metadata = asRecord(asRecord(row.recovery)[channel]);
if (metadata.eligible === true) return [];
return [metadata.reason === "live_claim" ? "i18n:govoplan-campaign.report_claim_still_active"
: "i18n:govoplan-campaign.report_claim_owner_unconfirmed"];
}))];
}