feat: show cold rests without campaigns and explain deduplicated mailbox connection reports

This commit is contained in:
Matthew Meszaros
2026-10-16 07:30:19 +00:00
committed by Devin AI
parent 4d70aada93
commit ed76eb5ac0
10 changed files with 290 additions and 18 deletions
+2 -2
View File
@@ -5,6 +5,7 @@ import { browseString, mailboxSort, mailboxTab, type MailboxTab } from "@/lib/br
import { useSearchParams } from "@/hooks/useSearchParams";
import useMailboxTagFilter from "@/hooks/useMailboxTagFilter";
import groupMailboxes from "@/lib/groupMailboxes";
import { mailboxColdActivity } from "@/lib/mailboxStatus";
import { useAppStore } from "@/stores/useAppStore";
import toast from "react-hot-toast/headless";
import { useQueryClient } from "@tanstack/react-query";
@@ -1426,8 +1427,7 @@ function MailboxStatusPill({ box, status, historicalIssue, warming, compact = fa
const error = status?.errors?.[0];
const lifecycle = status?.send_lifecycle;
const inCampaign = !!status?.in_campaign;
const resting = inCampaign && !!lifecycle && lifecycle.state !== "active";
const sending = inCampaign && !resting;
const { resting, sending } = mailboxColdActivity(status);
let problem: { label: string; text: string; Icon: LucideIcon; title: string } | null = null;
if (box.status === "revoked") problem = { label: "Reconnect", text: "text-rose-600", Icon: UnplugIcon, title: "Access was revoked at the provider. Reconnect the mailbox to send and warm again." };
@@ -790,6 +790,7 @@ function OverviewTab({ status, loading, mailbox }: { status?: import("@/lib/api/
{status.errors.map((e: AccountError) => (
<div key={e.id} className="rounded-md border border-rose-200 bg-rose-50 px-3 py-2">
<div className="text-[12px] font-medium text-rose-800">{e.title}</div>
<div className="text-[10px] text-rose-700/80 mt-0.5">Last reported {new Date(e.created_at).toLocaleString()}{e.operation === "send" ? " · Sending" : e.operation === "sync" ? " · Mailbox sync" : ""}</div>
<div className="text-[11px] text-rose-700/90 mt-0.5 leading-relaxed">{e.message}</div>
{e.action_required && <div className="text-[11px] text-rose-900 mt-1 font-medium">{e.action_required}</div>}
{e.id === firstCredentialErrorId &&
@@ -18,6 +18,7 @@ export interface AccountError {
message: string;
action_required?: string;
created_at: Date;
operation?: "send" | "sync" | "unknown";
}
export interface AccountDailyUsage {
+22
View File
@@ -0,0 +1,22 @@
import { describe, expect, it } from "vitest";
import { mailboxColdActivity } from "./mailboxStatus";
describe("cold rotation activity", () => {
it.each(["resting", "reserve"] as const)("shows %s without a campaign on this instance", (state) => {
expect(mailboxColdActivity({ in_campaign: false, send_lifecycle: { state } })).toEqual({ resting: true, sending: false });
});
it.each(["resting", "reserve"] as const)("never reports %s as campaign sending", (state) => {
expect(mailboxColdActivity({ in_campaign: true, send_lifecycle: { state } })).toEqual({ resting: true, sending: false });
});
it("keeps older status responses without lifecycle compatible", () => {
expect(mailboxColdActivity({ in_campaign: true })).toEqual({ resting: false, sending: true });
expect(mailboxColdActivity({ in_campaign: false })).toEqual({ resting: false, sending: false });
expect(mailboxColdActivity()).toEqual({ resting: false, sending: false });
});
it("does not call a mailbox sending just because it is available for cold rotation", () => {
expect(mailboxColdActivity({ in_campaign: false, send_lifecycle: { state: "active" } })).toEqual({ resting: false, sending: false });
});
});
+7
View File
@@ -1,8 +1,15 @@
import type Inbox from "@/lib/api/models/app/emails/Inbox";
import type AccountStatus from "@/lib/api/models/app/analytics/AccountStatus";
import { diagnosticSendingAllowed, diagnosticWarmupActive } from "./diagnosticParticipation";
export type MailboxDisplayStatus = "healthy" | "warming" | "paused" | "inactive";
export function mailboxColdActivity(status?: Pick<AccountStatus, "send_lifecycle" | "in_campaign">) {
const lifecycle = status?.send_lifecycle;
const resting = !!lifecycle && lifecycle.state !== "active";
return { resting, sending: !!status?.in_campaign && !resting };
}
// Account activity is not proof of deliverability or reputation readiness.
export default function mailboxDisplayStatus(box: Inbox): MailboxDisplayStatus {
if (box.status !== "active") return "inactive";