Companion to website#<pr>. Records Phase 1b as built, and corrects two things
the plan got wrong before anyone builds on them.
ENGAGEMENT.md
- Phase 1b step 2 said to pin the index to a case-insensitive collation. Every
_ci collation MariaDB offers here is also accent-insensitive, so that index
would refuse jose@x.com once josé@x.com existed and the de-duplication would
have cleared a legitimate account's address. The as-built block records the
generated-column design that shipped instead, and the second-order version of
the same bug that a seeded fixture caught in the de-dupe query itself.
- §0.6 named two callers of isDuplicateUsername(). There are five, and the
three it omits fail worse than the two it names.
BACKEND_DESIGN.md — the users table (already stale: it predated the player
account work), plus email_verifications and email_dedupe_report, and the five
new routes.
UPGRADE_NOTES.md — an operator entry, because the de-duplication is the kind of
quiet change this file exists for: nothing breaks, and the affected users find
out the next time they try to reset a password.
api-route-inventory.json — regenerated from the manifest; still ungated.
Co-Authored-By: Claude <noreply@anthropic.com>
Engagement Phase 1's documentation (ENGAGEMENT.md §6.0b, row 1).
BACKEND_DESIGN.md §7 is REWRITTEN rather than amended, as the plan
requires: it documented Gmail OAuth2 as the mechanism. It now covers the
transport registry and why credentialFields is a single declaration
three consumers read, the credential blob and its fail-safe decrypt, the
no-phone-home rule and its CI guardrail, the three SMTP postures, why
Send test is the only verification left, the five failure contracts, and
the silent upgrade. The §2 tree, the PR-4 route-count note, the contact
row and the dashboard row are corrected alongside it — the dashboard now
returns warnings[].
UPGRADE_NOTES.md is new, and is the home for every later phase's
operator note as well (1b, 6, 10 and 13 each owe one). Newest first, and
scoped deliberately: an upgrade that needs nothing does not get an entry.
The entries worth writing are the ones that fail QUIETLY, which is
exactly what the Gmail removal does — mail stops, nothing errors, and
the only signal is a dashboard warning.
ENGAGEMENT.md records Phase 1 as built, with the four things that are
not what the plan says: only the transport half of §3.1 was built (a
channel nothing calls is a shape frozen too early), `enabled` now gates
every sender where it used to gate none of the direct ones, the G22
warning reads the deprecated column on purpose, and `npm run swagger`
had to be fixed first — the "per-file route limit" phases 8 and 9
recorded does not exist, and the real rule matters to every later phase
here, all of which add routes.
Co-Authored-By: Claude <noreply@anthropic.com>