Skip to content

Feature/unregister doctor for camp

Mukthanand Reddy M requested to merge feature/unregister-doctor-for-camp into develop

Overview

Updates the doctor camp registration endpoint to support both register and unregister actions through a single endpoint, while preserving doctor camp-visit history for analytics and audit use cases.

What does this MR do and why?

Previously, unregistering a doctor deleted the CampVisit row entirely, causing permanent loss of historical participation data. This MR introduces a soft-unregister approach — setting attendance = false instead of deleting the record — so camp analytics and audit trails remain intact.

The register/unregister actions are unified under a single endpoint using a register boolean flag in the request body, keeping the API surface minimal and consistent.

Changes Made

  • app/schemas/doctor.py — Added DoctorRegisterSchema
  • app/services/doctor_service.py — Updated register_doctor_for_camp with reactivation logic; added unregister_doctor_for_camp with soft-delete
  • app/api/v1/routes/doctor_routes.py — Updated endpoint to accept DoctorRegisterSchema body and branch on register flag
  • tests/test_api/test_doctor_routes.py — Updated tests for new request body contract; added unregister 400 test
  • tests/test_services/test_doctor_service.py — Added integration tests for reactivation, soft-unregister, and attendance filtering

Technical Details

Endpoint: POST /api/v1/doctors/{doctor_id}/register

Request body:

{ "register": true }

or

{ "register": false }

Register (register = true):

  • Registers the doctor for the latest medical camp
  • If no CampVisit record exists, a new one is created with attendance = true and signup = true
  • If a CampVisit already exists with attendance = false (previously unregistered), the existing record is reactivated — attendance = true, signup = true
  • Raises 400 if the doctor is already actively registered (attendance = true)

Unregister (register = false):

  • Does not delete the CampVisit record — preserves history for reporting and audit
  • Marks the doctor as inactive for the latest camp — attendance = false, signup = false
  • Raises 400 if the doctor has no active registration for the camp

Impact on existing endpoints: GET /api/v1/doctors/registered is unaffected — it continues to return only doctors where CampVisit.camp_id matches the selected/latest camp, CampVisit.camp_role = 'doctor', and CampVisit.attendance = true. Unregistered doctors are automatically excluded.

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
  • 🎨 UI/UX improvement
  • ️ Refactor (no functional changes)
  • Performance improvement
  • 🧪 Test update
  • 🔧 Configuration change
  • 🚨 Security fix

Related Issues / References

Screenshots or Screen Recordings

-1. image

-2. image

How to Set Up and Validate Locally

  1. Checkout this branch
  2. Start the backend services:
    docker compose up
  3. Run focused backend tests:
    pytest tests/test_api/test_doctor_routes.py tests/test_services/test_doctor_service.py -v
  4. To test manually via API:
    • Register a doctor: POST /api/v1/doctors/{doctor_id}/register with { "register": true }
    • Unregister the same doctor: POST /api/v1/doctors/{doctor_id}/register with { "register": false }
    • Verify the CampVisit row still exists in DB with attendance = false
    • Confirm GET /api/v1/doctors/registered no longer returns the unregistered doctor

Testing Done

  • Manual testing completed
  • Unit tests added/updated

Test Cases Covered:

Scenario Expected Result Status
Register a new doctor for a camp New CampVisit created with attendance = true
Re-register a previously unregistered doctor Existing CampVisit reactivated, not duplicated
Register an already active doctor 400 error returned
Unregister an active doctor CampVisit preserved, attendance = false
Unregister a doctor with no active registration 400 error returned
Fetch registered doctors after unregister Unregistered doctor excluded from results

Test results: 10 passed, 0 failed

Code Quality Checklist

Code Standards

  • Code follows project conventions (naming, structure, formatting)
  • No console.log() or debugger statements left in code
  • No unused imports, variables, or functions
  • No duplicate code and use of existing components for reusability
  • i18n check passed with no hardcoded strings in codebase for i18n support
  • TypeScript types are properly defined (no any unless justified)
  • ESLint and Prettier checks pass
    bun run lint

React Best Practices

  • Components are properly split and single-responsibility
  • Hooks follow rules (no conditional hooks, proper dependencies)
  • State management is appropriate (local vs global state)
  • No unnecessary re-renders (memoization used where needed)
  • Event handlers are properly cleaned up

Component Patterns

  • shadcn/ui components used correctly
  • Tailwind classes follow utility-first approach
  • Responsive design considered (mobile-first if applicable)
  • Accessibility attributes included (aria-*, role, etc.)
  • Icons from lucide-react used consistently

API & Data Fetching

  • TanStack Query used for server state (if applicable)
  • Loading and error states handled
  • API types defined in src/types/api.ts
  • Axios interceptors handle auth tokens correctly
  • Use of Zod for data validations

Error Handling

  • Errors are caught and handled gracefully
  • User-friendly error messages displayed
  • Errors are being toasted properly
  • Network failures handled appropriately

Documentation

  • README.md updated (if setup steps changed)
  • .env.example updated (if new env vars added)
  • CHANGELOG.md updated (if applicable)

Known Limitations / Technical Debt

None introduced. Historical CampVisit records with attendance = false will accumulate over time — a future cleanup/archival strategy may be worth considering for large-scale deployments.

Additional Notes

  • This is a backend-only MR. The corresponding frontend MR handles the unregister UI and calls this endpoint.
  • The register flag approach was chosen over separate /register and /unregister endpoints to keep the API surface lean and mirror how the frontend tracks state.

MR Acceptance Checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Mukthanand Reddy M

Merge request reports

Loading