feat(PROJ-29): Tenant-Quotas & Usage-Limits vollständig implementiert
- storage/quota.go: SQL-Bug gefixt (emails.size → size_bytes, email_refs JOIN)
- tenantstore/quota.go: GetUsage nutzt jetzt email_refs JOIN für korrekte Tenant-Isolation
- smtpd: ErrQuotaExceeded → SMTP 452 statt 554 (MTA-retry statt permanent reject)
- admin_handlers: handleCreateUser prüft max_users-Quota → HTTP 402 bei Überschreitung
- quota_handlers: handleGetTenantUsage gibt jetzt warnings-Feld mit soft-limit-Prozenten zurück
- server.go: spec-konforme Alias-Route GET /api/admin/tenants/{id}/usage registriert
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -82,6 +82,18 @@ func (s *Server) handleCreateUser(w http.ResponseWriter, r *http.Request) {
|
||||
tenantID = sess.TenantID
|
||||
}
|
||||
|
||||
// PROJ-29: Enforce max_users quota before creating a new user.
|
||||
if tenantID != nil && s.tenantStore != nil {
|
||||
quota, qErr := s.tenantStore.GetQuota(r.Context(), *tenantID)
|
||||
if qErr == nil && quota.MaxUsers != nil {
|
||||
usage, uErr := s.tenantStore.GetUsage(r.Context(), *tenantID)
|
||||
if uErr == nil && int(usage.UserCount) >= *quota.MaxUsers {
|
||||
writeError(w, http.StatusPaymentRequired, "user quota exceeded")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
user, err := s.users.Create(userstore.CreateUserRequest{
|
||||
Username: req.Username,
|
||||
Email: req.Email,
|
||||
|
||||
Reference in New Issue
Block a user