feat(slice-4): honest delivery failure — send-before-commit + 502 delivery_failed (INV-9; closes #7)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-10 23:35:01 -07:00
parent 1b8c60fcb5
commit 22d738fc74
6 changed files with 77 additions and 12 deletions
+25 -12
View File
@@ -18,9 +18,16 @@ from datetime import datetime, timedelta, timezone
import psycopg
from app.platform import config
from app.platform.mailer import Mailer
from app.platform.mailer import Mailer, MailerError
from .errors import CodeExhausted, CodeExpired, CodeMismatch, InvalidEmail, ResendCooldown
from .errors import (
CodeExhausted,
CodeExpired,
CodeMismatch,
DeliveryFailed,
InvalidEmail,
ResendCooldown,
)
from .models import Account
# INV-3 constants — the one-time-code policy.
@@ -82,17 +89,23 @@ def request_code(conn: psycopg.Connection, mailer: Mailer, email: str) -> None:
"INSERT INTO auth_code (email, code_hash, expires_at) VALUES (%s, %s, %s)",
(email, _hash_code(code), now + CODE_TTL),
)
conn.commit()
mailer.send(
to=email,
subject=f"Your ecomm code: {code}",
body=(
f"Your ecomm one-time code is {code}.\n"
f"It is valid for {int(CODE_TTL.total_seconds() // 60)} minutes.\n"
"If you didn't request this, ignore this message."
),
)
# Send BEFORE commit (ecomm#7): a refused delivery rolls the row back, so no orphan
# code blocks the 60s cooldown and the caller can honestly retry at once (INV-9).
try:
mailer.send(
to=email,
subject=f"Your ecomm code: {code}",
body=(
f"Your ecomm one-time code is {code}.\n"
f"It is valid for {int(CODE_TTL.total_seconds() // 60)} minutes.\n"
"If you didn't request this, ignore this message."
),
)
except MailerError as exc:
conn.rollback()
raise DeliveryFailed(str(exc)) from exc
conn.commit()
def verify(conn: psycopg.Connection, email: str, code: str) -> tuple[Account, bool]: