Feature: The SPA can ask whether registration is currently open, without exposing anything else As the maintainer of RenewCMS I want a public, unauthenticated GET endpoint that reports whether registration is open, driven by the exact same rule CreateUserUseCase already enforces on POST /v1/auth/register, and that reveals nothing beyond that single boolean So that the SPA can decide whether to show a registration form before the user submits anything, without a second, drifting copy of the "is registration closed" rule and without leaking how many accounts exist or who they belong to Background: Given CreateUserUseCase already has a private registrationClosed() bool method that loops over user.Repository.GetAll() and returns true as soon as any existing user has IsVerified true; this slice exports that same check as a new method on CreateUserUseCase (e.g. IsRegistrationOpen() bool, returning the negation) so it can be called from outside the use case, and CreateUser itself keeps calling it exactly as before And this slice adds GET /v1/auth/registration, handled from the same handler package as POST /v1/auth/register (api/handlers/auth), reusing the same CreateUserUseCase instance the register handler already holds; no new use case, no new domain method beyond the exported check, and no second loop over user.Repository.GetAll anywhere in the handler And GET /v1/auth/registration is mounted in api/router.go's NewAuthRouter at the top level, outside every r.Group: not inside the jwtauth.Verifier/Authenticator group that guards /verify, DELETE /register and /me, and not inside either middleware.NewRateLimiter group that guards /login and /password-reset; no jwt cookie is ever read, parsed or validated for this route And the handler decodes no request body and reads no cookie and no claim; it calls CreateUserUseCase.IsRegistrationOpen(), sets the response header Cache-Control: no-store, and responds 200 with a JSON body containing exactly one field, "open", and nothing else: no user count, no usernames, no emails, no is_verified values Scenario: Registration is reported open while no verified account exists Given the user repository is empty When the client sends GET /v1/auth/registration with no jwt cookie Then the response status is 200 And the response header Cache-Control is "no-store" And the response body is exactly {"open": true} Scenario: Registration is reported open while every existing account is unverified Given the user repository contains a user "alice" with IsVerified false When the client sends GET /v1/auth/registration with no jwt cookie Then the response status is 200 And the response body is exactly {"open": true} Scenario: Registration is reported closed once a verified account exists Given the user repository contains a user "alice" with IsVerified true When the client sends GET /v1/auth/registration with no jwt cookie Then the response status is 200 And the response header Cache-Control is "no-store" And the response body is exactly {"open": false} Scenario: An expired, forged, or otherwise invalid jwt cookie makes no difference to the response Given the user repository contains a user "alice" with IsVerified true And the client holds a jwt cookie that is expired, forged, or otherwise invalid and would be rejected by jwtauth.Authenticator on any protected route When the client sends GET /v1/auth/registration with that cookie attached Then the response status is 200 And the response body is exactly {"open": false}, the same as a request with no cookie at all And the response does not set or clear any cookie And this proves the route never even attempts to parse or validate the cookie, not merely that a valid one would be ignored Scenario: The endpoint reveals nothing beyond the open flag Given the user repository contains three users, two verified and one unverified When the client sends GET /v1/auth/registration Then the response body's only top-level field is "open" And the response body contains none of: a user count, a username, an email, or an is_verified value Scenario: The route is never rate-limited, unlike login and password reset Given the user repository is empty When the client sends GET /v1/auth/registration 20 times in immediate succession from the same client Then every response status is 200 And none of the responses is 429 Scenario: The same rule CreateUser enforces is what answers this endpoint Given a user.Repository fake containing one user with IsVerified true And a CreateUserUseCase built directly over that fake, a hasher and a mail.Repository fake When IsRegistrationOpen is called Then it returns false And calling CreateUser on the same use case with a new username/email/password returns user.ErrRegistrationClosed, asserted with errors.Is