import { type PlatformOutcomeEvent, type PlatformRequestFailure, type PlatformRequestId, type PlatformRequestStatus, type ScopeId, type SendEmailRequest, type TenantId } from '@substrat-run/contracts'; import type { OperationContext } from './scope-host.js'; import type { SwitchSql } from './system-switch.js'; /** * Ask the platform to send one email, inside the operation (#2102). * * The send is a platform intent: a row written in this operation's transaction, so an * operation that throws afterwards sends nothing, and one that commits is delivered by the * platform's drain — retried while the provider defers it, and reported back as an * `email.sent`, `email.refused` or `email.dead-lettered` event on `mail.about` (or on the * intent, when the mail names no entity). The returned id is the `request` those events carry. * * Name the recipient's `subjectId` when they are a person in your data: the row holds their * address and the message, and that id is how a subject erasure finds and cancels it. * * Parsed here rather than at drain time, so a malformed address fails the operation that wrote * it, in front of the person who typed it, instead of a refusal event minutes later. Needs the * vertical's `emailSender` grant, as the relay always has; without it the send is refused. */ export declare function requestEmail(ctx: Pick, mail: Omit): PlatformRequestId; /** What the scope stamps on an outcome event it writes: the drain names the rest. */ export interface OutcomeEventStamp { tenantId: TenantId; scopeId: ScopeId; /** ISO 8601 — the settle's instant. */ now: string; mintEventId(ms: number): string; /** The deploy writing it, for the outbox's `version` column. */ version: string | null; } export interface PlatformRequestSettle { status: PlatformRequestStatus; result?: unknown; lastError?: string | null; failure?: PlatformRequestFailure | null; /** #2102: the event this settle writes into the scope, when it moves the row out of `pending`. */ event?: PlatformOutcomeEvent | null; } /** * Journal a platform-request outcome, and write its outcome event (#2102) — one step, so both * adapters say the same thing and the event commits with the settle or not at all. Run it in a * transaction. * * **Compare-and-set on `pending` (#1600 review).** The drain reads pending rows, runs a handler, * then settles — and between the read and the settle a subject erasure can redact the row. * Settling by `id` alone let that stale pass overwrite the redaction and write a provider's * reply, which can quote the person, back into `last_error`. A settle that finds the row * already terminal does nothing, deliberately silently — throwing would make the drain's * blanket catch retry a row that is correctly over. The event follows the same rule: written * only by the settle that actually moved the row, so a repeated settle never writes it twice. * * The event is refused (before anything is written) on a `pending` settle — an outcome event * says the request is over — and when its `request` is not the row being settled. */ export declare function settlePlatformRequestIn(db: SwitchSql, id: PlatformRequestId, outcome: PlatformRequestSettle, stamp: OutcomeEventStamp): void; //# sourceMappingURL=email-intent.d.ts.map