Skip to content

Commit c154575

Browse files
authored
Merge pull request #1 from ohcnetwork/v1-build-facility-demo-setup
Setup Demo facility plug V1 with generic data pack and integration with care_experience_sandbox
2 parents 1de08c5 + 6961956 commit c154575

82 files changed

Lines changed: 31042 additions & 18 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
---
2+
applyTo: "src/care_demo_facility_setup/services/**/*.{py},src/care_demo_facility_setup/tasks.py,src/care_demo_facility_setup/api/**/*.py"
3+
description: "Use when: working on CARE demo seed execution, CareFixtureBase integration, internal APIClient usage, Celery seed runs, or seed runner resource creation."
4+
---
5+
6+
# CARE demo seed client integration notes
7+
8+
## Use `CareFixtureBase` for CARE resource creation
9+
10+
The demo facility setup plugin should create CARE resources through the existing core fixture helper:
11+
12+
- `CareFixtureBase.create_facility(...)`
13+
- `CareFixtureBase.create_patient(...)`
14+
- later resource helpers such as locations, encounters, products, lab tests, etc.
15+
16+
This keeps seed execution aligned with CARE API behavior instead of bypassing serializers, permissions, validation, and side effects through direct model creation.
17+
18+
## Why `SeedAPIClient` exists
19+
20+
`SeedAPIClient` is not a replacement for `CareFixtureBase`.
21+
22+
It is an adapter for the DRF `APIClient` passed into `CareFixtureBase`.
23+
24+
The call flow is:
25+
26+
```text
27+
DemoSeedRunner
28+
→ CareSeedClient.create_facility(...)
29+
→ CareFixtureBase.create_facility(...)
30+
→ CareFixtureBase.post(...)
31+
→ SeedAPIClient.post(...)
32+
→ CARE DRF endpoint
33+
```
34+
35+
`CareFixtureBase` expects `self.client.get/post/patch(...)` to return a DRF response with `.data`.
36+
37+
In Celery/plugin runtime, plain `APIClient` can return Django redirect responses before DRF handles the request. That breaks `CareFixtureBase.post(...)`, because redirect responses do not have `.data`.
38+
39+
## Redirect issues handled by `SeedAPIClient`
40+
41+
`SeedAPIClient` handles two runtime issues.
42+
43+
### Trailing slash redirects
44+
45+
Django can redirect paths missing trailing slashes.
46+
47+
So `SeedAPIClient` normalizes request paths with a trailing slash before calling the parent `APIClient`.
48+
49+
### HTTP to HTTPS redirects
50+
51+
CARE may run with security middleware that redirects insecure internal requests:
52+
53+
```text
54+
http://testserver/api/...
55+
→ https://testserver/api/...
56+
```
57+
58+
So `SeedAPIClient` sets:
59+
60+
```python
61+
secure=True
62+
```
63+
64+
for internal `get`, `post`, and `patch` calls.
65+
66+
This prevents `HttpResponsePermanentRedirect` from reaching `CareFixtureBase`.
67+
68+
## Keep diagnostic response validation
69+
70+
`_ensure_drf_response(...)` should remain in place.
71+
72+
It catches unexpected non-DRF responses early and reports:
73+
74+
- path
75+
- status code
76+
- redirect location, if any
77+
78+
This gives a clear error instead of:
79+
80+
```text
81+
'HttpResponsePermanentRedirect' object has no attribute 'data'
82+
```
83+
84+
## Celery enqueueing must happen after DB commit
85+
86+
CARE uses `ATOMIC_REQUESTS=True`.
87+
88+
When a seed run is created from an API request, the `SeedRun` row is not visible to Celery until the request transaction commits.
89+
90+
Always enqueue real seed runs using:
91+
92+
```python
93+
transaction.on_commit(...)
94+
```
95+
96+
Otherwise the worker can receive the task too early and fail with:
97+
98+
```text
99+
SeedRun.DoesNotExist
100+
```
101+
102+
leaving the run stuck as `queued`.
103+
104+
## Phone number behavior
105+
106+
Do not store fixed real-looking phone numbers in seed JSON.
107+
108+
Use deterministic demo phone numbers generated from `SeedRun.id`:
109+
110+
- facility phone: unique per run
111+
- patient phone: unique per run and patient index
112+
113+
This keeps seed runs reproducible and avoids committing realistic contact data.
114+
115+
## Avoid `care_fixture_context()` in plugin runtime
116+
117+
Do not use `care_fixture_context()` for dashboard-triggered seed execution.
118+
119+
It is development fixture machinery and may:
120+
121+
- create/update the `admin` user
122+
- force-authenticate fixture clients
123+
- sync roles/valuesets
124+
- patch locks
125+
126+
For the plugin, create a controlled `APIClient`, authenticate it with the requesting superuser, and pass it into `CareFixtureBase`.

MANIFEST.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ recursive-exclude * __pycache__
88
recursive-exclude * *.py[co]
99

1010
recursive-include docs *.md Makefile *.jpg *.png *.gif
11+
recursive-include src/care_demo_facility_setup/data *.csv *.json
12+
recursive-include src/care_demo_facility_setup/seed_packs *.json

0 commit comments

Comments
 (0)