# InvitesController

> **File:** `src/EchoHub.Server/Controllers/InvitesController.cs`  
> **Kind:** class

```csharp
[ApiController]
[Route("api/invites")]
[Authorize]
[EnableRateLimiting("general")]
public class InvitesController : ControllerBase
```


InvitesController is the Admin-only API surface that manages invite codes used to gate registrations on this server. It stores codes in the server’s own database (via `EchoHubDbContext.InviteCodes`) and exposes endpoints to create, list, and revoke codes, keeping the lifetime and usage policy centralized on the local instance rather than a central service. Codes are generated by `GenerateCode` as unguessable, human-friendly strings in the form `XXXX-XXXX` drawn from a carefully chosen alphabet, and are surfaced to clients through a lightweight [`InviteDto`](../../EchoHub.Core/DTOs/InviteDtos.cs.md) via `ToDto`. Each operation is guarded by `GetCallerAsync(ServerRole.Admin)` to ensure only administrators can participate, with additional server-side validation of usage and expiration constraints. A hard cap of active invites (`MaxActiveInvites`) prevents unbounded growth, ensuring revocation activities stay in sync with availability. The controller logs creation and revocation events for auditability, reinforcing accountability around invite management.


## Remarks
InvitesController encapsulates invite-code policy in a single server-local component, enabling straightforward auditing and revocation without cross-service coordination. By keeping codes in this server’s own database, it offers immediate effect when invites are revoked and aligns with admin-driven registration flows. The combination of strict input validation, cryptographically strong code generation, and explicit admin authorization provides a clear boundary around who can issue or revoke invites and under what constraints.


## Notes
- The active-invite cap enforces a maximum of 200 invites with unused uses; attempting to create a new invite when this cap is reached results in a BadRequest and requires revoking unused invites first.
- Codes are stored in uppercase and normalized on revoke (via `FirstOrDefaultAsync` with a case-insensitive match); clients can supply codes in any case, but the server stores and compares in a normalized form.
- If an `ExpiresInHours` value is not supplied, `ExpiresAt` remains null, meaning the invite never expires. If supplied, it must be between 1 and 8760 hours (1 year).
