{"id":50742982,"url":"https://github.com/ohcnetwork/ccm_uhi","last_synced_at":"2026-06-10T18:30:42.002Z","repository":{"id":355762796,"uuid":"1229468760","full_name":"ohcnetwork/ccm_uhi","owner":"ohcnetwork","description":null,"archived":false,"fork":false,"pushed_at":"2026-06-01T12:44:40.000Z","size":137,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-01T14:23:40.019Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ohcnetwork.png","metadata":{"files":{"readme":"README.md","changelog":"HISTORY.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-05T04:31:56.000Z","updated_at":"2026-06-01T12:44:45.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ohcnetwork/ccm_uhi","commit_stats":null,"previous_names":["ohcnetwork/ccm_uhi"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ohcnetwork/ccm_uhi","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ohcnetwork%2Fccm_uhi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ohcnetwork%2Fccm_uhi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ohcnetwork%2Fccm_uhi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ohcnetwork%2Fccm_uhi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ohcnetwork","download_url":"https://codeload.github.com/ohcnetwork/ccm_uhi/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ohcnetwork%2Fccm_uhi/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34165482,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-10T02:00:07.152Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-10T18:30:40.478Z","updated_at":"2026-06-10T18:30:41.997Z","avatar_url":"https://github.com/ohcnetwork.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Care UHI\n\nDjango plugin for ohcnetwork/care.\n\n## Local Development\n\nTo develop the plug in local environment along with care, follow the steps below:\n\n1. Go to the care root directory and clone the plugin repository:\n\n```bash\ncd care\ngit clone git@github.com:ohcnetwork/Care UHI.git\n```\n\n2. Add the plugin config in plug_config.py\n\n```python\n...\n\nCare UHI_plugin = Plug(\n    name=Care UHI, # name of the django app in the plugin\n    package_name=\"/app/Care UHI\", # this has to be /app/ + plugin folder name\n    version=\"\", # keep it empty for local development\n    configs={}, # plugin configurations if any\n)\nplugs = [Care UHI_plugin]\n\n...\n```\n\n3. Tweak the code in plugs/manager.py, install the plugin in editable mode\n\n```python\n...\n\nsubprocess.check_call(\n    [sys.executable, \"-m\", \"pip\", \"install\", \"-e\", *packages] # add -e flag to install in editable mode\n)\n\n...\n```\n\n4. Rebuild the docker image and run the server\n\n```bash\nmake re-build\nmake up\n```\n\n\u003e [!IMPORTANT]\n\u003e Do not push these changes in a PR. These changes are only for local development.\n\n## Production Setup\n\nTo install care Care UHI, you can add the plugin config in [care/plug_config.py](https://github.com/ohcnetwork/care/blob/develop/plug_config.py) as follows:\n\n```python\n...\n\nCare UHI_plug = Plug(\n    name=Care UHI,\n    package_name=\"git+https://github.com/ohcnetwork/Care UHI.git\",\n    version=\"@master\",\n    configs={},\n)\nplugs = [Care UHI_plug]\n...\n```\n\n[Extended Docs on Plug Installation](https://care-be-docs.ohc.network/pluggable-apps/configuration.html)\n\n## API Reference\n\nAll endpoints are under the `/appointment/` router and accept `POST` requests with no authentication required.\n\n### 1. Search\n\n**`POST /appointment/search/`**\n\nSearches for available healthcare providers/services within a date range.\n\n```json\n{\n  \"context\": {\n    \"domain\": \"\u003cstring: domain code\u003e\",\n    \"country\": \"\u003cstring: ISO 3166-1 alpha-3\u003e\",\n    \"action\": \"search\",\n    \"transaction_id\": \"\u003cuuid\u003e\",\n    \"message_id\": \"\u003cuuid\u003e\",\n    \"consumer_id\": \"\u003cstring\u003e\",\n    \"consumer_uri\": \"\u003curl\u003e\"\n  },\n  \"message\": {\n    \"intent\": {\n      \"provider_id\": \"\u003cuuid\u003e\",\n      \"fulfillment\": {\n        \"type\": \"\u003cstring: physical | virtual\u003e\",\n        \"start\": { \"time\": { \"timestamp\": \"\u003cISO 8601 datetime\u003e\" } },\n        \"end\": { \"time\": { \"timestamp\": \"\u003cISO 8601 datetime\u003e\" } }\n      }\n    }\n  }\n}\n```\n\n### 2. Select\n\n**`POST /appointment/select/`**\n\nSelects a specific service item and fulfillment from a provider.\n\n```json\n{\n  \"context\": {\n    \"domain\": \"\u003cstring: domain code\u003e\",\n    \"country\": \"\u003cstring: ISO 3166-1 alpha-3\u003e\",\n    \"action\": \"select\",\n    \"transaction_id\": \"\u003cuuid\u003e\",\n    \"message_id\": \"\u003cuuid\u003e\",\n    \"consumer_id\": \"\u003cstring\u003e\",\n    \"consumer_uri\": \"\u003curl\u003e\"\n  },\n  \"message\": {\n    \"order\": {\n      \"descriptor_id\": \"\u003cuuid\u003e\",\n      \"item_id\": \"\u003cuuid\u003e\",\n      \"fulfillment_id\": \"\u003cuuid\u003e\"\n    }\n  }\n}\n```\n\n### 3. Init\n\n**`POST /appointment/init/`**\n\nInitializes an order with patient billing details.\n\n```json\n{\n  \"context\": {\n    \"domain\": \"\u003cstring: domain code\u003e\",\n    \"country\": \"\u003cstring: ISO 3166-1 alpha-3\u003e\",\n    \"action\": \"init\",\n    \"transaction_id\": \"\u003cuuid\u003e\",\n    \"message_id\": \"\u003cuuid\u003e\",\n    \"consumer_id\": \"\u003cstring\u003e\",\n    \"consumer_uri\": \"\u003curl\u003e\"\n  },\n  \"message\": {\n    \"order\": {\n      \"descriptor_id\": \"\u003cuuid\u003e\",\n      \"item_id\": \"\u003cuuid\u003e\",\n      \"fulfillment_id\": \"\u003cuuid\u003e\",\n      \"billing\": {\n        \"name\": \"\u003cstring\u003e\",\n        \"gender\": \"\u003cstring: male | female | transgender\u003e\",\n        \"date_of_birth\": \"\u003cdate: YYYY-MM-DD\u003e\",\n        \"year_of_birth\": \"\u003cinteger\u003e\",\n        \"blood_group\": \"\u003cstring: blood group enum\u003e\",\n        \"phone_number\": \"\u003cstring: E.164 phone\u003e\",\n        \"emergency_phone_number\": \"\u003cstring: E.164 phone\u003e\",\n        \"address\": \"\u003cstring\u003e\",\n        \"permanent_address\": \"\u003cstring\u003e\",\n        \"pincode\": \"\u003cinteger\u003e\",\n        \"geo_organization\": \"\u003cstring: state name\u003e\"\n      }\n    }\n  }\n}\n```\n\n### 4. Confirm\n\n**`POST /appointment/confirm/`**\n\nConfirms an order with agreed terms. Requires a valid `order_id` from a prior init/select flow.\n\n```json\n{\n  \"context\": {\n    \"domain\": \"\u003cstring: domain code\u003e\",\n    \"country\": \"\u003cstring: ISO 3166-1 alpha-3\u003e\",\n    \"action\": \"confirm\",\n    \"transaction_id\": \"\u003cuuid\u003e\",\n    \"message_id\": \"\u003cuuid\u003e\",\n    \"consumer_id\": \"\u003cstring\u003e\",\n    \"consumer_uri\": \"\u003curl\u003e\"\n  },\n  \"message\": {\n    \"order_id\": \"\u003cuuid\u003e\",\n    \"terms\": [\n      {\n        \"type\": \"\u003cstring: settlement | payment | cancellation\u003e\",\n        \"terms_state\": \"\u003cstring: agreed | disagreed\u003e\"\n      }\n    ]\n  }\n}\n```\n\n### 5. Status\n\n**`POST /appointment/status/`**\n\nChecks the status of an existing order. Requires a valid `order_id`.\n\n```json\n{\n  \"context\": {\n    \"domain\": \"\u003cstring: domain code\u003e\",\n    \"country\": \"\u003cstring: ISO 3166-1 alpha-3\u003e\",\n    \"action\": \"status\",\n    \"transaction_id\": \"\u003cuuid\u003e\",\n    \"message_id\": \"\u003cuuid\u003e\",\n    \"consumer_id\": \"\u003cstring\u003e\",\n    \"consumer_uri\": \"\u003curl\u003e\"\n  },\n  \"message\": {\n    \"order_id\": \"\u003cuuid\u003e\"\n  }\n}\n```\n\n### 6. Cancel\n\n**`POST /appointment/cancel/`**\n\nCancels an existing order. Requires a valid `order_id`.\n\n```json\n{\n  \"context\": {\n    \"domain\": \"\u003cstring: domain code\u003e\",\n    \"country\": \"\u003cstring: ISO 3166-1 alpha-3\u003e\",\n    \"action\": \"cancel\",\n    \"transaction_id\": \"\u003cuuid\u003e\",\n    \"message_id\": \"\u003cuuid\u003e\",\n    \"consumer_id\": \"\u003cstring\u003e\",\n    \"consumer_uri\": \"\u003curl\u003e\"\n  },\n  \"message\": {\n    \"order_id\": \"\u003cuuid\u003e\"\n  }\n}\n```\n\nThis plugin was created with [Cookiecutter](https://github.com/audreyr/cookiecutter) using the [ohcnetwork/care-plugin-cookiecutter](https://github.com/ohcnetwork/care-plugin-cookiecutter).\n\n---\n\n## Emergency Resource Request\n\n### 7. Emergency Request\n\n**`POST /emergency_request/`**\n\nCreates an emergency resource request to alert a facility about an incoming patient (e.g. ambulance transfer). Only one active request (status `pending` or `transfer_in_progress`) is allowed per patient.\n\n**Request:**\n\n```json\n{\n  \"provider_id\": \"\u003cuuid: facility external_id\u003e\",\n  \"patient\": {\n    \"name\": \"John Doe\",\n    \"phone_number\": \"9876543210\",\n    \"gender\": \"male\",\n    \"blood_group\": \"O+\",\n    \"abha_number\": \"12345678901234\",\n    \"date_of_birth\": \"1990-05-15\",\n    \"year_of_birth\": 1990,\n    \"address\": \"42, MG Road, Bengaluru, Karnataka, IND - 560001\",\n    \"permanent_address\": \"42, MG Road, Bengaluru, Karnataka, IND - 560001\",\n    \"pincode\": 560001\n  },\n  \"ambulance\": {\n    \"vehicle_number\": \"TS09AB1234\",\n    \"driver_name\": \"Ravi Kumar\",\n    \"driver_phone\": \"9876543210\",\n    \"eta_minutes\": 15,\n    \"notes\": \"Patient is conscious, minor head injury\"\n  },\n}\n```\n\n---\n\n## Notifications\n\nPatient notifications are pushed to the CCM gateway endpoint as fire-and-forget HTTP POST requests. They are triggered automatically via Django signals on booking/token state changes and dispatched through Celery tasks.\n\n### Payload Format\n\nAll notifications are sent as JSON with this structure:\n\n```json\n{\n  \"requestid\": \"\u003cUUID\u003e\",\n  \"fortype\": \"\u003cstring: notification type\u003e\",\n  \"patientid\": \"\u003cstring: patient ABHA identifier\u003e\",\n  \"notificationmessage\": \"\u003cstring: human-readable message\u003e\"\n}\n```\n\n### Notification Types \u0026 Triggers\n\n#### 1. Booking Confirmation\n\n**Trigger:** `TokenBooking` status changes to `booked` with a token assigned.\n\n**fortype:** `Booking`\n\n```json\n{\n  \"requestid\": \"EBA5D680-7989-4CF6-9B2A-3AF06030F5CA\",\n  \"fortype\": \"Booking\",\n  \"patientid\": \"91674538728603\",\n  \"notificationmessage\": \"Your appointment has been booked successfully. Booking ID: 30d00ccc-3121-4b15-b12e-45a1ac174f42, Patient: John Doe, Practitioner: Dr. Smith, Date \u0026 Time: 2026-06-01 10:00, Token Number: ccm-5\"\n}\n```\n\n#### 2. Reschedule\n\n**Trigger:** Reschedule API calls `OnConfirmService` internally to create a new booking, which triggers a `Booking` notification for the new appointment (same as a fresh booking).\n\n**fortype:** `Booking`\n\n```json\n{\n  \"requestid\": \"A1B2C3D4-5678-90AB-CDEF-1234567890AB\",\n  \"fortype\": \"Booking\",\n  \"patientid\": \"91674538728603\",\n  \"notificationmessage\": \"Your appointment has been booked successfully. Booking ID: 30d00ccc-3121-4b15-b12e-45a1ac174f42, Patient: John Doe, Practitioner: Dr. Smith, New Date \u0026 Time: 2026-06-02 14:00, Token Number: ccm-5\"\n}\n```\n\n\u003e **Note:** A reschedule also cancels the old booking, which triggers a separate `Cancellation` notification for the original appointment.\n\n#### 3. Cancellation\n\n**Trigger:** `TokenBooking` status changes to `cancelled`.\n\n**fortype:** `Cancellation`\n\n```json\n{\n  \"requestid\": \"F1E2D3C4-B5A6-9780-1234-ABCDEF567890\",\n  \"fortype\": \"Cancellation\",\n  \"patientid\": \"91674538728603\",\n  \"notificationmessage\": \"Your appointment has been cancelled. Booking ID: 30d00ccc-3121-4b15-b12e-45a1ac174f42, Patient: John Doe\"\n}\n```\n\n#### 4. Reminder (1 hour before appointment)\n\n**Trigger:** Scheduled automatically when a booking is confirmed; fires 1 hour before the slot start time.\n\n**fortype:** `Reminder`\n\n```json\n{\n  \"requestid\": \"12345678-ABCD-EF01-2345-6789ABCDEF01\",\n  \"fortype\": \"Reminder\",\n  \"patientid\": \"91674538728603\",\n  \"notificationmessage\": \"Reminder: Your appointment is scheduled in 1 hour. Booking ID: 30d00ccc-3121-4b15-b12e-45a1ac174f42, Patient: John Doe, Practitioner: Dr. Smith, Date \u0026 Time: 2026-06-01 10:00, Token Number: ccm-5\"\n}\n```\n\n#### 5. Queue Management — Position 5\n\n**Trigger:** Patient's token reaches position 5 in the active queue.\n\n**fortype:** `QueueManagement`\n\n```json\n{\n  \"requestid\": \"AABBCCDD-1122-3344-5566-778899AABBCC\",\n  \"fortype\": \"QueueManagement\",\n  \"patientid\": \"91674538728603\",\n  \"notificationmessage\": \"Queue update for token ccm-11. Current queue position: 5. You are 5th in the queue.\"\n}\n```\n\n#### 6. Queue Management — Next in Queue\n\n**Trigger:** Patient's token is next to be called (position immediately after the currently-called token).\n\n**fortype:** `QueueManagement`\n\n```json\n{\n  \"requestid\": \"11223344-AABB-CCDD-EEFF-556677889900\",\n  \"fortype\": \"QueueManagement\",\n  \"patientid\": \"91674538728603\",\n  \"notificationmessage\": \"Queue update for token ccm-12. Current queue position: 2. You are next in the queue.\"\n}\n```\n\n#### 7. Queue Management — Token Called\n\n**Trigger:** Patient's token status changes to `called` / `in_progress` / `ongoing` / `serving`.\n\n**fortype:** `QueueManagement`\n\n```json\n{\n  \"requestid\": \"EBA5D680-7989-4CF6-9B2A-3AF06030F5CA\",\n  \"fortype\": \"QueueManagement\",\n  \"patientid\": \"91674538728603\",\n  \"notificationmessage\": \"Queue update for token ccm-11. Current queue position: 7. Your token is currently being called.\"\n}\n```\n\n### Notification Flow\n\n1. Django signal (`post_save` on `TokenBooking` or `Token`) fires\n2. Celery task is dispatched (`.delay()`)\n3. Task resolves the patient's ABHA identifier\n4. `send_patient_notification()` builds payload and POSTs to endpoint\n5. Response is logged; failures are retried (max 2 retries)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fohcnetwork%2Fccm_uhi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fohcnetwork%2Fccm_uhi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fohcnetwork%2Fccm_uhi/lists"}