feat(volunteer): add Corpus audio recording/upload in KYP with Corpus credential login
Overview
This MR adds an end-to-end Corpus workflow inside Volunteer KYP: record audio, add metadata/location, authenticate with Corpus phone/password, and upload audio to Corpus using chunked upload + finalize APIs.
It solves the gap where KYP had no integrated voice upload flow and where Corpus authentication had to be treated separately from eHRS authentication.
What does this MR do and why?
%{first_multiline_commit}
Motivation:
- Volunteers needed a direct audio capture + upload path in KYP.
- Corpus credentials differ from eHRS credentials, so upload auth must be verified against Corpus API.
Approach:
- Added Corpus feature modules (
components,hooks,services,types) undersrc/features/corpus. - Integrated those modules into KYP page.
- Implemented Corpus login API call (
/api/v1/auth/login) and persisted Corpus token/session for upload. - Added chunked upload + retry + finalize behavior and progress UI.
Trade-offs:
- Some Corpus login UI strings are currently hardcoded and should be fully moved to i18n in follow-up.
- JWT fallback extraction is used for userId if response structure varies.
Changes Made
- Added new Corpus feature files:
src/features/corpus/components/AudioRecorder.tsxsrc/features/corpus/components/UploadForm.tsxsrc/features/corpus/hooks/useRecorder.tssrc/features/corpus/hooks/useCorpusUpload.tssrc/features/corpus/services/corpusApi.tssrc/features/corpus/types.ts- Integrated Corpus card into
src/pages/volunteer/KYPPage.tsx. - Updated
src/contexts/AuthContext.tsxto exposeauthTokenvia context. - Added/updated locale strings in:
src/locales/en/translations.jsonsrc/locales/hi/translations.jsonsrc/locales/te/translations.json- Added API helper tests:
tests/features/corpus/corpusApi.test.ts- Added config variable in
.env.example: VITE_CORPUS_SERVER_URL=https://api.corpus.swecha.org
Technical Details
Root causes addressed:
- No recording/upload UI inside KYP.
- No robust chunk retry/finalization handling for Corpus API.
- No dedicated Corpus credential login path in the KYP upload section.
Architecture and data flow:
-
KYPPageorchestrates recorder + upload state. -
AudioRecorderhandles user interactions, delegates media behavior touseRecorder. -
UploadFormcollects title/description/location and now includes Corpus credential inputs. -
useCorpusUploadmanages upload state and Corpus session lifecycle. -
corpusApiservice encapsulates login, chunk upload, retry policy, and finalization.
State management:
- Local component state for form/recording interactions.
- Hook-managed upload stage and progress.
- Corpus token/userId persisted in localStorage for session continuity.
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
- Closes #248 (closed)
Screenshots or Screen Recordings
- Included in Comments | KYP had no integrated Corpus credential login and no recording/upload flow | KYP includes Corpus login fields (phone/password), recording controls, and upload status/progress |
How to Set Up and Validate Locally
- Checkout this branch.
- Install dependencies:
bun install - Ensure env has Corpus server URL:
# .env VITE_SERVER_URL=http://localhost:8000 VITE_SOCKET_URL=http://localhost:8000 VITE_CORPUS_SERVER_URL=https://api.corpus.swecha.org - Start app:
bun dev - Navigate to:
http://localhost:5173/volunteer/kyp
- Validate flow:
- Search/select a patient.
- In Corpus card, enter Corpus phone/password and login.
- Record audio.
- Enter title/description.
- Capture location.
- Upload audio.
- Expected behavior:
- Corpus login verifies against Corpus API.
- Upload progress/finalizing states are shown.
- Successful upload shows confirmation.
- Unauthorized/error states are handled with clear messages.
Backend note:
- Corpus endpoints must be reachable from frontend runtime.
Testing Done
-
Manual testing completed -
Unit tests added/updated
Test Cases Covered:
| Scenario | Expected Result | Status |
|---|---|---|
| Chunk split for >5MB file | File split into correct chunk sizes | |
| Retry on transient chunk failure | Retries with exponential backoff and succeeds | |
| Unauthorized during upload | Unauthorized callback invoked and error propagated | |
| Finalize payload fields | Required multipart fields are present and correct | |
| Corpus login missing credentials | Login blocked with validation message | |
| Upload without prerequisites | Upload disabled/blocked with guidance |
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 anyunless 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
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.exampleupdated (if new env vars added) -
CHANGELOG.md updated (if applicable)
Known Limitations / Technical Debt
- Some new Corpus login strings are currently hardcoded and should be migrated to i18n keys.
- Corpus user id extraction includes JWT fallback parsing due varying response shapes.
- Branch currently includes
ENABLE_VOLUNTEER_CAMP_GATING = false; confirm if this is intended for merge.
Additional Notes
- This MR combines two related scopes in one flow:
- Existing Corpus recording + chunked upload integration in KYP.
- Additional Corpus credential login in KYP upload panel.
- If preferred, this can be split into two MRs (upload infra vs credential login UX) for easier review.
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 Praneeth Ashish