Web Auth Signals
Location: api/nextango/apps/web_auth/
Last Updated: 2026-07-09
Overview
web_auth defines no Django signals. There is no signals.py in this app. Authentication, rate limiting, and session management run through explicit service method calls in the views, not through post_save, user_logged_in, or any other signal.
Why no signals
Authentication has a strict required order: a rate-limit or lockout check must happen before a credential check, and session creation must happen only after a successful check. Signals fire in response to model events that have already happened, which makes them a poor fit for logic that needs to run and potentially block before an action completes, and their execution order across multiple handlers is not guaranteed.
The views in this app call RateLimitService.check_failure_block(), then attempt authentication, then call RateLimitService.clear_failed_attempts() or RateLimitService.record_failed_attempt(), then SessionService.create_session(), each step visible in the view code. See services.md for what each service method does.
Known gaps
None specific to signal absence. Session and OTP records are plain model rows; bulk operations against them (OTPCode.objects.filter(...).update(...)) bypass save(), which is expected since the update paths in OTPService and SessionService already account for it explicitly rather than relying on save()-time side effects.
Where other domains do use signals
Other apps in this codebase use post_save and similar signals for non-critical work such as audit logging, cache invalidation, or async notification dispatch, where a missed or delayed handler does not compromise correctness. web_auth's authentication path does not have that tolerance, which is why it stays on explicit service calls.