sos-portal-components-react 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,217 +1,229 @@
1
- # SOS Portal Components React
2
-
3
- ## Numbered engineering guides
4
-
5
- 1. [00 — Documentation index](docs/00-INDEX.md)
6
- 2. [01 — Portal modes, authentication and authority](docs/01-PORTAL_MODES_AND_AUTH.md)
7
- 3. [02 — Cross-portal Tuskr cases](docs/02-CROSS_PORTAL_TUSKR_CASES.md)
8
-
9
- Read these with the owning CH application's README for runnable commands and
10
- flavour configuration. The cases below retain their stable IDs; the numbered
11
- guides supply cross-portal steps, expected results and negative checks.
12
-
13
- Start dependencies by use case: local Demo UI/BFF uses the memory vault and
14
- no GW; clinical coding/cache cases add Terminology through its SDK, and call
15
- cases add LiveKit independently. Network cases progress from GW memory/test
16
- to local Fabric, then the chosen online `dev:staging` Test Network flavours.
17
- Demo stays BFF-only throughout. See the
18
- [dependency table](docs/01-PORTAL_MODES_AND_AUTH.md#11-start-dependencies-for-the-case-being-tested).
19
- Rerun the smallest failed/affected gate while retaining valid green evidence;
20
- release closure still requires every affected boundary.
21
-
22
- ## Runtime parity
23
-
24
- Components share use-case state between Demo and Test Network. Native support
25
- is export-specific: conversation uses the React Native/Web adapter; the device
26
- preferences renderer currently uses web DOM. A native preferences renderer
27
- remains future work. Components never select storage. Applications inject memory for
28
- all-local, Expo SQLite for native, or an explicit durable adapter. Firestore
29
- must not create a Demo-only component or data model.
30
-
31
- CH all-local portal execution does not start or require Chat, the telephone
32
- assistant or the optional web assistant. Realtime audio/video is a dedicated
33
- RTC boundary supplied by the host BFF. Invitations, terminal states and an
34
- optional unanswered audio attachment are rendered from Communications.
35
-
36
- Shared portal UI for base components. It provides the portal UI core for
37
- personal and professional applications across human
38
- health, animal care, public safety, emergency response and other configured
39
- sectors. The package exists to prevent each sector flavour from reimplementing
40
- the same shell, access journey, card navigation and governed subject workflows.
41
-
42
- Public Demo authenticates a real email account and uses BFF-validated synthetic
43
- profiles. Fixed Firebase test-phone codes belong only to tests in ignored
44
- configuration, never public Demo access. Demo business state stays behind the
45
- BFF Confidential Storage boundary; Test Network separately proves the complete
46
- organization/employee/subject lifecycle through its real authority and GW.
47
-
48
- The first implementation of a workflow may be proven in the animal-care
49
- portals. That does not make every future human-health consumer depend
50
- permanently on an animal-care component. Promotion into this package happens
51
- only after the shared contract is understood. Research, genomics and other
52
- specialist areas remain in their current package until their long-term
53
- boundary is deliberately chosen.
54
-
55
- ## Ownership boundaries
56
-
57
- - This package owns reusable portal presentation and controlled user intents.
58
- - Applications own branding, routes, environment selection, BFF calls and
59
- server-resolved sector/role policy.
60
- - `antifraud-hosting-components-react` owns neutral host- and
61
- tenant-controller administration. SOS may compose it but does not fork it.
62
- - `antifraud-portal-components-react` owns neutral evidence and conversation
63
- primitives used beyond health.
64
- - `terminology-components-react` owns terminology controls; the terminology
65
- service and SDK own canonical systems, releases and searches.
66
- - FHIR/SOS/Vet data utilities and SDKs own data contracts, validation,
67
- transport, signatures and persistence. React never derives authority.
68
- - Sector packages own their human-health, animal-care and other
69
- domain-specific extensions.
70
-
71
- Browser state, a visible tab or a selected role never grants authority. Every
72
- protected action is enabled from trusted host capabilities and remains
73
- revalidated by the BFF/Gateway.
74
-
75
- ## Implemented exports
76
-
77
- This is the current runtime inventory, not completion of the whole catalogue:
78
-
79
- | Export | Owner / responsibility |
80
- | --- | --- |
81
- | `SubjectConversationChat` | SOS projection of authorized subject Communications into the neutral Antifraud conversation renderer. |
82
- | `createLiveKitRealtimeCallClient` | Host-configured RTC client adapter; the BFF retains authorization, credentials and Communication persistence. |
83
- | `DeviceAssistancePreferences` | Reexport of Antifraud's controlled web preferences renderer. |
84
-
85
- The complete base-UI extraction is still pending. `PortalHeader`,
86
- `PortalSettingsPanel`, profile protection, subject/card navigation and several
87
- contact, permission and clinical controls remain in
88
- `uhc-portal-components-react`; application composition also remains in the
89
- owning portals. Research stays there pending its future owner. The catalogue
90
- below is acceptance scope and must not be read as an implemented export list.
91
- Controller administration is owned separately by
92
- `antifraud-hosting-components-react`.
93
-
94
- - `sos-portal-components-react/device-assistance-preferences` reexports the
95
- controlled `DeviceAssistancePreferences` owned by the neutral Antifraud
96
- package. Import `antifraud-portal-components-react/device-assistance-preferences.css`
97
- once in the application shell. It separates consent, runtime availability
98
- and explicit preparation; hosts supply localized labels, storage and runtime
99
- adapters. Rendering/toggling does not prepare a model or grant subject access.
100
- Use this independent entry on account pages to avoid loading conversation
101
- and RTC modules. Do not fork another device preferences panel per flavour.
102
-
103
- - `sos-portal-components-react/subject-conversation-chat` provides the
104
- canonical React Native/Web adapter for an already-authorized subject
105
- conversation. It projects the stable SOS entry model into the neutral
106
- Antifraud conversation surface backed by
107
- `@kesha-antonov/react-native-chat`. Hosts retain BFF delivery, attachment
108
- opening, FHIR rendering, WebRTC signaling and authorization.
109
-
110
- The compatibility export currently present in the human-health component
111
- package is deprecated and will delegate to this package while consumers move
112
- to the SOS-owned path.
113
-
114
- ## Tuskr use-case catalogue
115
-
116
- The stable IDs below are intended to become Tuskr cases. Each case must be
117
- executed for every applicable flavour, actor, viewport and environment. Demo
118
- uses synthetic state and must say so; Test Network and Production must use
119
- their real authorized BFF path.
120
-
121
- Use [02 — Cross-portal Tuskr cases](docs/02-CROSS_PORTAL_TUSKR_CASES.md)
122
- for Personal ↔ Professional prerequisites, numbered actions, both-side
123
- readback, rejected access, reset/revocation and execution evidence. A documented
124
- case is an acceptance target, not an end-to-end pass claim.
125
-
126
- | ID | Area | Governed journey and acceptance target |
127
- |---|---|---|
128
- | SOS-PORTAL-001 | Shell | Render the shared top bar, brand slot, account/profile menu, current subject and responsive navigation without flavour-specific forks. |
129
- | SOS-PORTAL-002 | Entry | Choose an enabled Demo, Test Network or Production entry supplied by trusted host configuration; a browser choice never selects network infrastructure. |
130
- | SOS-PORTAL-003 | Sign-in | Sign in through the host adapter, restore the exact protected profile and reject a profile belonging to another access path. |
131
- | SOS-PORTAL-004 | Biometrics | Unlock a protected profile with platform biometrics/passkey when available and use the governed PIN/password recovery fallback without exposing keys to React. |
132
- | SOS-PORTAL-005 | Registration | Register or accept an invitation for the applicable person, professional or animal-responsible profile; registration alone grants no subject access. |
133
- | SOS-PORTAL-006 | Cards | List only server-authorized individual or animal cards, select one card and preserve its stable identifier across navigation/reload. |
134
- | SOS-PORTAL-007 | Card sections | Resolve card sections from subject kind, sector, role and backend capabilities; hidden or read-only sections cannot be enabled by URL or browser state. |
135
- | SOS-PORTAL-008 | Identity | View and edit the permitted identity fields, provenance and attestations for a selected card while preserving immutable identifiers. |
136
- | SOS-PORTAL-009 | Related entities | Add, view, update or remove authorized related people, animals and organizations with explicit relationship type and provenance. |
137
- | SOS-PORTAL-010 | Contacts | Manage ordinary and emergency contacts independently, including priority, relationship, availability and emergency-only disclosure. |
138
- | SOS-PORTAL-011 | Encounters | List, open and author permitted encounters; bind contributions to the acting professional, organization, subject and server-confirmed scope. |
139
- | SOS-PORTAL-012 | Communications | Render one canonical conversation of DIDComm/FHIR Communications with text and governed attachments such as Bundles, documents, ICS, images and audio in both Personal and an authorized Professional card channel. |
140
- | SOS-PORTAL-013 | Calls | Initiate and display authorized audio/video calls and outgoing, incoming, completed, rejected, cancelled or missed call events without treating call signaling as clinical authority. |
141
- | SOS-PORTAL-014 | Appointments | Search availability and create, update or cancel appointments for applicable services, including blood-donation centres and other scheduled providers. |
142
- | SOS-PORTAL-015 | Clinical viewer | View authorized clinical documents, IPS summaries, sections, timelines and source/provenance details for human or animal cards. |
143
- | SOS-PORTAL-016 | Clinical authoring | Create and edit clinical documents through the canonical section-based editor, including encounters, observations, immunizations and host-enabled sections. |
144
- | SOS-PORTAL-017 | Credentials | Create, display, scan and verify supported health/data-card credentials and QR transports while keeping signing and verification outside React. |
145
- | SOS-PORTAL-018 | Permissions | View and change only permitted Consent/access relationships, group memberships and card grants; notifications never substitute for authorization. |
146
- | SOS-PORTAL-019 | Employee lifecycle | Compose the canonical Antifraud Hosting workforce screen for invitations, licences, employees and devices; SOS supplies sector labels and adapters, not a duplicate implementation. |
147
- | SOS-PORTAL-020 | Individual members | Manage an individual's authorized members/delegates separately from organization employees, with explicit lifecycle and revocation. |
148
- | SOS-PORTAL-021 | Emergency access | Show protected emergency data and request governed exceptional/break-glass access with reason, expiry, audit and clear post-access state. |
149
- | SOS-PORTAL-022 | Subject index | Display real index-update Communications from authorized providers and open linked records without manufacturing parallel chat events. |
150
- | SOS-PORTAL-023 | Provider directory | Select authorized card/index, clinical, appointment or emergency providers from host-supplied directories without hard-coded flavour endpoints. |
151
- | SOS-PORTAL-024 | Accessibility | Complete every shared journey by keyboard and screen reader with visible focus, labelled controls, status announcements and responsive layouts. |
152
- | SOS-PORTAL-025 | Expo reuse | Render platform-neutral contracts in Expo Android/iOS adapters and web adapters while retaining one message/card/action model and host-owned native capabilities. |
153
- | SOS-PORTAL-026 | Preferences | Reuse one device/account Preferences surface across modes: appearance, text size, locale, accessibility and actual speech/language-model enablement/availability/preparation, with explicit disabled states and no implied subject authorization. |
154
- | SOS-PORTAL-027 | Failure safety | Fail closed on missing capabilities, expired sessions, invalid attachments, unavailable providers or rejected persistence and preserve an actionable, non-sensitive error. |
155
- | SOS-PORTAL-028 | Controller embedding | In CH Management, embed the published Antifraud controller components for groups, departments, workforce and memberships until controller access is removed from branded professional portals. |
156
- | SOS-PORTAL-029 | Conversation threads | Open the individual card's root channel and authorized child threads for members, related entities or emergency contacts; each thread keeps stable subject/relationship/participant identifiers, and contact status alone grants no message access. |
157
-
158
- ### Communications execution matrix
159
-
160
- Tuskr must exercise `SOS-PORTAL-012`, `SOS-PORTAL-013` and
161
- `SOS-PORTAL-029` together:
162
-
163
- | Actor/surface | Root card channel | Authorized child thread | Required call events |
164
- |---|---|---|---|
165
- | Personal portal | View/send according to the individual's capability | Open a member, related-entity or emergency-contact thread only after the BFF confirms participation | outgoing, incoming, completed, rejected/cancelled and missed audio/video calls |
166
- | Professional portal | View/send in the selected individual's card channel only with professional subject scope | Open only child threads included in the professional's server-resolved scope | the same persisted call-event projection; no browser-manufactured duplicate |
167
- | Reload/cross-surface | Preserve stable channel, thread and message identifiers | Preserve the exact relationship reference and participant set | Personal and Professional render the same authorized event status and attachment metadata |
168
-
169
- Acceptance requires real persisted Communications (or the explicit synthetic
170
- Demo adapter), chronological projection without a parallel chat record, and
171
- negative tests proving that a contact listed for emergencies cannot enumerate
172
- or open a thread without separate authorization.
173
-
174
- ## Tracked specialist integration cases
175
-
176
- These cases must remain visible in Tuskr and in CH while they are migrated,
177
- but they are not owned by the initial SOS core package.
178
-
179
- | ID | Current owner | Planned direction | Acceptance target |
180
- |---|---|---|---|
181
- | HEALTH-RESEARCH-001 | Human-health components / host adapter | Candidate for animal-care components | Create, update, activate and revoke a research study with server-confirmed controller or delegated authority. |
182
- | HEALTH-RESEARCH-002 | Human-health components / host adapter | Candidate for animal-care components | Search and add authorized research subjects without turning discovery into access. |
183
- | HEALTH-RESEARCH-003 | Human-health components / host adapter | Candidate for animal-care components | Import research data, map source fields, track jobs and review/reclassify/discard staged records. |
184
- | HEALTH-RESEARCH-004 | Human-health components / host adapter | Candidate for animal-care components | Manage research contracts, study invitations, subscriptions and governed data access separately from ordinary card permissions. |
185
- | HEALTH-RESEARCH-005 | Human-health components / host adapter | Undecided specialist package | Use transcription/edge models and future genomic workflows only through explicit capability, provenance and privacy policy. |
186
-
187
- The current source inventory still contains host-local research panels.
188
- Migration is complete only when consuming portals import their published
189
- human-health implementation and the local alternatives are deprecated.
190
- Group-management source already lives in
191
- the Antifraud Controller application; its controlled UI must be exported by
192
- the Antifraud Hosting component package before CH can remove its final local
193
- group adapter.
194
-
195
- ## Explicitly outside the initial core
196
-
197
- - host registry, tenant admission and organization lifecycle policy (Antifraud
198
- Controller/Hosting);
199
- - research-study administration, research-subject import and genomic workflows
200
- (tracked above through their human-health to animal-care/specialist migration);
201
- - terminology databases and searches;
202
- - FHIR validation/conversion, DIDComm transport, wallets, signatures, QR
203
- cryptography, WebRTC signaling and persistence;
204
- - application-specific routes, branding and deployment configuration.
205
-
206
- ## Delivery order
207
-
208
- 1. Inventory the current verified components in deprecated sector portals,
209
- human-health components and consuming portal flavours.
210
- 2. Add a contract test for one canonical component per use case.
211
- 3. Move the current implementation without changing its data/authority
212
- boundary, then switch all CH flavours to the published package.
213
- 4. Mark old exports deprecated and keep their legacy tests separately runnable.
214
- 5. Add web plus Expo adapters only where the same controlled contract is
215
- genuinely reusable.
216
- 6. Remove compatibility implementations only in a later breaking release.
217
-
1
+ # SOS Portal Components React
2
+
3
+ ## Numbered engineering guides
4
+
5
+ 1. [00 — Documentation index](docs/00-INDEX.md)
6
+ 2. [01 — Portal modes, authentication and authority](docs/01-PORTAL_MODES_AND_AUTH.md)
7
+ 3. [02 — Cross-portal Tuskr cases](docs/02-CROSS_PORTAL_TUSKR_CASES.md)
8
+
9
+ Read these with the owning CH application's README for runnable commands and
10
+ flavour configuration. The cases below retain their stable IDs; the numbered
11
+ guides supply cross-portal steps, expected results and negative checks.
12
+
13
+ Start dependencies by use case: local Demo UI/BFF uses the memory vault and
14
+ no GW; clinical coding/cache cases add Terminology through its SDK, and call
15
+ cases add LiveKit independently. Network cases progress from GW memory/test
16
+ to local Fabric, then the chosen online `dev:staging` Test Network flavours.
17
+ Demo stays BFF-only throughout. See the
18
+ [dependency table](docs/01-PORTAL_MODES_AND_AUTH.md#11-start-dependencies-for-the-case-being-tested).
19
+ Rerun the smallest failed/affected gate while retaining valid green evidence;
20
+ release closure still requires every affected boundary.
21
+
22
+ ## Runtime parity
23
+
24
+ `SubjectCardLocatorFields` is a controlled web input, exported separately at
25
+ `sos-portal-components-react/subject-card-locator-fields`. It distinguishes
26
+ card number from DID/QR entry. For numbers, the user chooses person or animal;
27
+ animals also choose a supplied species or enter another NCBI taxonomy ID.
28
+ The host verifies those hints against the registered card. DID/QR lookup uses
29
+ the registered identity without asking the user to reinterpret its species.
30
+ The same renderer works in Demo and Network; it provides no authorization or
31
+ persistence and requires a native renderer before use in Expo.
32
+
33
+ Components share use-case state between Demo and Test Network. Native support
34
+ is export-specific: conversation uses the React Native/Web adapter; the device
35
+ preferences renderer currently uses web DOM. A native preferences renderer
36
+ remains future work. Components never select storage. Applications inject memory for
37
+ all-local, Expo SQLite for native, or an explicit durable adapter. Firestore
38
+ must not create a Demo-only component or data model.
39
+
40
+ CH all-local portal execution does not start or require Chat, the telephone
41
+ assistant or the optional web assistant. Realtime audio/video is a dedicated
42
+ RTC boundary supplied by the host BFF. Invitations, terminal states and an
43
+ optional unanswered audio attachment are rendered from Communications.
44
+
45
+ Shared portal UI for base components. It provides the portal UI core for
46
+ personal and professional applications across human
47
+ health, animal care, public safety, emergency response and other configured
48
+ sectors. The package exists to prevent each sector flavour from reimplementing
49
+ the same shell, access journey, card navigation and governed subject workflows.
50
+
51
+ Public Demo authenticates a real email account and uses BFF-validated synthetic
52
+ profiles. Fixed Firebase test-phone codes belong only to tests in ignored
53
+ configuration, never public Demo access. Demo business state stays behind the
54
+ BFF Confidential Storage boundary; Test Network separately proves the complete
55
+ organization/employee/subject lifecycle through its real authority and GW.
56
+
57
+ The first implementation of a workflow may be proven in the animal-care
58
+ portals. That does not make every future human-health consumer depend
59
+ permanently on an animal-care component. Promotion into this package happens
60
+ only after the shared contract is understood. Research, genomics and other
61
+ specialist areas remain in their current package until their long-term
62
+ boundary is deliberately chosen.
63
+
64
+ ## Ownership boundaries
65
+
66
+ - This package owns reusable portal presentation and controlled user intents.
67
+ - Applications own branding, routes, environment selection, BFF calls and
68
+ server-resolved sector/role policy.
69
+ - `antifraud-hosting-components-react` owns neutral host- and
70
+ tenant-controller administration. SOS may compose it but does not fork it.
71
+ - `antifraud-portal-components-react` owns neutral evidence and conversation
72
+ primitives used beyond health.
73
+ - `terminology-components-react` owns terminology controls; the terminology
74
+ service and SDK own canonical systems, releases and searches.
75
+ - FHIR/SOS/Vet data utilities and SDKs own data contracts, validation,
76
+ transport, signatures and persistence. React never derives authority.
77
+ - Sector packages own their human-health, animal-care and other
78
+ domain-specific extensions.
79
+
80
+ Browser state, a visible tab or a selected role never grants authority. Every
81
+ protected action is enabled from trusted host capabilities and remains
82
+ revalidated by the BFF/Gateway.
83
+
84
+ ## Implemented exports
85
+
86
+ This is the current runtime inventory, not completion of the whole catalogue:
87
+
88
+ | Export | Owner / responsibility |
89
+ | --- | --- |
90
+ | `SubjectConversationChat` | SOS projection of authorized subject Communications into the neutral Antifraud conversation renderer. |
91
+ | `createLiveKitRealtimeCallClient` | Host-configured RTC client adapter; the BFF retains authorization, credentials and Communication persistence. |
92
+ | `useRealtimeCallSessionLifecycle` | Shared persisted-end observation and profile-owned session cleanup for Personal and Professional, including React Strict Mode replay. |
93
+ | `DeviceAssistancePreferences` | Reexport of Antifraud's controlled web preferences renderer. |
94
+ | `PushNotificationRegistration` | Controlled browser-registration status, explicit enable and per-device revoke actions. The host owns permission, subscription/token, verified identity, BFF and transport. |
95
+ | `EmergencyContactCardDirectory` | Controlled card-linked emergency recipients and primary priority; host callbacks retain contact mutation, controller authority and persistence. |
96
+
97
+ The complete base-UI extraction is still pending. `PortalHeader`,
98
+ `PortalSettingsPanel`, profile protection, subject/card navigation and several
99
+ contact, permission and clinical controls remain in
100
+ `uhc-portal-components-react`; application composition also remains in the
101
+ owning portals. Research stays there pending its future owner. The catalogue
102
+ below is acceptance scope and must not be read as an implemented export list.
103
+ Controller administration is owned separately by
104
+ `antifraud-hosting-components-react`.
105
+
106
+ - `sos-portal-components-react/device-assistance-preferences` reexports the
107
+ controlled `DeviceAssistancePreferences` owned by the neutral Antifraud
108
+ package. Import `antifraud-portal-components-react/device-assistance-preferences.css`
109
+ once in the application shell. It separates consent, runtime availability
110
+ and explicit preparation; hosts supply localized labels, storage and runtime
111
+ adapters. Rendering/toggling does not prepare a model or grant subject access.
112
+ Use this independent entry on account pages to avoid loading conversation
113
+ and RTC modules. Do not fork another device preferences panel per flavour.
114
+
115
+ - `sos-portal-components-react/subject-conversation-chat` provides the
116
+ canonical React Native/Web adapter for an already-authorized subject
117
+ conversation. It projects the stable SOS entry model into the neutral
118
+ Antifraud conversation surface backed by
119
+ `@kesha-antonov/react-native-chat`. Hosts retain BFF delivery, attachment
120
+ opening, FHIR rendering, WebRTC signaling and authorization.
121
+
122
+ The compatibility export currently present in the human-health component
123
+ package is deprecated and will delegate to this package while consumers move
124
+ to the SOS-owned path.
125
+
126
+ ## Tuskr use-case catalogue
127
+
128
+ The stable IDs below are intended to become Tuskr cases. Each case must be
129
+ executed for every applicable flavour, actor, viewport and environment. Demo
130
+ uses synthetic state and must say so; Test Network and Production must use
131
+ their real authorized BFF path.
132
+
133
+ Use [02 — Cross-portal Tuskr cases](docs/02-CROSS_PORTAL_TUSKR_CASES.md)
134
+ for Personal ↔ Professional prerequisites, numbered actions, both-side
135
+ readback, rejected access, reset/revocation and execution evidence. A documented
136
+ case is an acceptance target, not an end-to-end pass claim.
137
+
138
+ | ID | Area | Governed journey and acceptance target |
139
+ |---|---|---|
140
+ | SOS-PORTAL-001 | Shell | Render the shared top bar, brand slot, account/profile menu, current subject and responsive navigation without flavour-specific forks. |
141
+ | SOS-PORTAL-002 | Entry | Choose an enabled Demo, Test Network or Production entry supplied by trusted host configuration; a browser choice never selects network infrastructure. |
142
+ | SOS-PORTAL-003 | Sign-in | Sign in through the host adapter, restore the exact protected profile and reject a profile belonging to another access path. |
143
+ | SOS-PORTAL-004 | Biometrics | Unlock a protected profile with platform biometrics/passkey when available and use the governed PIN/password recovery fallback without exposing keys to React. |
144
+ | SOS-PORTAL-005 | Registration | Register or accept an invitation for the applicable person, professional or animal-responsible profile; registration alone grants no subject access. |
145
+ | SOS-PORTAL-006 | Cards | List only server-authorized individual or animal cards, select one card and preserve its stable identifier across navigation/reload. |
146
+ | SOS-PORTAL-007 | Card sections | Resolve card sections from subject kind, sector, role and backend capabilities; hidden or read-only sections cannot be enabled by URL or browser state. |
147
+ | SOS-PORTAL-008 | Identity | View and edit the permitted identity fields, provenance and attestations for a selected card while preserving immutable identifiers. |
148
+ | SOS-PORTAL-009 | Related entities | Add, view, update or remove authorized related people, animals and organizations with explicit relationship type and provenance. |
149
+ | SOS-PORTAL-010 | Contacts | Manage ordinary and emergency contacts independently, including priority, relationship, availability and emergency-only disclosure. |
150
+ | SOS-PORTAL-011 | Encounters | List, open and author permitted encounters; bind contributions to the acting professional, organization, subject and server-confirmed scope. |
151
+ | SOS-PORTAL-012 | Communications | Render one canonical conversation of DIDComm/FHIR Communications with text and governed attachments such as Bundles, documents, ICS, images and audio in both Personal and an authorized Professional card channel. |
152
+ | SOS-PORTAL-013 | Calls | Initiate and display authorized audio/video calls and outgoing, incoming, completed, rejected, cancelled or missed call events without treating call signaling as clinical authority. |
153
+ | SOS-PORTAL-014 | Appointments | Search availability and create, update or cancel appointments for applicable services, including blood-donation centres and other scheduled providers. |
154
+ | SOS-PORTAL-015 | Clinical viewer | View authorized clinical documents, IPS summaries, sections, timelines and source/provenance details for human or animal cards. |
155
+ | SOS-PORTAL-016 | Clinical authoring | Create and edit clinical documents through the canonical section-based editor, including encounters, observations, immunizations and host-enabled sections. |
156
+ | SOS-PORTAL-017 | Credentials | Create, display, scan and verify supported health/data-card credentials and QR transports while keeping signing and verification outside React. |
157
+ | SOS-PORTAL-018 | Permissions | View and change only permitted Consent/access relationships, group memberships and card grants; notifications never substitute for authorization. |
158
+ | SOS-PORTAL-019 | Employee lifecycle | Compose the canonical Antifraud Hosting workforce screen for invitations, licences, employees and devices; SOS supplies sector labels and adapters, not a duplicate implementation. |
159
+ | SOS-PORTAL-020 | Individual members | Manage an individual's authorized members/delegates separately from organization employees, with explicit lifecycle and revocation. |
160
+ | SOS-PORTAL-021 | Emergency access | Show protected emergency data and request governed exceptional/break-glass access with reason, expiry, audit and clear post-access state. |
161
+ | SOS-PORTAL-022 | Subject index | Display real index-update Communications from authorized providers and open linked records without manufacturing parallel chat events. |
162
+ | SOS-PORTAL-023 | Provider directory | Select authorized card/index, clinical, appointment or emergency providers from host-supplied directories without hard-coded flavour endpoints. |
163
+ | SOS-PORTAL-024 | Accessibility | Complete every shared journey by keyboard and screen reader with visible focus, labelled controls, status announcements and responsive layouts. |
164
+ | SOS-PORTAL-025 | Expo reuse | Render platform-neutral contracts in Expo Android/iOS adapters and web adapters while retaining one message/card/action model and host-owned native capabilities. |
165
+ | SOS-PORTAL-026 | Preferences | Reuse one device/account Preferences surface across modes: appearance, text size, locale, accessibility and actual speech/language-model enablement/availability/preparation, with explicit disabled states and no implied subject authorization. |
166
+ | SOS-PORTAL-027 | Failure safety | Fail closed on missing capabilities, expired sessions, invalid attachments, unavailable providers or rejected persistence and preserve an actionable, non-sensitive error. |
167
+ | SOS-PORTAL-028 | Controller embedding | In CH Management, embed the published Antifraud controller components for groups, departments, workforce and memberships until controller access is removed from branded professional portals. |
168
+ | SOS-PORTAL-029 | Conversation threads | Open the individual card's root channel and authorized child threads for members, related entities or emergency contacts; each thread keeps stable subject/relationship/participant identifiers, and contact status alone grants no message access. |
169
+
170
+ ### Communications execution matrix
171
+
172
+ Tuskr must exercise `SOS-PORTAL-012`, `SOS-PORTAL-013` and
173
+ `SOS-PORTAL-029` together:
174
+
175
+ | Actor/surface | Root card channel | Authorized child thread | Required call events |
176
+ |---|---|---|---|
177
+ | Personal portal | View/send according to the individual's capability | Open a member, related-entity or emergency-contact thread only after the BFF confirms participation | outgoing, incoming, completed, rejected/cancelled and missed audio/video calls |
178
+ | Professional portal | View/send in the selected individual's card channel only with professional subject scope | Open only child threads included in the professional's server-resolved scope | the same persisted call-event projection; no browser-manufactured duplicate |
179
+ | Reload/cross-surface | Preserve stable channel, thread and message identifiers | Preserve the exact relationship reference and participant set | Personal and Professional render the same authorized event status and attachment metadata |
180
+
181
+ Acceptance requires real persisted Communications (or the explicit synthetic
182
+ Demo adapter), chronological projection without a parallel chat record, and
183
+ negative tests proving that a contact listed for emergencies cannot enumerate
184
+ or open a thread without separate authorization.
185
+
186
+ ## Tracked specialist integration cases
187
+
188
+ These cases must remain visible in Tuskr and in CH while they are migrated,
189
+ but they are not owned by the initial SOS core package.
190
+
191
+ | ID | Current owner | Planned direction | Acceptance target |
192
+ |---|---|---|---|
193
+ | HEALTH-RESEARCH-001 | Human-health components / host adapter | Candidate for animal-care components | Create, update, activate and revoke a research study with server-confirmed controller or delegated authority. |
194
+ | HEALTH-RESEARCH-002 | Human-health components / host adapter | Candidate for animal-care components | Search and add authorized research subjects without turning discovery into access. |
195
+ | HEALTH-RESEARCH-003 | Human-health components / host adapter | Candidate for animal-care components | Import research data, map source fields, track jobs and review/reclassify/discard staged records. |
196
+ | HEALTH-RESEARCH-004 | Human-health components / host adapter | Candidate for animal-care components | Manage research contracts, study invitations, subscriptions and governed data access separately from ordinary card permissions. |
197
+ | HEALTH-RESEARCH-005 | Human-health components / host adapter | Undecided specialist package | Use transcription/edge models and future genomic workflows only through explicit capability, provenance and privacy policy. |
198
+
199
+ The current source inventory still contains host-local research panels.
200
+ Migration is complete only when consuming portals import their published
201
+ human-health implementation and the local alternatives are deprecated.
202
+ Group-management source already lives in
203
+ the Antifraud Controller application; its controlled UI must be exported by
204
+ the Antifraud Hosting component package before CH can remove its final local
205
+ group adapter.
206
+
207
+ ## Explicitly outside the initial core
208
+
209
+ - host registry, tenant admission and organization lifecycle policy (Antifraud
210
+ Controller/Hosting);
211
+ - research-study administration, research-subject import and genomic workflows
212
+ (tracked above through their human-health to animal-care/specialist migration);
213
+ - terminology databases and searches;
214
+ - FHIR validation/conversion, DIDComm transport, wallets, signatures, QR
215
+ cryptography, WebRTC signaling and persistence;
216
+ - application-specific routes, branding and deployment configuration.
217
+
218
+ ## Delivery order
219
+
220
+ 1. Inventory the current verified components in deprecated sector portals,
221
+ human-health components and consuming portal flavours.
222
+ 2. Add a contract test for one canonical component per use case.
223
+ 3. Move the current implementation without changing its data/authority
224
+ boundary, then switch all CH flavours to the published package.
225
+ 4. Mark old exports deprecated and keep their legacy tests separately runnable.
226
+ 5. Add web plus Expo adapters only where the same controlled contract is
227
+ genuinely reusable.
228
+ 6. Remove compatibility implementations only in a later breaking release.
229
+
@@ -0,0 +1,30 @@
1
+ import type { SoschainDemoContact, SoschainDemoSubject } from 'sos-data-utils-ts/portal-demo-fixtures';
2
+ export type EmergencyContactCardDirectoryCopy = Readonly<{
3
+ title: string;
4
+ controller: string;
5
+ contactCard: string;
6
+ add: string;
7
+ remove: string;
8
+ makePrimary: string;
9
+ primary: string;
10
+ empty: string;
11
+ noCandidates: string;
12
+ authority: string;
13
+ }>;
14
+ export type EmergencyContactCardDirectoryProps = Readonly<{
15
+ copy: EmergencyContactCardDirectoryCopy;
16
+ contacts: readonly SoschainDemoContact<string>[];
17
+ candidates: readonly Pick<SoschainDemoSubject, 'uhcId' | 'nickname'>[];
18
+ controllerLabel: string;
19
+ busy?: boolean;
20
+ error?: string;
21
+ className?: string;
22
+ actionClassName?: string;
23
+ selectClassName?: string;
24
+ onAdd(subjectIdentifier: string): void | Promise<void>;
25
+ onRemove(contactId: string): void | Promise<void>;
26
+ onMakePrimary(contactId: string): void | Promise<void>;
27
+ }>;
28
+ /** Controlled card relationships; the host owns persistence and authorization. */
29
+ export declare function EmergencyContactCardDirectory({ copy, contacts, candidates, controllerLabel, busy, error, className, actionClassName, selectClassName, onAdd, onRemove, onMakePrimary }: EmergencyContactCardDirectoryProps): import("react").JSX.Element;
30
+ //# sourceMappingURL=EmergencyContactCardDirectory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmergencyContactCardDirectory.d.ts","sourceRoot":"","sources":["../src/EmergencyContactCardDirectory.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,mBAAmB,EAAC,mBAAmB,EAAC,MAAM,wCAAwC,CAAA;AAGnG,MAAM,MAAM,iCAAiC,GAAC,QAAQ,CAAC;IACrD,KAAK,EAAC,MAAM,CAAC;IAAA,UAAU,EAAC,MAAM,CAAC;IAAA,WAAW,EAAC,MAAM,CAAC;IAAA,GAAG,EAAC,MAAM,CAAC;IAAA,MAAM,EAAC,MAAM,CAAA;IAC1E,WAAW,EAAC,MAAM,CAAC;IAAA,OAAO,EAAC,MAAM,CAAC;IAAA,KAAK,EAAC,MAAM,CAAC;IAAA,YAAY,EAAC,MAAM,CAAC;IAAA,SAAS,EAAC,MAAM,CAAA;CACpF,CAAC,CAAA;AAEF,MAAM,MAAM,kCAAkC,GAAC,QAAQ,CAAC;IACtD,IAAI,EAAC,iCAAiC,CAAA;IACtC,QAAQ,EAAC,SAAS,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAA;IAC/C,UAAU,EAAC,SAAS,IAAI,CAAC,mBAAmB,EAAC,OAAO,GAAC,UAAU,CAAC,EAAE,CAAA;IAClE,eAAe,EAAC,MAAM,CAAA;IACtB,IAAI,CAAC,EAAC,OAAO,CAAA;IACb,KAAK,CAAC,EAAC,MAAM,CAAA;IACb,SAAS,CAAC,EAAC,MAAM,CAAA;IACjB,eAAe,CAAC,EAAC,MAAM,CAAA;IACvB,eAAe,CAAC,EAAC,MAAM,CAAA;IACvB,KAAK,CAAC,iBAAiB,EAAC,MAAM,GAAE,IAAI,GAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAClD,QAAQ,CAAC,SAAS,EAAC,MAAM,GAAE,IAAI,GAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7C,aAAa,CAAC,SAAS,EAAC,MAAM,GAAE,IAAI,GAAC,OAAO,CAAC,IAAI,CAAC,CAAA;CACnD,CAAC,CAAA;AAEF,kFAAkF;AAClF,wBAAgB,6BAA6B,CAAC,EAAC,IAAI,EAAC,QAAQ,EAAC,UAAU,EAAC,eAAe,EAAC,IAAI,EAAC,KAAK,EAAC,SAAS,EAAC,eAAe,EAAC,eAAe,EAAC,KAAK,EAAC,QAAQ,EAAC,aAAa,EAAC,EAAC,kCAAkC,+BA2B5M"}
@@ -0,0 +1,13 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useId, useState } from 'react';
4
+ /** Controlled card relationships; the host owns persistence and authorization. */
5
+ export function EmergencyContactCardDirectory({ copy, contacts, candidates, controllerLabel, busy, error, className, actionClassName, selectClassName, onAdd, onRemove, onMakePrimary }) {
6
+ const id = useId();
7
+ const [selection, setSelection] = useState('');
8
+ const available = candidates.filter(candidate => !contacts.some(contact => contact.subjectId === candidate.uhcId));
9
+ const selected = available.some(candidate => candidate.uhcId === selection) ? selection : '';
10
+ return _jsxs("section", { "aria-labelledby": `${id}-title`, className: ['emergency-contact-card-directory', className].filter(Boolean).join(' '), children: [_jsx("h3", { id: `${id}-title`, children: copy.title }), _jsxs("p", { children: [_jsxs("strong", { children: [copy.controller, ": "] }), controllerLabel] }), _jsx("p", { children: copy.authority }), _jsxs("fieldset", { disabled: busy, children: [contacts.length ? _jsx("ul", { children: contacts.map(contact => _jsxs("li", { children: [_jsx("strong", { children: contact.label }), _jsx("p", { children: contact.relationshipLabel }), contact.primary ? _jsx("p", { children: copy.primary }) : _jsx("button", { type: "button", className: actionClassName, disabled: busy, onClick: () => void onMakePrimary(contact.contactId), children: copy.makePrimary }), _jsx("button", { type: "button", className: actionClassName, disabled: busy, onClick: () => void onRemove(contact.contactId), children: copy.remove })] }, contact.contactId)) }) : _jsx("p", { children: copy.empty }), available.length ? _jsxs("form", { onSubmit: event => { event.preventDefault(); if (!busy && selected)
11
+ void onAdd(selected); }, children: [_jsx("label", { htmlFor: `${id}-contact`, children: copy.contactCard }), _jsxs("select", { id: `${id}-contact`, className: selectClassName, value: selected, onChange: event => setSelection(event.target.value), required: true, children: [_jsx("option", { value: "", disabled: true, children: copy.contactCard }), available.map(candidate => _jsx("option", { value: candidate.uhcId, children: candidate.nickname }, candidate.uhcId))] }), _jsx("button", { type: "submit", className: actionClassName, disabled: busy || !selected, children: copy.add })] }) : _jsx("p", { children: copy.noCandidates })] }), error ? _jsx("p", { role: "alert", children: error }) : null] });
12
+ }
13
+ //# sourceMappingURL=EmergencyContactCardDirectory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmergencyContactCardDirectory.js","sourceRoot":"","sources":["../src/EmergencyContactCardDirectory.tsx"],"names":[],"mappings":"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"}