+
+
+
+
+
+
+
+ {validationStale && The stored validation result is no longer an active delivery lock. Run validation again.
}
+
+ void runValidation()}
+ disabled={!version || Boolean(busy) || userLockedVersion || finalVersion || readyForDelivery}
+ >
+ {busy === "validate"
+ ? "Validating…"
+ : readyForDelivery
+ ? "Validated and locked"
+ : validationPresent
+ ? "Validate again"
+ : "Validate campaign"}
+
+
+
+
+
+
+
+
+
+
+
+ {validationPresent && validationErrors === 0 && (
+ No blocking validation exceptions remain.
+ )}
+ {validationErrors > 0 && (
+ Resolve the blocking entries in the current issue table, then validate again.
+ )}
+
+ Open current issue table
+ Review attachment rules
+
+
+
+
+
+
+
+
+
+
+ Building resolves recipient values and attachment patterns into the exact message queue used by the later stages.
+
+ void runBuild()} disabled={!version || Boolean(busy) || !readyForDelivery || deliveryQueued || deliveryStarted}>
+ {busy === "build" ? "Building…" : hasBuild ? "Build again" : "Build exact messages"}
+
+
+
+
+
+
+
+
+
+
+
+ Use the Template preview to inspect rendered content and the actual managed files matched for individual recipients.
+
+ Open template review
+ setMessageReviewComplete((value) => !value)} disabled={!hasBuild}>
+ {messageReviewComplete ? "Message review completed" : "Mark message review complete"}
+
+
+
+
+
+
+
+
+
+
+
+ This uses the existing mock mailbox and failure-safe delivery path. It never marks the campaign as sent.
+
+ void runMockSend()} disabled={!version || Boolean(busy) || !messageReviewComplete || deliveryQueued || deliveryStarted}>
+ {busy === "mock" ? "Running mock delivery…" : mockResult ? "Run mock delivery again" : "Run mock delivery"}
+
+ Review server settings
+
+
+
+
+
+
Recipients {jobsTotal || "—"}
+
Messages to send {builtCount || jobsTotal || "—"}
+
Matched attachments {matchedAttachments || "—"}
+
Missing / ambiguous {missingAttachments} / {ambiguousAttachments}
+
Rate limit {messagesPerMinute > 0 ? `${messagesPerMinute}/min` : "Not set"}
+
Minimum duration {estimatedMinutes ? `about ${estimatedMinutes} min` : "—"}
+
IMAP append {Boolean(imapAppend.enabled) ? "Enabled" : "Disabled"}
+
Version {version ? `v${version.version_number}` : "—"}
+
+ The development page intentionally delegates the real-send action to the established page while this layout is evaluated.
+
+ Open final send controls
+
+
+
+
+
+
+
+
+
+
+
+
+ {deliveryStarted ? "Delivery activity is available in the report and audit views." : "No real delivery has started for this campaign version."}
+
+
+ Open report
+ Open audit log
+
+
+
+