refactor(campaign): split review and recipient boundaries

This commit is contained in:
2026-07-30 01:01:26 +02:00
parent 23b9a531d5
commit 961d5d1130
12 changed files with 1860 additions and 1179 deletions
@@ -0,0 +1,66 @@
import { asArray, asRecord } from "../utils/campaignView";
export function formatAddressList(value: unknown): string {
return asArray(value).map(asRecord).map(formatSingleAddress).filter(Boolean).join(", ");
}
export function formatSingleAddress(value: unknown): string {
const address = asRecord(value);
const email = String(address.email ?? "").trim();
const name = String(address.name ?? "").trim();
if (name && email) return `${name} <${email}>`;
return email || name;
}
export function countResolvedAttachments(value: unknown): number {
const archives = new Set<string>();
let directCount = 0;
for (const item of asArray(value)) {
const attachment = asRecord(item);
const zipFilename = String(attachment.zip_filename ?? "").trim();
const managedCount = asArray(attachment.managed_matches).length;
const matchCount = asArray(attachment.matches).length;
if (zipFilename && (managedCount > 0 || matchCount > 0)) {
archives.add(zipFilename);
continue;
}
if (managedCount > 0) {
directCount += managedCount;
continue;
}
directCount += matchCount;
}
return directCount + archives.size;
}
export function numberFrom(record: Record<string, unknown>, keys: string[]): number {
for (const key of keys) {
const value = record[key];
if (typeof value === "number" && Number.isFinite(value)) return value;
if (
typeof value === "string" &&
value.trim() &&
Number.isFinite(Number(value))
) {
return Number(value);
}
}
return 0;
}
export function numberOrUndefined(value: unknown): number | undefined {
if (typeof value === "number" && Number.isFinite(value)) return value;
if (
typeof value === "string" &&
value.trim() &&
Number.isFinite(Number(value))
) {
return Number(value);
}
return undefined;
}
export function stringOrUndefined(value: unknown): string | undefined {
if (typeof value !== "string") return undefined;
return value.trim() || undefined;
}