Full REST surface for /user/profile replaces upstream stub
Altien replaces upstream's single-method POST stub with four properly scoped endpoints: GET, PATCH, a credits increment, and DELETE /user/account with cascade. The whitelist-based PATCH and cascading account deletion are cleaner than anything upstream ships, regardless of whether you care about the Azure-specific pieces.
Commit ff992534 rewrites backend/src/routes/user.ts from roughly 10 lines to over 200. The old endpoint was a POST that upserted a blank profile row and returned { ok: true }. The new surface is four endpoints.
GET /user/profile returns the full profile row plus a global_api_keys map - booleans advertising which of Claude, Gemini, OpenAI, and Azure OpenAI have shared server-side keys configured. This lets the frontend show models as available without ever sending actual key values to the client. The GET also normalizes credits_reset_date: if the stored date has already elapsed, it resets the counter to zero and writes a new 30-day window before responding.
PATCH /user/profile uses an explicit allowlist of 11 fields (display_name, organisation, tabular_model, fast_model, and the four provider key/endpoint columns). Anything not on the list is silently ignored; an empty update body gets a 400. That's a meaningful improvement over the common pattern of passing req.body straight to the ORM.
DELETE /user/account cascades through every user-owned table and returns 403 in Entra mode, where account closure is the tenant admin's responsibility rather than the app's.
The auth.admin.deleteUser call that upstream used for deletion is gone. IdP teardown is deferred to the IdP, which is correct.
Spotted something wrong? Or know the PR text has fresher detail than the writeup above?