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:
@@ -278,6 +278,16 @@ func (s *session) Data(r io.Reader) error {
|
||||
id, err := s.daemon.store.Save(context.Background(), raw, time.Now(), tenantID)
|
||||
if err != nil {
|
||||
s.daemon.stats.Rejected.Add(1)
|
||||
// PROJ-29: Quota exceeded — return 452 (Insufficient system storage) so
|
||||
// the sending MTA retries later. All other storage errors get 554.
|
||||
if errors.Is(err, storage.ErrQuotaExceeded) {
|
||||
s.daemon.logger.Warn("SMTP: quota exceeded", "from", s.from, "tenant", tenantID)
|
||||
return &smtp.SMTPError{
|
||||
Code: 452,
|
||||
EnhancedCode: smtp.EnhancedCode{4, 2, 2},
|
||||
Message: "Insufficient system storage — quota exceeded",
|
||||
}
|
||||
}
|
||||
s.daemon.logger.Error("SMTP: storage failed", "from", s.from, "err", err)
|
||||
return &smtp.SMTPError{
|
||||
Code: 554,
|
||||
|
||||
Reference in New Issue
Block a user