meta { name: Checkin seq: 9 } docs { ## Check-in — endpoints PUBLICS (pas d'auth Bearer) Le check-in est l'email envoyé à **l'utilisateur** (pas au client) pour confirmer qu'une facture a été payée AVANT que la première relance ne parte (cf. CLAUDE.md → Glossaire). Remplace l'intégration banking V1. ## Flow 1. Quand une facture avec un plan est créée, `scheduleCheckinForInvoice` enqueue un BullMQ job à `dueDate` (pile à l'échéance). 2. À l'exécution, `SendCheckinJob` envoie un email à l'user avec 2 liens : "C'est payé" et "Toujours en attente". 3. L'user clique → endpoint public ci-dessous → DB update + redirect SPA. ## Token - 32 bytes random base64url, généré au schedule. - Stocké hashé (SHA-256) en DB (CheckinTask.token_hash). - TTL 24h après envoi (sentAt + 24h). - Une seule réponse possible (idempotent : 2e click → already_answered). ## Pourquoi pas d'auth Bearer ? L'utilisateur clique depuis sa boîte mail — pas de session JS active. Le token est l'authentification : sa connaissance vaut autorisation (avec TTL 24h pour limiter la fenêtre de risque). ## Pour tester Crée une facture avec dueDate dans le passé (Invoices → 04 Create) : le check-in est programmé à `now + 1min`. ~1min plus tard, regarde Mailpit http://localhost:8025 → tu vois l'email avec les 2 liens. Copie le token de l'URL et utilise les requêtes Bruno ci-dessous. }