diff --git a/CLAUDE.md b/CLAUDE.md index 59ab674..0e6fe72 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -551,6 +551,20 @@ The control plane refuses to change an `hq`-sourced user's role or delete it the portal, but the API is the boundary; the UI is a courtesy. There is no local password-change endpoint at all, so there is no competing writer for the hash. +**A rename moves the host, and the licence does not care.** `PUT +/api/instances/:id/name` re-derives the slug from the new name through +`provision.RenameSlug` — the same rules that named the instance at creation — +and writes the control plane first, because `instances.slug`'s unique index is +what settles a race between two accounts reaching for one name. A taken slug is +a refusal, not an `acme-2`: creation appends a counter because any free slug +will do, and a rename is a request for one specific host. A licence binds the +instance UUID, so nothing is reissued and Paddle is not called. The old host +keeps resolving for up to 60s (`instancehost.go`'s cache, which admin cannot +reach into), and `km_session` is host-only, so the customer signs in again on +the new address — the portal says so rather than redirecting them into a login +screen with no explanation. The 24h cooldown lives on `admin_instances.renamed_at` +because it is admin's policy; staff bypass it and must not write the field. + --- ## Auth and Orgs @@ -692,6 +706,7 @@ GET /account # account, instances, max_relinks POST /instances # create a cloud instance (Free tier, one Free per account per deployment) POST /instances/:id/renew # Free renewal; refuses outside the renewal window POST /instances/:id/claim-free # issue Free on a linked self-hosted instance +PUT /instances/:id/name # rename a cloud instance; moves its slug (owner|admin, 24h cooldown) POST /instances/link · /instances/:id/relink GET /instances/:id/entitlement GET /checkout/options # active plans + catalogue prices for the running PADDLE_ENV @@ -717,6 +732,7 @@ Staff-session (`/api/staff`): GET,POST /accounts · GET /accounts/:id # search by name, email, Paddle ID or instance UUID GET,POST /instances · GET /instances/:id # instance + account + licence history + injection state POST /instances/:id/issue · /instances/:id/relink +PUT /instances/:id/name # rename any instance, no cooldown GET /licenses · /subscriptions · /audit · /plans · PUT /plans/:deployment/:tier GET,PUT /catalogue GET,PUT /instances/:id/entitlement