Context
Pre-existing issues surfaced during review of PR #149 (send invite email on user creation). These are out of scope for that PR but should be tracked.
Findings
High Priority
Medium Priority
Low Priority
Files
services/platform/apps/api/customers/views.py
services/platform/apps/customers/user_management_views.py
services/platform/apps/users/services.py
services/platform/templates/customers/emails/welcome_email.html
services/platform/templates/customers/emails/welcome_email.txt
Context
Pre-existing issues surfaced during review of PR #149 (send invite email on user creation). These are out of scope for that PR but should be tracked.
Findings
High Priority
Missing rate limiting on
customer_users_create—apps/api/customers/views.py:980. No@throttle_classesdecorator. A compromised portal token can create users in a loop, triggering unbounded email sending. Other similar endpoints (e.g.,update_customer_billing_addressat line 688) use@throttle_classes([BurstAPIThrottle]).Duplicate
_send_welcome_email_secureacross two service classes —apps/users/services.py:364(onSecureUserRegistrationService) andapps/users/services.py:854(onSecureCustomerUserService). Byte-for-byte identical. A bug fix to one won't propagate to the other. Extract to a standalone function or shared mixin.Medium Priority
Empty
company_nameproduces broken email text —apps/users/services.py:386. For individual-type customers,company_nameis blank. Email subject becomes "Account Created for " and body reads "You have been invited to join ." — confusing first impression. Fix: usecustomer.company_name or customer.name or "your organization".Private method
_send_welcome_email_securecalled from external modules —apps/api/customers/views.py:1029andapps/customers/user_management_views.py:123both call a_-prefixed method. Either rename tosend_welcome_email(public API) or add a public facade.No integration test for email rendering — All tests mock
_send_welcome_email_secure. No test verifies that templates render without error, that the token is valid, or thatsend_mailis called with correct context. Add at least one test using Django'smail.outbox.Low Priority
Hardcoded "2 hours" in email template —
templates/customers/emails/welcome_email.html:24. Should derive fromsettings.PASSWORD_RESET_TIMEOUT // 3600and pass as template context variable.Email not lowercased before DB lookup —
apps/api/customers/views.py:996andapps/customers/user_management_views.py:96.email.strip()without.lower()means case-mismatched duplicates hitIntegrityErrorinstead of clean duplicate message.Files
services/platform/apps/api/customers/views.pyservices/platform/apps/customers/user_management_views.pyservices/platform/apps/users/services.pyservices/platform/templates/customers/emails/welcome_email.htmlservices/platform/templates/customers/emails/welcome_email.txt