Vai al contenuto

Runbook: eseguire il workflow newsletter via API

Obiettivo

Eseguire in ordine il percorso editoriale della newsletter tramite Admin API:

health → identità → fonti accepted → generazione → quality
→ approvazione esplicita → pubblicazione → readback → rendering email
→ verifica di zero effetti Mailjet

La collection dedicata è docs/postman/architecture-coffee-newsletter-workflow.postman_collection.json. L'environment di esempio sanitizzato è docs/postman/architecture-coffee-newsletter-workflow.postman_environment.example.json.

Inventario API esatto

Ordine Metodo e route Scopo Permesso applicativo
1 GET /health Health del Worker pubblico
2 GET /db/health Health D1 con query minima pubblico
3 GET /admin/auth/me Identità operatore sicura e permessi effettivi admin:read
4 GET /admin/editorial/topics?status=accepted&limit=100 Topic accettati admin:read
5 GET /admin/editorial/knowledge-assets?status=accepted&limit=100 Knowledge Asset accettati admin:read
6 POST /admin/issues/generation-jobs Richiesta asincrona di generazione issue:generate
7 GET /admin/issues/generation-jobs/{jobId} Poll bounded del job admin:read
8 GET /admin/issues/{slug} Readback del draft canonico admin:read
9 PUT /admin/issues/{slug}/draft Correzione opzionale con expectedRevision issue:draft
10 GET /admin/issues/{slug}/quality Quality gate deterministico admin:read
11 POST /admin/issues/{slug}/approve Approvazione attribuita all'operatore issue:review
12 POST /admin/issues/{slug}/publish Pubblicazione esplicita issue:publish
13 GET /issues/{slug} Readback pubblico del JSON canonico pubblico
14 GET /admin/issues/{slug}/email/html Rendering HTML canonico campaign:draft
15 GET /admin/issues/{slug}/email/text Rendering plain text canonico campaign:draft
16 GET /admin/issues/{slug}/email-campaign Stato Campaign Draft e attempt, sola lettura campaign:draft

La collection non include send-test, prepare, confirm, content_upload, schedule, deployment, archive, search, glossario o feedback analytics.

Configurazione rapida

  1. Importare collection ed environment di esempio.
  2. Duplicare l'environment in Postman; non modificare il file versionato.
  3. Selezionare baseUrl:
  4. http://127.0.0.1:8787 per il Worker locale;
  5. il valore di developmentBaseUrl per development remoto;
  6. productionBaseUrl soltanto in una futura Issue operativa autorizzata.
  7. Scegliere authMode:
  8. local-service per sviluppo locale;
  9. access-service per il workflow remoto completo.

Per access-service, conservare cfAccessClientId e cfAccessClientSecret soltanto nell'environment locale. Non esportare environment popolati e non estrarre cookie browser.

Esecuzione locale diretta

Preparare D1 locale e avviare il Worker:

npm run db:prepare:local
npm run dev:api

La generazione richiede OPENAI_API_KEY nel secret store locale del Worker. Allineare localAuthSubject al subject service locale. Lasciare:

authMode = local-service
allowMutations = true
allowProductionMutations = false
runDraftCorrection = false

Avviare la collection con Collection Runner in ordine. Un delay di un secondo tra le richieste rende leggibile il polling; pollLimit limita comunque il numero di tentativi e produce un errore esplicito. La collection cattura automaticamente topicId, generationJobId, issueId, slug, contenuto, revisione e timestamp: non copiare ID a mano.

Impostare runDraftCorrection = true soltanto dopo avere modificato canonicalContent nell'environment locale. La write usa la revisione letta dal server e fallisce con conflitto se il draft è cambiato.

Verifiche decisive

La run è valida soltanto se:

  • la richiesta senza autenticazione viene rifiutata;
  • /admin/auth/me restituisce un'identità service, un riferimento hash senza subject raw e i permessi richiesti;
  • Topic e Knowledge Asset selezionati sono accepted;
  • il job termina completed entro pollLimit;
  • il secondo read del job terminale è identico;
  • schema e quality risultano validi;
  • la pubblicazione prima dell'approvazione fallisce;
  • approvazione e pubblicazione restano due richieste distinte;
  • il readback pubblico coincide con il contenuto pubblicato;
  • HTML e plain text sono disponibili;
  • i conteggi di Campaign Draft e attempt dopo la pubblicazione coincidono con il baseline;
  • non esiste alcun nuovo stato scheduled o di delivery.

Controllo contenuto email

Sulle richieste 18 e 19 della collection verificare direttamente:

  1. nell'HTML, il <title> coincide con Architecture Coffee #<numero>: <titolo>;
  2. il preheader nascosto deriva dal sottotitolo e dal tempo di lettura;
  3. paragrafi, liste, blocchi tecnici e riferimenti HTTPS restano leggibili a larghezza mobile e desktop;
  4. i quattro link di feedback sono assoluti, usano https://api.architecturecoffee.it/f/{token} (o l'origine API dell'ambiente), sono identici per ogni destinatario, non contengono email o id sequenziali e aprono soltanto la pagina di ringraziamento del Worker;
  5. HTML e plain text contengono lo stesso significato, gli stessi riferimenti, la stessa domanda di feedback e il placeholder Mailjet [[UNSUB_LINK_EN]];
  6. il testo non contiene tag HTML, CSS o entità HTML residue.

Questi endpoint sono read-only: non preparano né caricano un Campaign Draft. Il controllo visuale può quindi essere ripetuto senza una nuova conferma.

Confini e stop

allowProductionMutations resta false. Non abilitarlo senza una Issue Production che descriva esattamente la mutazione e una PR mergiata da Fra. Questa collection non chiama Mailjet, non prepara Campaign Draft, non carica contenuto provider, non schedula, non invia e non esegue deployment.

Fermarsi se identità o permessi non corrispondono, il job fallisce, il polling scade, quality non passa, il readback diverge o cambia il conteggio Campaign Draft/attempt. Conservare soltanto status HTTP, ID applicativi non sensibili, stati, timestamp e diagnostica sanitizzata; mai cookie, credenziali, indirizzi destinatario o payload provider.