feat(patient): add DOB support
Overview
This MR adds backend support for patient Date of Birth (DOB), including storage, API read/write support, estimated DOB fallback for legacy records, and an Alembic migration-chain repair required to run migrations successfully.
What does this MR do and why?
Previously, patient records mainly relied on age, which becomes stale over time and made accurate DOB tracking impossible for older records.
This MR introduces user_dob in backend storage, allows updating DOB through patient APIs, and returns a patient_dob_estimated flag so UI/workflows can identify records where DOB is inferred (not confirmed).
A migration-chain issue (Can't locate revision identified by 'bdf268c19712') blocked schema upgrades in this environment, so a no-op bridge migration was added to restore Alembic continuity safely.
Changes Made
- Added DB column
users.user_dobvia migration. - Added bridge migration for missing revision id.
- Updated patient schema/models/services to support:
patient_dobpatient_dob_estimated
- Added create/update handling:
- accept DOB
- derive/store age from DOB when DOB is provided
- Added response behavior:
- use real DOB when available
- fallback DOB as
YYYY-01-01for age-only legacy records - dynamic age derivation from DOB in patient responses
Technical Details
- Root issue:
- Missing DOB support in backend domain model and API contracts.
- Alembic chain broken due to absent revision
bdf268c19712.
- Fix approach:
- Schema: add nullable DOB column on
users. - Service layer: centralize user->patient response mapping and DOB/age logic.
- Migration chain: add no-op bridge revision and repoint downstream
down_revision.
- Schema: add nullable DOB column on
- Trade-off:
- Legacy records still rely on inferred DOB (
YYYY-01-01) until manually corrected.
- Legacy records still rely on inferred DOB (
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
- Related to patient DOB enhancement requirement.
- Fixes local migration-chain failure: missing revision
bdf268c19712.
Screenshots
PATCH /api/v1/patients/{book_no}
GET /api/v1/patients/{book_no}
-
PATCH /api/v1/patients/{book_no}with DOB payload -
GET /api/v1/patients/{book_no}showing:patient_dobpatient_agepatient_dob_estimated
How to Validate Locally
- Checkout branch:
feature/patient-dob-backend
- Run migration:
alembic upgrade head
- Login in Swagger and authorize token.
- Call:
PATCH /api/v1/patients/99992- Body:
{ "patient_dob": "2000-01-01" }
- Verify:
GET /api/v1/patients/99992
- Expected:
-
patient_dob=2000-01-01 -
patient_agederived from DOB -
patient_dob_estimated=false
-
- Validate legacy behavior with an age-only patient:
- fallback DOB is
YYYY-01-01 -
patient_dob_estimated=true
- fallback DOB is
Testing Done
-
Unit tests added/updated -
API endpoint tests passing
Test Cases Covered:
| Scenario | Expected Result | Status |
|---|---|---|
| PATCH patient with DOB | 200 OK, DOB saved, age updated | |
| GET patient after DOB update |
patient_dob real value, patient_dob_estimated=false
|
|
| Legacy patient without DOB | fallback DOB shown, patient_dob_estimated=true
|
|
| Alembic upgrade | migration reaches head without missing-revision error |
Test Commands Run:
alembic upgrade head
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 Anyunless 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.exampleupdated (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
- Legacy patients without real DOB still use inferred fallback (
YYYY-01-01) until manually corrected. -
user_ageremains present for backward compatibility. - Bridge migration is environment-repair oriented; should be retained to avoid chain breakage.
Additional Notes
- Branch:
feature/patient-dob-backend - Main commit includes backend model/schema/service/route updates plus migration fixes.
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



