import { domainSites, sitesOwnedBy } from "./store";
import { clearDomainLapse, lapsedDomainAccounts, startUnpaidGraceClocks } from "../billing/domain-addon";
import { releaseSiteDomain } from "./site";
/** Matches the 72 h stale-claim window that lets another site take an unverified domain over. */
const UNVERIFIED_CLAIM_MS = 72 * 60 * 60 * 1000;
const BATCH = 20;
const ACCOUNT_DOMAINS_PAGE = 100;
/** Never fully verified: no verification timestamp, and not currently active either. */
const NEVER_VERIFIED = "(domain_verified_at IS NULL AND (domain_status IS NULL OR domain_status NOT LIKE 'active%'))";
/** Cron: unverified custom domain claims older than the claim window lose their Cloudflare hostname. */
async function expireUnverifiedClaims(now: number): Promise<void> {
const cutoff = now - UNVERIFIED_CLAIM_MS;
const sites = (await domainSites(`${NEVER_VERIFIED} AND COALESCE(domain_claimed_at, updated_at) < ?`, cutoff)).slice(
0,
BATCH,
);
for (const site of sites) await releaseSiteDomain(site);
}
/** Cron: once a lapsed add-on's grace period ends, every custom domain of the account is unmapped and deleted. */
async function releaseLapsedAddons(now: number): Promise<void> {
for (const accountId of await lapsedDomainAccounts(now)) {
const sites = (await sitesOwnedBy(accountId))
.filter((site) => site.custom_domain !== null)
.slice(0, ACCOUNT_DOMAINS_PAGE);
for (const site of sites) await releaseSiteDomain(site);
if (sites.length < ACCOUNT_DOMAINS_PAGE) await clearDomainLapse(accountId);
}
}
export async function sweepCustomDomains(now = Date.now()): Promise<void> {
await expireUnverifiedClaims(now);
await startUnpaidGraceClocks(now);
await releaseLapsedAddons(now);
}