Skip to content

feat(auth, users): simplify login to book_no-based auth and add user identification endpoint

Mohana Sri Bhavitha requested to merge doctor/patient-login into develop

Merge Request

Overview

This MR simplifies the authentication flow by enforcing login strictly via book_no + password and introduces a new public endpoint to help users identify their accounts using phone_no + password.

It removes ambiguous multi-flow login logic and replaces it with a clear, secure, and user-friendly identification + login process.

What does this MR do and why?

Previously:

  • Login supported both phone_no and book_no, leading to ambiguity.
  • Multiple users could share the same phone number, causing confusion.
  • Forgot password flow had multiple branches and unnecessary complexity.

Now:

  • Login is simplified to book_no + password only
  • A new endpoint /api/v1/users/details allows users to:
    • Enter phone_no + password
    • Retrieve all associated accounts (book_no, name, age, role)
  • Forgot password flow is unified and simplified using book_no

This improves:

  • Clarity in authentication
  • Security (no ambiguous login paths)
  • Better UX for multi-account users

Changes Made

Authentication

  • Signup Flow (action = signup)
    • OTP is sent only if the phone number is not already registered
    • If user already exists → returns:
      • "User already exists. Please login or use forgot password"
    • If phone_no is missing → returns:
      • "Provide phone_no to send otp"
  • Forgot Password Flow (action = forgot_password)
    • OTP is sent only if the user exists for the given book_no
    • If user does not exist → returns:
      • "User not found"
    • If book_no is missing → returns:
      • "Provide book_no to send otp"
  • Response Improvement
    • Phone number is now masked in response:
      • Example: ******3210

New Endpoint

  • Added /api/v1/users/details (public endpoint)
    • Method: POST
    • Input: phone_no + password
    • Output:
      • All users linked to the phone number:
        • book_no
        • name
        • age
        • role
    • No authentication required

Forgot Password Refactor

  • Updated /api/v1/auth/forgot-password
    • Removed dropdown and multiple flows
    • Single unified flow for all users
    • Input:
      • book_no
      • user_password
      • confirm_password
      • otp
    • phone_no is now derived internally using book_no
    • Works for:
      • First-time users
      • Existing users resetting password

Swagger Improvements

  • Removed unnecessary dropdowns
  • Simplified examples for:
    • login
    • forgot-password
  • Updated documentation for new endpoint

Technical Details

  • Login logic now strictly queries user by book_no
  • User identification endpoint:
    • Validates password against any user linked to the phone number
    • Returns all associated accounts after successful validation
  • Forgot password:
    • Fetches phone number internally from book_no
    • Validates OTP against that phone number
  • Removed legacy branching logic for roles and first-time login

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to change)
  • 📝 Documentation update
  • ️ Refactor (no functional changes)
  • Performance improvement
  • 🧪 Test update
  • 🔧 Configuration change
  • 🚨 Security fix
  • 🗑️ Deprecation (removing deprecated code)

Related Issues / References

-closes #39 (closed)

Screenshots or Screen Recordings

Updated Swagger UI for:

  • Login (book_no only)
  • Forgot Password (single flow)
  • Users Details endpoint (multi-account response)

How to Validate Locally

Previous Behavior

  • Login allowed both phone_no and book_no
  • Multiple users per phone caused ambiguity
  • Forgot password had multiple flows

New Behavior

  1. Login:
    • Use book_no + password
    • Should return 200 on success
  2. User Identification:
    • Call /api/v1/users/details
    • Input: phone_no + password
    • Should return all linked accounts
  3. Forgot Password:
    • Use book_no + otp + new password
    • Password should update successfully

Testing Done

  • Unit tests added/updated
  • API endpoint tests passing

Test Cases Covered:

Scenario Expected Result Status
Login with phone_no Successful login
Login with invalid password Unauthorized
Fetch users with phone_no Returns all linked accounts
Forgot password with valid OTP Password updated
Foorgot password with invalid OTP Error response

Test Commands Run:

# Example: Run all tests
pytest

# Example: Run specific test file
pytest tests/test_api_v1/test_patient_routes.py -v

# Example: Run with coverage
pytest --cov=app

Code Quality Checklist

Code Standards

  • Code follows project conventions (naming, structure, formatting)

  • No debug statements or commented-out code left (unless necessary and intended)

  • No unused imports, variables, or functions

  • No duplicate code (DRY principle followed)

  • Type hints are properly defined (no Any unless justified and no mypy type check errors)

  • Ruff checks pass:

    ruff check .
    ruff format . --check

Python & FastAPI Best Practices

  • Functions follow single-responsibility principle
  • Async/await used correctly (no blocking calls in async functions)
  • Dependency injection used appropriately
  • Pydantic models used for request/response validation
  • SQLAlchemy queries are optimized (no N+1 queries)
  • Error handling is comprehensive (try/except with proper logging)

API Design

  • RESTful conventions followed
  • Proper HTTP status codes returned
  • Input validation implemented
  • Authentication/authorization enforced
  • Role Base access control used for user restriction
  • API documentation (docstrings) updated

Database & Migrations

  • Database migrations created (if schema changed)
  • Database migrations version is pointing to the latest version (and version name follows project conventions)
  • Migrations are reversible (migrations contain downgrade scripts)
  • Indexes added for frequently queried fields
  • No raw SQL queries (using SQLAlchemy ORM)
  • Data integrity constraints maintained

Security

  • No sensitive data logged (passwords, tokens, PII)

  • SQL injection prevention verified (ORM used)

  • Input sanitization implemented

  • Authentication tokens handled securely

  • CORS settings appropriate

  • Security scan passes:

    bandit -r app/

Error Handling

  • Errors are caught and handled gracefully
  • User-friendly error messages returned
  • Errors are logged appropriately
  • HTTP error responses follow API standards

Documentation

  • README.md updated (if setup steps changed)
  • .env.example updated (if new env vars added)
  • API documentation updated (docstrings, OpenAPI specs)
  • CHANGELOG.md will be updated (if applicable)
  • Code comments explain complex logic (not what, but why)

Known Limitations / Technical Debt

Additional Notes

Anything else reviewers should know

  • Improves usability for frontend integration and QA testing
  • No impact on production logic if OTP exposure is disabled later

MR Acceptance Checklist

Quality & Correctness

  • Code works as intended and solves the stated problem
  • No bugs introduced (existing functionality not broken)
  • Edge cases handled appropriately

Maintainability

  • Code is readable and well-organized
  • Code is testable and well-tested
  • Follows project patterns and conventions

Acceptance Review

  • Reviewed by at least 1 teammate
  • Reviewed by product owner
Edited by Mohana Sri Bhavitha

Merge request reports

Loading