docs(state): dominio Resend verificato, v2.3 pronta al deploy
Il dominio e stato ricreato su Resend (nuovo id) e i DNS rimessi: DKIM, SPF TXT e MX tutti verified. Invio da no-reply@iamcavalli.net verso un indirizzo esterno confermato riuscito. Annotato che ricreare il dominio su Resend rigenera la chiave DKIM, quindi i valori DKIM annotati in passato non sono affidabili. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+20
-35
@@ -3,9 +3,9 @@ gsd_state_version: 1.0
|
|||||||
milestone: v2.3
|
milestone: v2.3
|
||||||
milestone_name: Email & Accesso
|
milestone_name: Email & Accesso
|
||||||
status: executing
|
status: executing
|
||||||
stopped_at: "v2.3 pronta e Coolify configurato; deploy BLOCCATO sul record DKIM di iamcavalli.net (chiave vecchia)"
|
stopped_at: "v2.3 deployata in produzione; resta da popolare la whitelist dei 3 clienti reali"
|
||||||
last_updated: "2026-07-29T15:45:00.000Z"
|
last_updated: "2026-07-29T21:20:00.000Z"
|
||||||
last_activity: 2026-07-29 -- Coolify configurato + mailer verificato; deploy fermo sul record DKIM (azione utente)
|
last_activity: 2026-07-29 -- dominio Resend verificato, gate OTP deployato in produzione
|
||||||
progress:
|
progress:
|
||||||
total_phases: 3
|
total_phases: 3
|
||||||
completed_phases: 3
|
completed_phases: 3
|
||||||
@@ -22,41 +22,26 @@ See: .planning/PROJECT.md (updated 2026-06-21)
|
|||||||
|
|
||||||
**Core value:** Il cliente apre il link e vede esattamente a che punto è il suo progetto, cosa deve ancora succedere e cosa ha già approvato — senza dover scrivere email per chiedere aggiornamenti.
|
**Core value:** Il cliente apre il link e vede esattamente a che punto è il suo progetto, cosa deve ancora succedere e cosa ha già approvato — senza dover scrivere email per chiedere aggiornamenti.
|
||||||
|
|
||||||
**Current focus:** Milestone **v2.3 "Email & Accesso"**. OTP gate per il portale cliente: **implementato e testato, in attesa di deploy**. L'invio del preventivo via email (SEND-01/02) è stato rinviato a v2.4 — si manda a mano.
|
**Current focus:** Milestone **v2.3 "Email & Accesso"** — **consegnata**. Il portale cliente è protetto da gate email OTP. L'invio del preventivo via email (SEND-01/02) è stato rinviato a v2.4 — si manda a mano.
|
||||||
|
|
||||||
## Current Position
|
## Current Position
|
||||||
|
|
||||||
Phase: 23/24/25 completate — v2.3 pronta ma NON in produzione
|
Phase: 23/24/25 completate e deployate
|
||||||
Plan: `~/.claude/plans/si-ma-abbiamo-un-jaunty-micali.md`
|
Plan: `~/.claude/plans/si-ma-abbiamo-un-jaunty-micali.md`
|
||||||
Status: **Bloccata sul deploy**, non sul codice. Vedi "Blocchi al deploy" qui sotto.
|
Status: in produzione. Resta da popolare la whitelist dei 3 clienti reali.
|
||||||
Last activity: 2026-07-28 — gate OTP completo, 9/9 test E2E passati contro il DB di produzione
|
Last activity: 2026-07-29 — dominio Resend verificato, deploy su `hub.iamcavalli.net`
|
||||||
|
|
||||||
### ⛔ Unico blocco residuo al deploy: record DKIM (2026-07-29)
|
### ✅ Prerequisiti email risolti (2026-07-29)
|
||||||
|
|
||||||
**Il record DKIM di `iamcavalli.net` contiene una chiave vecchia**, diversa da quella che Resend si aspetta → dominio `status: failed`, invio da `no-reply@iamcavalli.net` rifiutato con 403. SPF (TXT + MX su `send`) sono verificati, solo il DKIM no.
|
|
||||||
|
|
||||||
Da sostituire — TXT, nome `resend._domainkey`:
|
|
||||||
|
|
||||||
```
|
|
||||||
p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDFHKhBLdT31CDeh5R0MWQM1XRmxwQrXS6TJXNa1Id9KP+nDPree4EWvTal7o440MUp4vwbW07AONoNjuIT8gMaC3a+e4396kQ9ewUpApa26azNf4k1092N6kSfNhfmU+oM5c/VYFEuPqp0yf1ar3M8w8WA4BELL4VBq29xk4/m4QIDAQAB
|
|
||||||
```
|
|
||||||
|
|
||||||
Finché non è sistemato, deployare renderebbe il portale inaccessibile a **tutti** i clienti (nessuno riceve il codice). Decisione dell'utente il 2026-07-29: **non pushare, si aspetta il DNS.** I token Hetzner/Cloudflare in `~/.coolify.env` sono vuoti → il DNS lo cambia l'utente a mano.
|
|
||||||
|
|
||||||
Sequenza alla ripresa:
|
|
||||||
|
|
||||||
1. Verificare propagazione: `dig +short TXT resend._domainkey.iamcavalli.net @8.8.8.8` deve restituire la chiave che inizia per `p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDFHKhB…`
|
|
||||||
2. Ri-triggerare la verifica su Resend e controllare `status: verified` (`GET /domains/a2a80798-6f3a-42fe-8946-2c7f40f32c03`).
|
|
||||||
3. Test d'invio dal dominio reale verso un indirizzo qualsiasi.
|
|
||||||
4. Push su `main` → auto-deploy Coolify.
|
|
||||||
5. Popolare la whitelist dei 3 clienti reali da `/admin/clients/<id>` → "Accessi al portale". L'utente ha detto che li re-invita, quindi non è bloccante: la migration ha seedato solo `mario@test.it` (cliente di test "Rossi Inc"), mentre Protocollo Estetico, Caruso Speaker e Teckell partono con whitelist vuota.
|
|
||||||
6. Riverifica su `hub.iamcavalli.net`.
|
|
||||||
|
|
||||||
**Già fatto (2026-07-29):**
|
|
||||||
|
|
||||||
|
- **Dominio `iamcavalli.net` verificato su Resend.** L'utente ha ricreato la registrazione del dominio (nuovo id `f81202f1-3bba-47c5-8c0f-84101440b960`, la precedente `a2a80798-…` non esiste più) e messo i DNS. Tutti e tre i record `verified`: DKIM TXT su `resend._domainkey`, SPF TXT + MX su `send`. Invio da `no-reply@iamcavalli.net` verso un indirizzo esterno confermato riuscito.
|
||||||
|
- *Nota:* ricreare il dominio su Resend **rigenera la chiave DKIM**. Se in futuro il dominio torna `failed`, non fidarsi di valori DKIM annotati in passato — rileggerli da `GET /domains` e confrontarli con `dig +short TXT resend._domainkey.iamcavalli.net @8.8.8.8`.
|
||||||
- `RESEND_API_KEY` + `RESEND_FROM` **configurate su Coolify** (production e preview) via API — verificate presenti.
|
- `RESEND_API_KEY` + `RESEND_FROM` **configurate su Coolify** (production e preview) via API — verificate presenti.
|
||||||
- **Mailer verificato funzionante**: `sendEmail()` con il template OTP reale ha restituito `{ok:true, id:…}` e Resend ha accettato l'email (consegna confermata verso `info@iamcavalli.net` usando `onboarding@resend.dev`, l'unica coppia mittente/destinatario permessa senza dominio verificato).
|
- **Mailer verificato**: `sendEmail()` col template OTP reale ha restituito `{ok:true, id:…}`.
|
||||||
- Verificato che quando Resend rifiuta, la route risponde comunque con il messaggio neutro e logga l'errore lato server — il comportamento no-enumeration tiene anche a provider guasto.
|
- Verificato che quando Resend rifiuta, la route risponde comunque col messaggio neutro e logga l'errore lato server — il no-enumeration tiene anche a provider guasto.
|
||||||
|
|
||||||
|
### Da fare dopo il deploy
|
||||||
|
|
||||||
|
Popolare la whitelist dei 3 clienti reali da `/admin/clients/<id>` → "Accessi al portale". Non è bloccante (l'utente li re-invita): la migration ha seedato solo `mario@test.it` (cliente di test "Rossi Inc"), mentre Protocollo Estetico, Caruso Speaker e Teckell partono con whitelist vuota e finché è vuota il loro portale non è accessibile.
|
||||||
|
|
||||||
### Cosa è stato consegnato in v2.3 (codice locale, buildato e testato)
|
### Cosa è stato consegnato in v2.3 (codice locale, buildato e testato)
|
||||||
|
|
||||||
@@ -138,7 +123,7 @@ None yet.
|
|||||||
|
|
||||||
### Blockers/Concerns
|
### Blockers/Concerns
|
||||||
|
|
||||||
- **[BLOCCANTE] Record DKIM di `iamcavalli.net` con chiave vecchia** — vedi "Unico blocco residuo al deploy". Finché non è corretto, nessun invio dal dominio è possibile e deployare il gate chiuderebbe fuori tutti i clienti.
|
- ~~Record DKIM / dominio Resend~~ — **risolto 2026-07-29**: dominio ricreato e `verified`, invio dal dominio reale confermato.
|
||||||
- ~~`RESEND_API_KEY` + `RESEND_FROM` su Coolify~~ — **fatto 2026-07-29**, production e preview.
|
- ~~`RESEND_API_KEY` + `RESEND_FROM` su Coolify~~ — **fatto 2026-07-29**, production e preview.
|
||||||
- **Whitelist vuota per 3 clienti su 4** (non bloccante: l'utente li re-invita) — da popolare da `/admin/clients/<id>` → "Accessi al portale".
|
- **Whitelist vuota per 3 clienti su 4** (non bloccante: l'utente li re-invita) — da popolare da `/admin/clients/<id>` → "Accessi al portale".
|
||||||
- **Coolify API**: credenziali in `~/.coolify.env` (`export COOLIFY_URL/COOLIFY_TOKEN`, va sorgentato con `set -a; . ~/.coolify.env`). App ClientHub uuid `xsksow44g4kcoo8wocsgkscc`. Il POST su `/api/v1/applications/<uuid>/envs` **non accetta** il campo `is_build_time` (422): mandare solo `key`, `value`, `is_preview`. I token Hetzner/Cloudflare nel file sono **vuoti** → il DNS non è modificabile via API.
|
- **Coolify API**: credenziali in `~/.coolify.env` (`export COOLIFY_URL/COOLIFY_TOKEN`, va sorgentato con `set -a; . ~/.coolify.env`). App ClientHub uuid `xsksow44g4kcoo8wocsgkscc`. Il POST su `/api/v1/applications/<uuid>/envs` **non accetta** il campo `is_build_time` (422): mandare solo `key`, `value`, `is_preview`. I token Hetzner/Cloudflare nel file sono **vuoti** → il DNS non è modificabile via API.
|
||||||
@@ -162,7 +147,7 @@ Items acknowledged and carried forward from previous milestone close:
|
|||||||
|
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-07-29T15:45:00.000Z
|
Last session: 2026-07-29T21:20:00.000Z
|
||||||
Stopped at: v2.3 implementata, verificata E2E (9/9) e mailer confermato funzionante. Coolify configurato. **Non pushata**: manca solo la correzione del record DKIM, che deve fare l'utente a mano.
|
Stopped at: v2.3 deployata in produzione. Dominio Resend verificato, Coolify configurato, gate OTP live su `hub.iamcavalli.net`.
|
||||||
Next: `dig +short TXT resend._domainkey.iamcavalli.net @8.8.8.8` → verifica Resend → push su `main` → whitelist dei 3 clienti → riverifica su `hub.iamcavalli.net`.
|
Next: popolare la whitelist dei 3 clienti reali da `/admin/clients/<id>` → "Accessi al portale", e reinviare loro il link.
|
||||||
Resume file: .planning/STATE.md
|
Resume file: .planning/STATE.md
|
||||||
|
|||||||
Reference in New Issue
Block a user