Implemented - architecture - backend - openIMIS module
Overview
This architecture outlines a robust system for self-enrolled insuree login and OTP-based notifications within the OpenIMIS platform, extended via a custom membership pip package. The system supports secure authentication using JSON Web Tokens (JWT), OTP-based registration and verification, and Firebase Cloud Messaging (FCM) for notifications. It integrates with the OpenIMIS core, uses SQLite for local storage (demo purposes), and connects to external payment systems (e.g., PayPal) for enrollment.
The membership package is a modular extension of OpenIMIS, designed specifically for mobile app APIs. It encapsulates authentication, OTP handling, payment processing, and PDF slip generation, ensuring seamless integration with the OpenIMIS core.
Components
Membership Module (Django-based pip package):
A custom pip package integrated into OpenIMIS as a mobile app API extension.
Contains views (views.py), utilities (auth_helper.py, db_helper.py), and services for authentication, OTP management, and payment processing.
Uses Django REST Framework (DRF) for API endpoints and SimpleJWT for token-based authentication.
Database Layer:
SQLite (Local Storage): Stores temporary data such as OTPs, Firebase tokens, and payment transactions in tables like membership_insuree, firebase_tokens, and payment_transactions.
OpenIMIS Database (PostgreSQL/MySQL): Stores core data (e.g., Insuree, Family, User, InteractiveUser) and is queried for insuree details.
Synchronization occurs between SQLite and the OpenIMIS database for user and insuree data.
Notification System (Firebase):
Uses Firebase Cloud Messaging (FCM) to send OTP notifications to users’ mobile devices.
Stores FCM tokens in the firebase_tokens table for targeted notifications.
External Integrations:
PayPal Service: Handles payment processing for enrollments, with transaction details stored in SQLite.
Mailtrap (Sandbox): Used for email-based OTP delivery in development (replaceable with production-grade email/SMS services).
FHIR API: Supports querying insuree details via the PatientIdentifierAPIView.
Authentication System:
Leverages SimpleJWT for generating and validating JWT tokens.
Integrates with OpenIMIS core’s user_authentication service for credential verification.
System Architecture Diagram
Below is a high-level system architecture diagram showing the membership module’s integration with OpenIMIS and external services:
Login Flow
The login process authenticates users (insurees or officers) and issues JWT tokens for secure access.
Input Credentials: The user submits username and password via the mobile app’s login form.
API Request: The mobile app sends a POST request to the /signin endpoint (Signin view in views.py).
Authentication:
The Signin view calls authenticate_and_get_token (auth_helper.py), which uses OpenIMIS’s user_authentication service.
Credentials are validated against the User and InteractiveUser models in the OpenIMIS database.
The SQLiteHelper checks if the user is an insuree (is_insuree) and retrieves the associated insuree_id.
Token Generation:
If authentication succeeds, a JWT payload is created using jwt_payload (OpenIMIS core).
The payload is encoded into a JWT token using jwt_encode_user_key.
Response:
The API returns a JSON response containing:
access and refresh tokens.
User details (e.g., username, first_name, last_name, email).
Flags: is_officer, is_insuree.
insuree_info (if applicable, including chfid, uuid, family).
Login Flow
OTP Notification Flow
The OTP system supports user registration and verification, using Firebase for notifications and SQLite for OTP storage.
Initiate Registration:
The user submits registration details (e.g., chfid, head_chfid, phone, email) via the /register endpoint (RegisterAPIView).
The system verifies the insuree’s existence in the OpenIMIS database (Insuree model).
OTP Generation:
A 6-digit OTP is generated (random.randint(100000, 999999)).
The OTP, along with insuree_id, phone, and otp_expiry (5-minute validity), is stored in the membership_insuree table using SQLiteHelper.insert_user.
FCM Token Storage:
The mobile app sends the FCM token to the /save-firebase-token endpoint (SaveFirebaseTokenView).
The token is stored in the firebase_tokens table using SQLiteHelper.insert_fcm_token.
OTP Notification:
The system retrieves the FCM token using SQLiteHelper.get_fcm_token_by_user_id.
The OTP is sent via Firebase Cloud Messaging (FCM) with a payload:
json
Copy
{ "to": "<fcm_token>", "notification": { "title": "OTP Notification", "body": "Your OTP is <otp_code>" } }Alternatively, in development, OTPs are sent via Mailtrap (send_otp function).
OTP Validation:
The user submits the OTP and registration details to the /validate-otp endpoint (ValidateOTPAPIView).
The system verifies the OTP against the membership_insuree table, checking otp_code and otp_expiry.
If valid, a user is created (create_insuree_user) with the insuree role, and the user_id is updated in SQLite.
OTP Notification Flow
Key Implementation Details
Membership Module Structure:
Directory: membership/
views.py: Contains all API endpoints (e.g., Signin, RegisterAPIView, ValidateOTPAPIView, SaveFirebaseTokenView).
utils/auth_helper.py: Handles JWT authentication logic.
utils/db_helper.py: Manages SQLite interactions.
services.py: Includes services like PDFGenerationService and PayPalService.
apps.py: Configures the membership module as a Django app.
Integrated as a pip package in OpenIMIS’s INSTALLED_APPS.
Database Schema :
SQLite Tables:
membership_insuree:
sql
Copy
id (PK), insuree_id, phone (UNIQUE), otp_code, user_id, otp_expiry, created_atfirebase_tokens:
sql
Copy
id (PK), user_id, fcm_token (UNIQUE), created_atpayment_transactions:
sql
Copy
id (PK), family_id, paypal_transaction_id (UNIQUE), amount, status, validity_to, created_at
OpenIMIS Tables (partial):
core_user: Stores User and InteractiveUser data.
insuree_insuree: Stores insuree details (chf_id, phone, email).
insuree_family: Stores family relationships.
Authentication:
Uses SimpleJWT for token management.
Tokens are validated for protected endpoints (e.g., InsureeInformation, PolicyCreateAndUpdateAPIView).
Custom permission IsInsuree ensures only insuree users access specific APIs.
OTP Handling:
OTPs are valid for 5 minutes (otp_expiry = time.time() + 300).
OTPs are stored in SQLite and verified during registration/validation.
Resend functionality is supported via ResendOTPAPIView.
Notification System:
FCM is the primary notification channel, with Mailtrap as a fallback for email-based OTPs.
The FCM payload is lightweight and includes only essential data (title, body).
Future scalability: Replace Mailtrap with AWS SES or Twilio for production.
Payment Processing:
The EnrollmentView integrates with PayPalService for payment processing.
Payments are stored in the payment_transactions table with paypal_transaction_id and JSON payload.
Currency conversion (e.g., USD to NPR) is handled in EnrollmentView.
PDF Slip Generation:
The PrintPdfSlipView generates membership slips using PDFGenerationService.
Slips are returned as base64-encoded PDFs for mobile app rendering.
SQlite is for demonstration purpose, developer should generate real db tables using django migrations
Improvements Over Previous Architecture
Modular Design:
The membership package is explicitly defined as a pip-installable module, integrated into OpenIMIS.
Clear separation of concerns between views, utilities, and services.
Enhanced Notification System:
Incorporates FCM token storage and retrieval, missing in the previous design.
Supports fallback email OTP delivery via Mailtrap for development.
Robust Authentication:
Leverages OpenIMIS’s user_authentication service and SimpleJWT, ensuring compatibility with core security.
Includes is_insuree checks for role-based access control.
Detailed Diagrams:
Includes comprehensive flow diagrams for login and OTP processes, showing interactions between the mobile app, membership module, OpenIMIS core, SQLite, and external services.
Payment Integration:
Adds PayPal payment processing and transaction storage, enhancing enrollment functionality.
Scalability Considerations:
SQLite is used for demo purposes but can be replaced with a production-grade database (e.g., PostgreSQL) for local storage.
External services (FCM, PayPal, Mailtrap) are modular and replaceable.
Recommendations for Production and Future usage for implementators
Database:
Generate django migration instead of sqlite.
Proper indexing on membership_insuree.phone and firebase_tokens.fcm_token for performance.
Notifications:
Production-grade SMS/email service (e.g., Twilio, AWS SES) instead of Mailtrap.
Implement retry mechanisms for FCM failures.
Security:
HTTPS for all API endpoints.
Implement rate limiting on OTP-related endpoints to prevent abuse.
Store sensitive data (e.g., PayPal credentials) in environment variables.
RSA encryption for payload and server (SECURITY_FEATURES)
Monitoring:
logging for authentication failures, OTP generation, and payment processing.
Use a monitoring tool (e.g., Sentry) to track API errors.
Did you encounter a problem or do you have a suggestion?
Please contact our Service Desk
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. https://creativecommons.org/licenses/by-sa/4.0/