- Login 2FA via @Primary MfaFactorBackedTwoFactorServiceImpl (replaces legacy) - LincPay SMS OTP and SMTP email OTP with auto-promote to m_user_mfa_factor - Reusable EmailSenderService + EmailTemplateService (CBSnexora branding) - Admin OTP audit viewer (GET /v1/otp-logs) with paging, search, masking - Self-service MFA factor API at /v1/mfa/factors - READ_OTP_LOG permission + OTP Log Auditor role + bankadmin direct grant - JsonAuthenticationEntryPoint suppresses Basic-auth popup for SPA paths - TwoFactorAuthenticationFilter grants TWOFACTOR_AUTHENTICATED when no challenge - Soft-delete + audit columns + deletion audit + version on client tables - CIF number generator (TTYYYYNNNNNN format) - DocumentNotFoundExceptionMapper to silence noisy WARN logs on missing images - Liquibase migrations 0278-0291 (MFA, OTP log, audit/soft-delete, role wiring) Note: application.properties intentionally not committed — contains local DB and Gmail App Password fallbacks. Set SPRING_MAIL_PASSWORD, FINERACT_DEFAULT_TENANTDB_PWD, FINERACT_HIKARI_PASSWORD as env vars in prod. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>