Campaign Draft
Il Campaign Draft è un aggregate operativo separato dall'Issue. Il workspace
Admin corrente espone soltanto prepare e content_upload, con attempt
immutabili e retry espliciti.
Obiettivo e transizione autorevole
flowchart TD
publish["Issue published"] -.->|"nessun side effect"| ready["Eleggibile"]
ready --> prepare["prepare"]
prepare --> draft["draft_created"]
draft --> upload["content_upload"]
upload --> content["content_uploaded"]
content -.->|"operazione separata"| schedule["scheduling"]
schedule -.->|"provider separato"| delivery["delivery"]
La freccia tratteggiata indica un confine, non un automatismo.
Input e fonti accettate
Un Issue è eleggibile soltanto se:
status: published;editorialStatus: approved;- quality gate verdi.
L'applicazione rende subject, HTML e testo dall'Issue Content canonico. Il target proviene dal catalogo server-owned e viene esposto come alias, display name e riferimento mascherato.
Attore e autorizzazione
L'identità deve possedere campaign:draft. Il browser seleziona soltanto un
target configurato, l'Issue e i metadati temporali richiesti. Credenziali,
lista reale e ID provider non sono input arbitrari del client.
Validazione e quality gate
L'API rilegge l'Issue, la configurazione e l'aggregate prima di ogni
operazione. Un Campaign Draft attivo duplicato è rifiutato. content_upload
richiede un provider draft esistente. Il retry è disponibile solo quando
proiettato dal server e crea un nuovo attempt collegato.
Responsabilità dell'AI
L'AI non partecipa alla preparazione. HTML e testo sono rendering deterministici del contenuto approvato; non vengono rigenerati dal modello.
Persistenza e audit in D1
issue_email_campaigns conserva lo stato corrente. Gli attempt conservano:
operationType:prepareocontent_upload;providerMode:mock,dry_runolive;- stato
pending,processing,succeeded,failedounknown; - parent del retry;
- evidenza provider sanitizzata.
Un attempt terminale non viene riscritto.
Evidenza di successo
Per prepare, richiedere attempt succeeded e provider draft autorevole. Per
content_upload, richiedere aggregate content_uploaded, attempt riuscito e
provider mode coerente.
mock e dry_run provano soltanto il contratto locale. Non provano una
chiamata Mailjet live.
Fallimento e recupero
Timeout o risposta ambigua producono unknown o fallimento sanitizzato. Non
inventare un ID provider. Usare l'azione retry solo se proiettata e creare un
nuovo attempt; per l'ambiguità provider seguire il
runbook diagnostico.
Effetti collaterali esclusi
La preparazione:
- non pubblica;
- non carica automaticamente il contenuto;
- non schedula;
- non invia;
- non gestisce contatti o consenso;
- non distribuisce Worker.
Il caricamento contenuto non schedula e non invia.
Contratto legacy di conferma
Il backend conserva un percorso di conferma che può sequenziare upload e
scheduling dopo una conferma esplicita. Non è l'operazione prepare e non è
esposto dal workspace Campaign Draft steady-state. Qualunque suo uso richiede
scope operativo distinto; il suo stato scheduled non è prova di delivery.