sos-portal-components-react 0.3.4 → 0.4.0

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/CHANGELOG.md CHANGED
@@ -1,145 +1,163 @@
1
- # Changelog
2
-
3
- ## Unreleased
4
-
5
- ## 0.3.4 - 2026-11-12
6
-
7
- - Render provider-supplied organization/service labels for authorized foreign history without exposing service-reference internals or mutation controls.
8
-
9
- - Keep other-organization Encounter history read-only in the shared journey action selector. Document consent-free professional encounter traceability, scoped history read grants and the full IPS permission catalog.
10
-
11
- ## 0.3.3 - 2026-11-11
12
-
13
- - Add controlled, host-authorized Encounter journey and transfer components, including persisted response validation and read-only Personal presentation. Retain the UHC transfer console through a compatibility wrapper.
14
- - Recover the shared person/animal clinical-section, permission and US Core STU6 contract; distinguish existing views from the pending complete example lifecycle.
15
-
16
- ## 0.3.2 - 2026-11-10
17
-
18
- - Add controlled `SubjectCardLocatorFields` for card-number or DID/QR entry.
19
- Number entry distinguishes person/animal and animal taxonomy, including
20
- species beyond the supplied presets. Hosts provide labels/options and own
21
- resolution and authorization; the fields select no mode, storage or provider.
22
-
23
- ## 0.3.1 - 2026-11-09
24
-
25
- - Add a persisted RTC completion signal for local/remote hangup and injected
26
- canonical terminal-state observation. Release tracks, de-duplicate end
27
- requests, preserve retryable history failures and cancel invitations after
28
- connection failure. Load browser media capability before issuing a grant.
29
-
30
- - Add shared account-level push registration controls with explicit enable,
31
- current-browser disable, other-device revocation and unavailable/denied
32
- states. Permission requests, transports, identity and persistence remain in
33
- the host adapters.
34
-
35
- - Add one controlled emergency-contact card directory with separate controller
36
- context, primary-recipient presentation and injected add/remove/priority
37
- operations. It owns no storage or authority and can render the same state
38
- across execution modes; native rendering remains a separate adapter.
39
-
40
- - Specify the complete created-card emergency acceptance journey under the
41
- existing Tuskr IDs: My card, dependent/controller/contact defaults, pasted
42
- identifier/manual tuple/camera/image intake, linked-identifier discovery,
43
- Encounter-scoped contact and RTC, recipient-card history, exceptional access
44
- and ambulance/hospital handover. Distinguish requirements from executed
45
- evidence and isolated media cases from full lifecycle acceptance.
46
-
47
- ## 0.3.0 - 2026-11-08
48
-
49
- - Export shared device-assistance preferences through an independent SOS entry,
50
- delegating its controlled web renderer to Antifraud 0.3.0. Keep runtime,
51
- capability detection, storage and authorization in the owning application.
52
- Native preferences rendering is not implemented by this release.
53
- - Typecheck, build and the independent export smoke pass. Cross-application
54
- phone-authenticated browser checks belong to the CH acceptance evidence.
55
- - List the three implemented runtime exports separately from the acceptance
56
- catalogue. Base shell/profile/card extraction from the existing domain
57
- package remains pending; controller administration has a separate owner.
58
-
59
- - Specify shared subject-control placement, semantic option/action colours,
60
- account-menu versus subject-device grants, appearance namespace parity and
61
- separate model enablement/availability/preparation states in the existing
62
- Tuskr cases. These are acceptance requirements, not new runtime readiness.
63
-
64
- - Correct the shared acceptance guides to use the selected simulated-phone
65
- tests without mailbox access. Treat current email-only Organization/employee
66
- contracts as an implementation gap; preserve official-source verification,
67
- independent profile authority and existing GW/DID behavior.
68
-
69
- - Replace the dated developer handoff with numbered, README-linked guides for
70
- generic portal modes/authentication and detailed cross-portal Tuskr cases.
71
- Preserve the existing `SOS-PORTAL-001`-`029` and specialist research IDs.
72
- - Distinguish public Demo real-email account login from fixed Firebase test
73
- phone fixtures, BFF-owned Demo persistence from Test Network authority/GW
74
- lifecycle, and dedicated RTC media from Communication history and assistants.
75
- - Document positive/negative Personal ? Professional journeys, both-side
76
- readback, profile/relationship revocation, sector variants and evidence
77
- boundaries without claiming unexecuted gates have passed.
78
- - Specify dependency-by-case progression: BFF/memory Demo first, independent
79
- terminology-cache and RTC additions, and memory-GW -> local Fabric ->
80
- online Test Network acceptance for network cases. Retain green evidence and
81
- rerun only failed/affected gates while closing the cumulative release set.
82
-
83
- ## 0.2.3 - 2026-11-07
84
-
85
- - Render caller-cancelled Communications as `Cancelled`/`Cancelada` rather
86
- than collapsing them into an undefined or generic ended state.
87
- - Let the host distinguish a caller cancellation from an unanswered timeout
88
- when ending an RTC session; media teardown remains separate from canonical
89
- Communication persistence.
90
-
91
- ## 0.2.2 - 2026-11-07
92
-
93
- - Render the canonical ringing, missed and ended state beside every call
94
- Communication in the shared Personal/Professional conversation surface.
95
- Host portals no longer need divergent status labels to expose call history.
96
-
97
- ## 0.2.1 - 2026-11-07
98
-
99
- - Pin `sos-data-utils-ts@0.6.28`, the exact release that owns the portal RTC
100
- Communication contract consumed by `createLiveKitRealtimeCallClient`. Clean npm
101
- installs no longer retain a nested pre-RTC data-utils release.
102
-
103
- ## 0.2.0 - 2026-11-07
104
-
105
- - Establish this package as the shared presentation boundary consumed directly
106
- by CH Personal and Professional in every flavour. Product portals provide
107
- authorization, policy and BFF adapters; UHC compatibility exports no longer
108
- own the active implementation.
109
- - Export `SubjectConversationChat` as the single subject-channel renderer over
110
- canonical Communications. It projects text, governed attachments, clinical
111
- Bundles, ICS/files, audio and call events without owning persistence,
112
- signaling or recipient authority.
113
- - Export `createLiveKitRealtimeCallClient` as a dynamically loaded web RTC adapter
114
- designed for later Expo substitution. It consumes only the short grant
115
- issued by the BFF and never receives LiveKit API credentials.
116
- - Separate CH all-local, telephone-assistant, optional web-assistant and RTC
117
- integration profiles. Calls use a host-injected dedicated RTC client while
118
- invitations, terminal events and unanswered audio render as Communications.
119
-
120
- ## 0.1.2 - 2026-11-07
121
-
122
- - Document and enforce one shared UI contract for Demo, Test Network, web and
123
- Expo; presentation components never select a persistence adapter.
124
-
125
- ## 0.1.1 - 2026-11-06
126
-
127
- - Document the GitHub organization handoff, BFF-validated synthetic Demo
128
- boundary, scoped storage contract and two-browser call verification flow.
129
-
130
- ## 0.1.0 - 2026-11-06
131
-
132
- - Establish the shared cross-sector portal-component boundary.
133
- - Publish the initial Tuskr-ready use-case catalogue covering shell, access,
134
- cards, identity, encounters, communications, appointments, relationships,
135
- calls, clinical documents, permissions and lifecycle composition.
136
- - Add the Personal/Professional communications matrix for card-root channels,
137
- relationship child threads and persisted audio/video call-event states.
138
- - Keep host/tenant controller governance in Antifraud Hosting and leave
139
- research/genomics outside the initial core until their package boundary is
140
- decided.
141
- - Add the canonical `SubjectConversationChat` React Native/Web adapter over
142
- Antifraud's neutral conversation surface and SOS subject-conversation
143
- contracts, including text, governed attachments, FHIR documents and call
144
- events without moving authorization or delivery into React.
145
-
1
+ # Changelog
2
+
3
+ ## Unreleased
4
+
5
+ ## 0.4.0 - 2026-11-14
6
+
7
+ - Verify the full 33 component tests and three required dependency contracts,
8
+ typecheck/build, source/emitted privacy and all six JavaScript public entries
9
+ plus CSS against the independent registry cohort. This release preserves
10
+ the existing shared API; it does not incorporate UHC components.
11
+
12
+ - Require the independent dependency gate in the normal check: reject GDC
13
+ declarations and aliases, source/declaration/emitted imports or re-exports,
14
+ and every transitive registry lock entry.
15
+
16
+ - Consume the published FHIR and SOS Data 0.7 contracts through registry-only
17
+ dependencies, preserving the shared UI API and the existing neutral
18
+ Antifraud renderer.
19
+
20
+ - Pin the reviewed SOS Data contract version used by the shared journey
21
+ renderer so dependency resolution does not reinstall an older catalog.
22
+
23
+ ## 0.3.4 - 2026-11-12
24
+
25
+ - Render provider-supplied organization/service labels for authorized foreign history without exposing service-reference internals or mutation controls.
26
+
27
+ - Keep other-organization Encounter history read-only in the shared journey action selector. Document consent-free professional encounter traceability, scoped history read grants and the full IPS permission catalog.
28
+
29
+ ## 0.3.3 - 2026-11-11
30
+
31
+ - Add controlled, host-authorized Encounter journey and transfer components, including persisted response validation and read-only Personal presentation. Retain the UHC transfer console through a compatibility wrapper.
32
+ - Recover the shared person/animal clinical-section, permission and US Core STU6 contract; distinguish existing views from the pending complete example lifecycle.
33
+
34
+ ## 0.3.2 - 2026-11-10
35
+
36
+ - Add controlled `SubjectCardLocatorFields` for card-number or DID/QR entry.
37
+ Number entry distinguishes person/animal and animal taxonomy, including
38
+ species beyond the supplied presets. Hosts provide labels/options and own
39
+ resolution and authorization; the fields select no mode, storage or provider.
40
+
41
+ ## 0.3.1 - 2026-11-09
42
+
43
+ - Add a persisted RTC completion signal for local/remote hangup and injected
44
+ canonical terminal-state observation. Release tracks, de-duplicate end
45
+ requests, preserve retryable history failures and cancel invitations after
46
+ connection failure. Load browser media capability before issuing a grant.
47
+
48
+ - Add shared account-level push registration controls with explicit enable,
49
+ current-browser disable, other-device revocation and unavailable/denied
50
+ states. Permission requests, transports, identity and persistence remain in
51
+ the host adapters.
52
+
53
+ - Add one controlled emergency-contact card directory with separate controller
54
+ context, primary-recipient presentation and injected add/remove/priority
55
+ operations. It owns no storage or authority and can render the same state
56
+ across execution modes; native rendering remains a separate adapter.
57
+
58
+ - Specify the complete created-card emergency acceptance journey under the
59
+ existing Tuskr IDs: My card, dependent/controller/contact defaults, pasted
60
+ identifier/manual tuple/camera/image intake, linked-identifier discovery,
61
+ Encounter-scoped contact and RTC, recipient-card history, exceptional access
62
+ and ambulance/hospital handover. Distinguish requirements from executed
63
+ evidence and isolated media cases from full lifecycle acceptance.
64
+
65
+ ## 0.3.0 - 2026-11-08
66
+
67
+ - Export shared device-assistance preferences through an independent SOS entry,
68
+ delegating its controlled web renderer to Antifraud 0.3.0. Keep runtime,
69
+ capability detection, storage and authorization in the owning application.
70
+ Native preferences rendering is not implemented by this release.
71
+ - Typecheck, build and the independent export smoke pass. Cross-application
72
+ phone-authenticated browser checks belong to the CH acceptance evidence.
73
+ - List the three implemented runtime exports separately from the acceptance
74
+ catalogue. Base shell/profile/card extraction from the existing domain
75
+ package remains pending; controller administration has a separate owner.
76
+
77
+ - Specify shared subject-control placement, semantic option/action colours,
78
+ account-menu versus subject-device grants, appearance namespace parity and
79
+ separate model enablement/availability/preparation states in the existing
80
+ Tuskr cases. These are acceptance requirements, not new runtime readiness.
81
+
82
+ - Correct the shared acceptance guides to use the selected simulated-phone
83
+ tests without mailbox access. Treat current email-only Organization/employee
84
+ contracts as an implementation gap; preserve official-source verification,
85
+ independent profile authority and existing GW/DID behavior.
86
+
87
+ - Replace the dated developer handoff with numbered, README-linked guides for
88
+ generic portal modes/authentication and detailed cross-portal Tuskr cases.
89
+ Preserve the existing `SOS-PORTAL-001`-`029` and specialist research IDs.
90
+ - Distinguish public Demo real-email account login from fixed Firebase test
91
+ phone fixtures, BFF-owned Demo persistence from Test Network authority/GW
92
+ lifecycle, and dedicated RTC media from Communication history and assistants.
93
+ - Document positive/negative Personal ? Professional journeys, both-side
94
+ readback, profile/relationship revocation, sector variants and evidence
95
+ boundaries without claiming unexecuted gates have passed.
96
+ - Specify dependency-by-case progression: BFF/memory Demo first, independent
97
+ terminology-cache and RTC additions, and memory-GW -> local Fabric ->
98
+ online Test Network acceptance for network cases. Retain green evidence and
99
+ rerun only failed/affected gates while closing the cumulative release set.
100
+
101
+ ## 0.2.3 - 2026-11-07
102
+
103
+ - Render caller-cancelled Communications as `Cancelled`/`Cancelada` rather
104
+ than collapsing them into an undefined or generic ended state.
105
+ - Let the host distinguish a caller cancellation from an unanswered timeout
106
+ when ending an RTC session; media teardown remains separate from canonical
107
+ Communication persistence.
108
+
109
+ ## 0.2.2 - 2026-11-07
110
+
111
+ - Render the canonical ringing, missed and ended state beside every call
112
+ Communication in the shared Personal/Professional conversation surface.
113
+ Host portals no longer need divergent status labels to expose call history.
114
+
115
+ ## 0.2.1 - 2026-11-07
116
+
117
+ - Pin `sos-data-utils-ts@0.6.28`, the exact release that owns the portal RTC
118
+ Communication contract consumed by `createLiveKitRealtimeCallClient`. Clean npm
119
+ installs no longer retain a nested pre-RTC data-utils release.
120
+
121
+ ## 0.2.0 - 2026-11-07
122
+
123
+ - Establish this package as the shared presentation boundary consumed directly
124
+ by CH Personal and Professional in every flavour. Product portals provide
125
+ authorization, policy and BFF adapters; UHC compatibility exports no longer
126
+ own the active implementation.
127
+ - Export `SubjectConversationChat` as the single subject-channel renderer over
128
+ canonical Communications. It projects text, governed attachments, clinical
129
+ Bundles, ICS/files, audio and call events without owning persistence,
130
+ signaling or recipient authority.
131
+ - Export `createLiveKitRealtimeCallClient` as a dynamically loaded web RTC adapter
132
+ designed for later Expo substitution. It consumes only the short grant
133
+ issued by the BFF and never receives LiveKit API credentials.
134
+ - Separate CH all-local, telephone-assistant, optional web-assistant and RTC
135
+ integration profiles. Calls use a host-injected dedicated RTC client while
136
+ invitations, terminal events and unanswered audio render as Communications.
137
+
138
+ ## 0.1.2 - 2026-11-07
139
+
140
+ - Document and enforce one shared UI contract for Demo, Test Network, web and
141
+ Expo; presentation components never select a persistence adapter.
142
+
143
+ ## 0.1.1 - 2026-11-06
144
+
145
+ - Document the GitHub organization handoff, BFF-validated synthetic Demo
146
+ boundary, scoped storage contract and two-browser call verification flow.
147
+
148
+ ## 0.1.0 - 2026-11-06
149
+
150
+ - Establish the shared cross-sector portal-component boundary.
151
+ - Publish the initial Tuskr-ready use-case catalogue covering shell, access,
152
+ cards, identity, encounters, communications, appointments, relationships,
153
+ calls, clinical documents, permissions and lifecycle composition.
154
+ - Add the Personal/Professional communications matrix for card-root channels,
155
+ relationship child threads and persisted audio/video call-event states.
156
+ - Keep host/tenant controller governance in Antifraud Hosting and leave
157
+ research/genomics outside the initial core until their package boundary is
158
+ decided.
159
+ - Add the canonical `SubjectConversationChat` React Native/Web adapter over
160
+ Antifraud's neutral conversation surface and SOS subject-conversation
161
+ contracts, including text, governed attachments, FHIR documents and call
162
+ events without moving authorization or delivery into React.
163
+
package/README.md CHANGED
@@ -1,233 +1,233 @@
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
- | `EncounterJourneyPanel` | Controlled create/status/transfer and read-only saved journey; BFF callbacks own authority and persistence. |
91
- | `EncounterTransferConsole` | Shared transfer presentation; UHC retains a deprecated compatibility wrapper. |
92
- | `SubjectConversationChat` | SOS projection of authorized subject Communications into the neutral Antifraud conversation renderer. |
93
- | `createLiveKitRealtimeCallClient` | Host-configured RTC client adapter; the BFF retains authorization, credentials and Communication persistence. |
94
- | `useRealtimeCallSessionLifecycle` | Shared persisted-end observation and profile-owned session cleanup for Personal and Professional, including React Strict Mode replay. |
95
- | `DeviceAssistancePreferences` | Reexport of Antifraud's controlled web preferences renderer. |
96
- | `PushNotificationRegistration` | Controlled browser-registration status, explicit enable and per-device revoke actions. The host owns permission, subscription/token, verified identity, BFF and transport. |
97
- | `EmergencyContactCardDirectory` | Controlled card-linked emergency recipients and primary priority; host callbacks retain contact mutation, controller authority and persistence. |
98
-
99
- The complete base-UI extraction is still pending. `PortalHeader`,
100
- `PortalSettingsPanel`, profile protection, subject/card navigation and several
101
- contact, permission and clinical controls remain in
102
- `uhc-portal-components-react`; application composition also remains in the
103
- owning portals. Research stays there pending its future owner. The catalogue
104
- below is acceptance scope and must not be read as an implemented export list.
105
- Controller administration is owned separately by
106
- `antifraud-hosting-components-react`.
107
-
108
- - `sos-portal-components-react/device-assistance-preferences` reexports the
109
- controlled `DeviceAssistancePreferences` owned by the neutral Antifraud
110
- package. Import `antifraud-portal-components-react/device-assistance-preferences.css`
111
- once in the application shell. It separates consent, runtime availability
112
- and explicit preparation; hosts supply localized labels, storage and runtime
113
- adapters. Rendering/toggling does not prepare a model or grant subject access.
114
- Use this independent entry on account pages to avoid loading conversation
115
- and RTC modules. Do not fork another device preferences panel per flavour.
116
-
117
- - `sos-portal-components-react/subject-conversation-chat` provides the
118
- canonical React Native/Web adapter for an already-authorized subject
119
- conversation. It projects the stable SOS entry model into the neutral
120
- Antifraud conversation surface backed by
121
- `@kesha-antonov/react-native-chat`. Hosts retain BFF delivery, attachment
122
- opening, FHIR rendering, WebRTC signaling and authorization.
123
-
124
- The compatibility export currently present in the human-health component
125
- package is deprecated and will delegate to this package while consumers move
126
- to the SOS-owned path.
127
-
128
- ## Tuskr use-case catalogue
129
-
130
- The stable IDs below are intended to become Tuskr cases. Each case must be
131
- executed for every applicable flavour, actor, viewport and environment. Demo
132
- uses synthetic state and must say so; Test Network and Production must use
133
- their real authorized BFF path.
134
-
135
- Use [02 — Cross-portal Tuskr cases](docs/02-CROSS_PORTAL_TUSKR_CASES.md)
136
- for Personal ↔ Professional prerequisites, numbered actions, both-side
137
- readback, rejected access, reset/revocation and execution evidence. A documented
138
- case is an acceptance target, not an end-to-end pass claim.
139
-
140
- | ID | Area | Governed journey and acceptance target |
141
- |---|---|---|
142
- | SOS-PORTAL-001 | Shell | Render the shared top bar, brand slot, account/profile menu, current subject and responsive navigation without flavour-specific forks. |
143
- | 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. |
144
- | 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. |
145
- | 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. |
146
- | SOS-PORTAL-005 | Registration | Register or accept an invitation for the applicable person, professional or animal-responsible profile; registration alone grants no subject access. |
147
- | SOS-PORTAL-006 | Cards | List only server-authorized individual or animal cards, select one card and preserve its stable identifier across navigation/reload. |
148
- | 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. |
149
- | SOS-PORTAL-008 | Identity | View and edit the permitted identity fields, provenance and attestations for a selected card while preserving immutable identifiers. |
150
- | SOS-PORTAL-009 | Related entities | Add, view, update or remove authorized related people, animals and organizations with explicit relationship type and provenance. |
151
- | SOS-PORTAL-010 | Contacts | Manage ordinary and emergency contacts independently, including priority, relationship, availability and emergency-only disclosure. |
152
- | SOS-PORTAL-011 | Encounters | List, open and author permitted encounters; bind contributions to the acting professional, organization, subject and server-confirmed scope. |
153
- | 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. |
154
- | 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. |
155
- | SOS-PORTAL-014 | Appointments | Search availability and create, update or cancel appointments for applicable services, including blood-donation centres and other scheduled providers. |
156
- | SOS-PORTAL-015 | Clinical viewer | View authorized clinical documents, IPS summaries, sections, timelines and source/provenance details for human or animal cards. |
157
- | SOS-PORTAL-016 | Clinical authoring | Create and edit clinical documents through the canonical section-based editor, including encounters, observations, immunizations and host-enabled sections. |
158
- | SOS-PORTAL-017 | Credentials | Create, display, scan and verify supported health/data-card credentials and QR transports while keeping signing and verification outside React. |
159
- | SOS-PORTAL-018 | Permissions | View and change only permitted Consent/access relationships, group memberships and card grants; notifications never substitute for authorization. |
160
- | 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. |
161
- | SOS-PORTAL-020 | Individual members | Manage an individual's authorized members/delegates separately from organization employees, with explicit lifecycle and revocation. |
162
- | 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. |
163
- | SOS-PORTAL-022 | Subject index | Display real index-update Communications from authorized providers and open linked records without manufacturing parallel chat events. |
164
- | SOS-PORTAL-023 | Provider directory | Select authorized card/index, clinical, appointment or emergency providers from host-supplied directories without hard-coded flavour endpoints. |
165
- | SOS-PORTAL-024 | Accessibility | Complete every shared journey by keyboard and screen reader with visible focus, labelled controls, status announcements and responsive layouts. |
166
- | 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. |
167
- | 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. |
168
- | 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. |
169
- | 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. |
170
- | 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. |
171
-
172
- ### Communications execution matrix
173
-
174
- Tuskr must exercise `SOS-PORTAL-012`, `SOS-PORTAL-013` and
175
- `SOS-PORTAL-029` together:
176
-
177
- | Actor/surface | Root card channel | Authorized child thread | Required call events |
178
- |---|---|---|---|
179
- | 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 |
180
- | 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 |
181
- | 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 |
182
-
183
- Acceptance requires real persisted Communications (or the explicit synthetic
184
- Demo adapter), chronological projection without a parallel chat record, and
185
- negative tests proving that a contact listed for emergencies cannot enumerate
186
- or open a thread without separate authorization.
187
-
188
- ## Tracked specialist integration cases
189
-
190
- These cases must remain visible in Tuskr and in CH while they are migrated,
191
- but they are not owned by the initial SOS core package.
192
-
193
- | ID | Current owner | Planned direction | Acceptance target |
194
- |---|---|---|---|
195
- | 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. |
196
- | HEALTH-RESEARCH-002 | Human-health components / host adapter | Candidate for animal-care components | Search and add authorized research subjects without turning discovery into access. |
197
- | 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. |
198
- | 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. |
199
- | 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. |
200
-
201
- The current source inventory still contains host-local research panels.
202
- Migration is complete only when consuming portals import their published
203
- human-health implementation and the local alternatives are deprecated.
204
- Group-management source already lives in
205
- the Antifraud Controller application; its controlled UI must be exported by
206
- the Antifraud Hosting component package before CH can remove its final local
207
- group adapter.
208
-
209
- ## Explicitly outside the initial core
210
-
211
- - host registry, tenant admission and organization lifecycle policy (Antifraud
212
- Controller/Hosting);
213
- - research-study administration, research-subject import and genomic workflows
214
- (tracked above through their human-health to animal-care/specialist migration);
215
- - terminology databases and searches;
216
- - FHIR validation/conversion, DIDComm transport, wallets, signatures, QR
217
- cryptography, WebRTC signaling and persistence;
218
- - application-specific routes, branding and deployment configuration.
219
-
220
- ## Delivery order
221
-
222
- 1. Inventory the current verified components in deprecated sector portals,
223
- human-health components and consuming portal flavours.
224
- 2. Add a contract test for one canonical component per use case.
225
- 3. Move the current implementation without changing its data/authority
226
- boundary, then switch all CH flavours to the published package.
227
- 4. Mark old exports deprecated and keep their legacy tests separately runnable.
228
- 5. Add web plus Expo adapters only where the same controlled contract is
229
- genuinely reusable.
230
- 6. Remove compatibility implementations only in a later breaking release.
231
-
232
-
233
- See [clinical sections, permissions and US Core contract](docs/03-CLINICAL_SECTIONS_AND_US_CORE_CONTRACT.md) for the recovered person/animal mappings and pending full example lifecycle.
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
+ | `EncounterJourneyPanel` | Controlled create/status/transfer and read-only saved journey; BFF callbacks own authority and persistence. |
91
+ | `EncounterTransferConsole` | Shared transfer presentation; UHC retains a deprecated compatibility wrapper. |
92
+ | `SubjectConversationChat` | SOS projection of authorized subject Communications into the neutral Antifraud conversation renderer. |
93
+ | `createLiveKitRealtimeCallClient` | Host-configured RTC client adapter; the BFF retains authorization, credentials and Communication persistence. |
94
+ | `useRealtimeCallSessionLifecycle` | Shared persisted-end observation and profile-owned session cleanup for Personal and Professional, including React Strict Mode replay. |
95
+ | `DeviceAssistancePreferences` | Reexport of Antifraud's controlled web preferences renderer. |
96
+ | `PushNotificationRegistration` | Controlled browser-registration status, explicit enable and per-device revoke actions. The host owns permission, subscription/token, verified identity, BFF and transport. |
97
+ | `EmergencyContactCardDirectory` | Controlled card-linked emergency recipients and primary priority; host callbacks retain contact mutation, controller authority and persistence. |
98
+
99
+ The complete base-UI extraction is still pending. `PortalHeader`,
100
+ `PortalSettingsPanel`, profile protection, subject/card navigation and several
101
+ contact, permission and clinical controls remain in
102
+ `uhc-portal-components-react`; application composition also remains in the
103
+ owning portals. Research stays there pending its future owner. The catalogue
104
+ below is acceptance scope and must not be read as an implemented export list.
105
+ Controller administration is owned separately by
106
+ `antifraud-hosting-components-react`.
107
+
108
+ - `sos-portal-components-react/device-assistance-preferences` reexports the
109
+ controlled `DeviceAssistancePreferences` owned by the neutral Antifraud
110
+ package. Import `antifraud-portal-components-react/device-assistance-preferences.css`
111
+ once in the application shell. It separates consent, runtime availability
112
+ and explicit preparation; hosts supply localized labels, storage and runtime
113
+ adapters. Rendering/toggling does not prepare a model or grant subject access.
114
+ Use this independent entry on account pages to avoid loading conversation
115
+ and RTC modules. Do not fork another device preferences panel per flavour.
116
+
117
+ - `sos-portal-components-react/subject-conversation-chat` provides the
118
+ canonical React Native/Web adapter for an already-authorized subject
119
+ conversation. It projects the stable SOS entry model into the neutral
120
+ Antifraud conversation surface backed by
121
+ `@kesha-antonov/react-native-chat`. Hosts retain BFF delivery, attachment
122
+ opening, FHIR rendering, WebRTC signaling and authorization.
123
+
124
+ The compatibility export currently present in the human-health component
125
+ package is deprecated and will delegate to this package while consumers move
126
+ to the SOS-owned path.
127
+
128
+ ## Tuskr use-case catalogue
129
+
130
+ The stable IDs below are intended to become Tuskr cases. Each case must be
131
+ executed for every applicable flavour, actor, viewport and environment. Demo
132
+ uses synthetic state and must say so; Test Network and Production must use
133
+ their real authorized BFF path.
134
+
135
+ Use [02 — Cross-portal Tuskr cases](docs/02-CROSS_PORTAL_TUSKR_CASES.md)
136
+ for Personal ↔ Professional prerequisites, numbered actions, both-side
137
+ readback, rejected access, reset/revocation and execution evidence. A documented
138
+ case is an acceptance target, not an end-to-end pass claim.
139
+
140
+ | ID | Area | Governed journey and acceptance target |
141
+ |---|---|---|
142
+ | SOS-PORTAL-001 | Shell | Render the shared top bar, brand slot, account/profile menu, current subject and responsive navigation without flavour-specific forks. |
143
+ | 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. |
144
+ | 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. |
145
+ | 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. |
146
+ | SOS-PORTAL-005 | Registration | Register or accept an invitation for the applicable person, professional or animal-responsible profile; registration alone grants no subject access. |
147
+ | SOS-PORTAL-006 | Cards | List only server-authorized individual or animal cards, select one card and preserve its stable identifier across navigation/reload. |
148
+ | 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. |
149
+ | SOS-PORTAL-008 | Identity | View and edit the permitted identity fields, provenance and attestations for a selected card while preserving immutable identifiers. |
150
+ | SOS-PORTAL-009 | Related entities | Add, view, update or remove authorized related people, animals and organizations with explicit relationship type and provenance. |
151
+ | SOS-PORTAL-010 | Contacts | Manage ordinary and emergency contacts independently, including priority, relationship, availability and emergency-only disclosure. |
152
+ | SOS-PORTAL-011 | Encounters | List, open and author permitted encounters; bind contributions to the acting professional, organization, subject and server-confirmed scope. |
153
+ | 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. |
154
+ | 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. |
155
+ | SOS-PORTAL-014 | Appointments | Search availability and create, update or cancel appointments for applicable services, including blood-donation centres and other scheduled providers. |
156
+ | SOS-PORTAL-015 | Clinical viewer | View authorized clinical documents, IPS summaries, sections, timelines and source/provenance details for human or animal cards. |
157
+ | SOS-PORTAL-016 | Clinical authoring | Create and edit clinical documents through the canonical section-based editor, including encounters, observations, immunizations and host-enabled sections. |
158
+ | SOS-PORTAL-017 | Credentials | Create, display, scan and verify supported health/data-card credentials and QR transports while keeping signing and verification outside React. |
159
+ | SOS-PORTAL-018 | Permissions | View and change only permitted Consent/access relationships, group memberships and card grants; notifications never substitute for authorization. |
160
+ | 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. |
161
+ | SOS-PORTAL-020 | Individual members | Manage an individual's authorized members/delegates separately from organization employees, with explicit lifecycle and revocation. |
162
+ | 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. |
163
+ | SOS-PORTAL-022 | Subject index | Display real index-update Communications from authorized providers and open linked records without manufacturing parallel chat events. |
164
+ | SOS-PORTAL-023 | Provider directory | Select authorized card/index, clinical, appointment or emergency providers from host-supplied directories without hard-coded flavour endpoints. |
165
+ | SOS-PORTAL-024 | Accessibility | Complete every shared journey by keyboard and screen reader with visible focus, labelled controls, status announcements and responsive layouts. |
166
+ | 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. |
167
+ | 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. |
168
+ | 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. |
169
+ | 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. |
170
+ | 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. |
171
+
172
+ ### Communications execution matrix
173
+
174
+ Tuskr must exercise `SOS-PORTAL-012`, `SOS-PORTAL-013` and
175
+ `SOS-PORTAL-029` together:
176
+
177
+ | Actor/surface | Root card channel | Authorized child thread | Required call events |
178
+ |---|---|---|---|
179
+ | 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 |
180
+ | 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 |
181
+ | 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 |
182
+
183
+ Acceptance requires real persisted Communications (or the explicit synthetic
184
+ Demo adapter), chronological projection without a parallel chat record, and
185
+ negative tests proving that a contact listed for emergencies cannot enumerate
186
+ or open a thread without separate authorization.
187
+
188
+ ## Tracked specialist integration cases
189
+
190
+ These cases must remain visible in Tuskr and in CH while they are migrated,
191
+ but they are not owned by the initial SOS core package.
192
+
193
+ | ID | Current owner | Planned direction | Acceptance target |
194
+ |---|---|---|---|
195
+ | 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. |
196
+ | HEALTH-RESEARCH-002 | Human-health components / host adapter | Candidate for animal-care components | Search and add authorized research subjects without turning discovery into access. |
197
+ | 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. |
198
+ | 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. |
199
+ | 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. |
200
+
201
+ The current source inventory still contains host-local research panels.
202
+ Migration is complete only when consuming portals import their published
203
+ human-health implementation and the local alternatives are deprecated.
204
+ Group-management source already lives in
205
+ the Antifraud Controller application; its controlled UI must be exported by
206
+ the Antifraud Hosting component package before CH can remove its final local
207
+ group adapter.
208
+
209
+ ## Explicitly outside the initial core
210
+
211
+ - host registry, tenant admission and organization lifecycle policy (Antifraud
212
+ Controller/Hosting);
213
+ - research-study administration, research-subject import and genomic workflows
214
+ (tracked above through their human-health to animal-care/specialist migration);
215
+ - terminology databases and searches;
216
+ - FHIR validation/conversion, DIDComm transport, wallets, signatures, QR
217
+ cryptography, WebRTC signaling and persistence;
218
+ - application-specific routes, branding and deployment configuration.
219
+
220
+ ## Delivery order
221
+
222
+ 1. Inventory the current verified components in deprecated sector portals,
223
+ human-health components and consuming portal flavours.
224
+ 2. Add a contract test for one canonical component per use case.
225
+ 3. Move the current implementation without changing its data/authority
226
+ boundary, then switch all CH flavours to the published package.
227
+ 4. Mark old exports deprecated and keep their legacy tests separately runnable.
228
+ 5. Add web plus Expo adapters only where the same controlled contract is
229
+ genuinely reusable.
230
+ 6. Remove compatibility implementations only in a later breaking release.
231
+
232
+
233
+ See [clinical sections, permissions and US Core contract](docs/03-CLINICAL_SECTIONS_AND_US_CORE_CONTRACT.md) for the recovered person/animal mappings and pending full example lifecycle.
@@ -1,91 +1,91 @@
1
- .uhcp-transfer-console { background:var(--uhcp-surface,#fff); color:var(--uhcp-text,#102754); display:grid; font-family:Inter,ui-sans-serif,system-ui,sans-serif; grid-template-columns:minmax(16rem,23rem) minmax(0,1fr); min-height:calc(100vh - 4.5rem); }
2
- .uhcp-transfer-console button,.uhcp-transfer-console input,.uhcp-transfer-console textarea { font:inherit; }
3
- .uhcp-transfer-console svg { fill:none; height:1.25rem; stroke:currentColor; stroke-linecap:round; stroke-linejoin:round; stroke-width:1.8; width:1.25rem; }
4
- .uhcp-transfer-contacts { border-inline-end:1px solid #dce5ec; padding:1.2rem; }
5
- .uhcp-transfer-contacts summary { cursor:pointer; font-size:1.05rem; font-weight:850; list-style-position:inside; padding:.35rem 0 1rem; }
6
- .uhcp-transfer-contact-list { border-block:1px solid #e2e9ef; display:grid; padding:.45rem 0; }
7
- .uhcp-transfer-contact-list button { background:transparent; border:0; border-inline-start:3px solid transparent; color:inherit; cursor:pointer; display:grid; gap:.15rem; grid-template-columns:2.7rem 1fr; padding:.75rem; text-align:start; }
8
- .uhcp-transfer-contact-list button[aria-pressed=true] { background:var(--uhcp-surface-muted,#eaf8fd); border-inline-start-color:var(--uhcp-text,#09a9dc); }
9
- .uhcp-transfer-contact-list button>span { align-items:center; background:var(--uhcp-surface-muted,#d7e7f1); border-radius:50%; display:flex; font-weight:800; grid-row:span 2; height:2.4rem; justify-content:center; width:2.4rem; }
10
- .uhcp-transfer-contact-list small { color:var(--uhcp-text,#58708e); }
11
- .uhcp-transfer-contact-actions { display:grid; gap:.55rem; padding:1rem 0; }
12
- .uhcp-transfer-contact-actions button,.uhcp-transfer-mode button,.uhcp-transfer-composer fieldset button { align-items:center; background:var(--uhcp-surface,#fff); border:1px solid #cad7e2; border-radius:.55rem; color:inherit; cursor:pointer; display:flex; gap:.7rem; padding:.7rem .85rem; }
13
- .uhcp-transfer-contact-actions button[aria-pressed=true],.uhcp-transfer-mode button[aria-pressed=true] { background:var(--uhcp-surface-muted,#eaf8fd); border-color:var(--uhcp-text,#09a9dc); color:var(--uhcp-text,#006f96); font-weight:800; }
14
- .uhcp-transfer-composer fieldset button[aria-pressed=true] { background:var(--uhcp-surface-muted,#eaf8fd); border-color:var(--uhcp-text,#09a9dc); color:var(--uhcp-text,#006f96); font-weight:800; }
15
- .uhcp-transfer-composer { display:grid; gap:.8rem; }
16
- .uhcp-transfer-composer h3 { font-size:.95rem; margin:.2rem 0 0; }
17
- .uhcp-transfer-mode { display:grid; grid-template-columns:1fr 1fr; }
18
- .uhcp-transfer-mode button { justify-content:center; }
19
- .uhcp-transfer-composer label { display:grid; font-size:.82rem; font-weight:750; gap:.35rem; }
20
- .uhcp-transfer-composer textarea { border:1px solid #cad7e2; border-radius:.55rem; color:inherit; resize:vertical; padding:.75rem; }
21
- .uhcp-transfer-composer fieldset { border:0; margin:0; padding:0; }
22
- .uhcp-transfer-composer legend { font-size:.82rem; font-weight:750; margin-bottom:.4rem; }
23
- .uhcp-transfer-composer fieldset>div { display:flex; flex-wrap:wrap; gap:.4rem; }
24
- .uhcp-transfer-record { background:var(--uhcp-surface,#fff); border:1px dashed #09a9dc; border-radius:.55rem; color:var(--uhcp-text,#006f96); padding:1rem; }
25
- .uhcp-transfer-primary { background:#0796a8!important; border-color:#0796a8!important; color:#fff!important; font-weight:850!important; }
26
- .uhcp-transfer-main { min-width:0; padding:1rem; }
27
- .uhcp-transfer-patient,.uhcp-transfer-journey,.uhcp-transfer-review { border:1px solid #dce5ec; border-radius:.7rem; box-shadow:0 4px 16px rgb(16 39 84 / 5%); }
28
- .uhcp-transfer-patient { padding:1rem; }
29
- .uhcp-transfer-patient h2,.uhcp-transfer-journey h2,.uhcp-transfer-review h2 { font-size:1.18rem; margin:0; }
30
- .uhcp-transfer-patient>div { align-items:center; display:grid; gap:.75rem; grid-template-columns:minmax(11rem,.85fr) 1px minmax(13rem,1fr) auto; margin-top:.75rem; }
31
- .uhcp-transfer-patient button,.uhcp-transfer-patient label { align-items:center; background:var(--uhcp-surface,#fff); border:1px solid #9fb3c8; border-radius:.45rem; display:flex; gap:.65rem; min-height:3rem; padding:.7rem .9rem; }
32
- .uhcp-transfer-patient button { color:inherit; cursor:pointer; font-weight:800; justify-content:center; }
33
- .uhcp-transfer-patient button:last-child { background:var(--uhcp-surface-muted,#0796a8); border-color:var(--uhcp-text,#0796a8); color:#fff; }
34
- .uhcp-transfer-patient>div>span { background:var(--uhcp-surface-muted,#cbd7e1); height:2rem; }
35
- .uhcp-transfer-patient label { color:var(--uhcp-text,#64748b); }
36
- .uhcp-transfer-patient input { border:0; color:var(--uhcp-text,#102754); min-width:0; outline:0; width:100%; }
37
- .uhcp-transfer-journey { margin-top:.8rem; overflow:hidden; padding:1rem; }
38
- .uhcp-transfer-journey>header,.uhcp-transfer-review>header { align-items:center; display:flex; justify-content:space-between; }
39
- .uhcp-transfer-journey>header>div { display:flex; gap:.4rem; }
40
- .uhcp-transfer-journey>header button { align-items:center; background:var(--uhcp-surface,#fff); border:1px solid #cad7e2; border-radius:.45rem; color:inherit; display:flex; padding:.45rem; }
41
- .uhcp-transfer-journey>header button:first-child svg { transform:rotate(180deg); }
42
- .uhcp-transfer-rail { align-items:center; display:flex; gap:.8rem; min-height:18rem; overflow-x:auto; padding:1rem .25rem; scrollbar-color:#aebfce #edf2f5; }
43
- .uhcp-transfer-card { border:1px solid #cad7e2; border-radius:.5rem; flex:0 0 10rem; min-height:12rem; overflow:hidden; }
44
- .uhcp-transfer-card h3 { background:var(--uhcp-surface-muted,#087db8); color:var(--uhcp-text,#fff); font-size:.82rem; margin:0; padding:.65rem; }
45
- .uhcp-transfer-card-body { display:grid; gap:.45rem; padding:.85rem; }
46
- .uhcp-transfer-card-body time,.uhcp-transfer-card-body span,.uhcp-transfer-card-body code { color:var(--uhcp-text,#60738c); font-size:.72rem; }
47
- .uhcp-transfer-card-body small { background:var(--uhcp-surface-muted,#edf2f5); border-radius:999px; color:var(--uhcp-text,#466079); font-size:.7rem; justify-self:start; padding:.25rem .55rem; }
48
- .uhcp-transfer-card-body small[data-status=in-progress] { background:var(--uhcp-surface-muted,#d7f4e5); color:var(--uhcp-text,#087a47); }
49
- .uhcp-transfer-card-body small[data-status=completed] { background:var(--uhcp-surface-muted,#dff6e8); color:var(--uhcp-text,#087a47); }
50
- .uhcp-transfer-card-body small[data-status=on-hold] { background:var(--uhcp-surface-muted,#fff1d2); color:var(--uhcp-text,#9a5a00); }
51
- .uhcp-transfer-source { border-color:var(--uhcp-text,#078dcc); flex-basis:13.5rem; }
52
- .uhcp-transfer-destination { border-color:var(--uhcp-text,#069f69); flex-basis:13rem; }
53
- .uhcp-transfer-destination h3 { background:var(--uhcp-surface-muted,#069f69); }
54
- .uhcp-transfer-source fieldset { border:0; border-top:1px solid #dce5ec; margin:.2rem .7rem .7rem; padding:.7rem 0 0; }
55
- .uhcp-transfer-source legend { font-size:.72rem; font-weight:800; }
56
- .uhcp-transfer-source label { align-items:start; display:flex; gap:.45rem; padding:.35rem 0; }
57
- .uhcp-transfer-source label span { display:grid; }
58
- .uhcp-transfer-source label small { color:var(--uhcp-text,#60738c); font-size:.68rem; }
59
- .uhcp-transfer-arrow { align-items:center; color:var(--uhcp-text,#0796a8); display:grid; flex:0 0 5rem; grid-template-columns:1fr auto; text-align:center; }
60
- .uhcp-transfer-arrow span { font-size:.7rem; font-weight:800; grid-column:1/-1; }
61
- .uhcp-transfer-arrow i { background:var(--uhcp-surface-muted,#0796a8); height:2px; }
62
- .uhcp-transfer-arrow svg { margin-left:-.45rem; }
63
- .uhcp-transfer-help { background:var(--uhcp-surface-muted,#f4f9fc); border-radius:.5rem; padding:.65rem .8rem; }
64
- .uhcp-transfer-help summary { cursor:pointer; font-size:.78rem; font-weight:800; }
65
- .uhcp-transfer-help p { color:var(--uhcp-text,#51677e); font-size:.78rem; margin:.4rem 0 0; }
66
- .uhcp-transfer-controls { display:flex; gap:.55rem; justify-content:flex-end; padding-top:.75rem; }
67
- .uhcp-transfer-controls button { background:var(--uhcp-surface,#fff); border:1px solid #0796a8; border-radius:.45rem; color:var(--uhcp-text,#08738a); padding:.7rem 1rem; }
68
- .uhcp-transfer-review { margin-top:.8rem; padding:1rem; }
69
- .uhcp-transfer-review header p { background:var(--uhcp-surface-muted,#fff5dd); border:1px solid #f3ce79; border-radius:.4rem; color:var(--uhcp-text,#925800); font-size:.72rem; margin:0; padding:.5rem .7rem; }
70
- .uhcp-transfer-review ol { list-style:none; margin:.7rem 0 0; padding:0; }
71
- .uhcp-transfer-review li { align-items:center; border-top:1px solid #e1e8ee; display:grid; gap:.7rem; grid-template-columns:1.8rem 1fr auto; padding:.55rem; }
72
- .uhcp-transfer-review li>span { align-items:center; background:var(--uhcp-surface-muted,#e8f6fc); border-radius:50%; color:var(--uhcp-text,#087db8); display:flex; font-size:.72rem; font-weight:900; height:1.7rem; justify-content:center; width:1.7rem; }
73
- .uhcp-transfer-review li strong { font-size:.8rem; }
74
- .uhcp-transfer-review details { font-size:.68rem; }
75
- .uhcp-transfer-review summary { color:var(--uhcp-text,#60738c); cursor:pointer; }
76
- .uhcp-transfer-status { background:var(--uhcp-surface-muted,#dff6e8); border-radius:.45rem; color:var(--uhcp-text,#087a47); font-weight:750; padding:.75rem; }
77
- @media(max-width:900px){.uhcp-transfer-console{grid-template-columns:1fr}.uhcp-transfer-contacts{border-bottom:1px solid #dce5ec;border-inline-end:0}.uhcp-transfer-contact-actions{grid-template-columns:repeat(3,1fr)}.uhcp-transfer-patient>div{grid-template-columns:1fr}.uhcp-transfer-patient>div>span{display:none}.uhcp-transfer-review>header{align-items:flex-start;gap:.7rem;flex-direction:column}}
78
- @media(max-width:560px){.uhcp-transfer-main{padding:.55rem}.uhcp-transfer-contact-actions{grid-template-columns:1fr}.uhcp-transfer-rail{align-items:stretch}.uhcp-transfer-review li{grid-template-columns:1.8rem 1fr}.uhcp-transfer-review li details{grid-column:2}.uhcp-transfer-controls button{flex:1}.uhcp-transfer-review header p{font-size:.65rem}}
79
-
80
- .sos-encounter-journey { min-width:0; color:var(--uhcp-text,inherit); border:1px solid var(--uhcp-border,#dce5ec); border-radius:1rem; padding:clamp(.75rem,2vw,1.5rem); }
81
- .sos-encounter-journey>header,.sos-encounter-journey>form,.sos-encounter-actions { display:flex; align-items:center; flex-wrap:wrap; gap:.75rem; margin-bottom:1rem; }
82
- .sos-encounter-journey>header { justify-content:space-between; }
83
- .sos-encounter-journey h2 { margin:0; font-size:1.25rem; }
84
- .sos-encounter-journey label { display:grid; gap:.35rem; min-width:0; }
85
- .sos-encounter-journey select { max-width:100%; color:inherit; background:var(--uhcp-surface,#fff); border:1px solid var(--uhcp-border,#dce5ec); border-radius:.4rem; padding:.5rem; }
86
- .sos-encounter-journey button { cursor:pointer; border:1px solid var(--uhcp-border,#9bbfd1); border-radius:.5rem; padding:.55rem .8rem; color:inherit; background:var(--uhcp-surface-muted,#eef6fa); }
87
- .sos-encounter-journey button:disabled { opacity:.5; cursor:not-allowed; }
88
- .sos-encounter-journey button:focus-visible,.sos-encounter-journey select:focus-visible { outline:3px solid #1388c9; outline-offset:2px; }
89
- .sos-encounter-journey time,.sos-encounter-journey code { overflow-wrap:anywhere; }
90
- .sos-encounter-journey [role=alert] { color:var(--uhcp-danger,#b42318); }
91
- .sos-encounter-journey [role=status] { color:var(--uhcp-success,#087a47); }
1
+ .uhcp-transfer-console { background:var(--uhcp-surface,#fff); color:var(--uhcp-text,#102754); display:grid; font-family:Inter,ui-sans-serif,system-ui,sans-serif; grid-template-columns:minmax(16rem,23rem) minmax(0,1fr); min-height:calc(100vh - 4.5rem); }
2
+ .uhcp-transfer-console button,.uhcp-transfer-console input,.uhcp-transfer-console textarea { font:inherit; }
3
+ .uhcp-transfer-console svg { fill:none; height:1.25rem; stroke:currentColor; stroke-linecap:round; stroke-linejoin:round; stroke-width:1.8; width:1.25rem; }
4
+ .uhcp-transfer-contacts { border-inline-end:1px solid #dce5ec; padding:1.2rem; }
5
+ .uhcp-transfer-contacts summary { cursor:pointer; font-size:1.05rem; font-weight:850; list-style-position:inside; padding:.35rem 0 1rem; }
6
+ .uhcp-transfer-contact-list { border-block:1px solid #e2e9ef; display:grid; padding:.45rem 0; }
7
+ .uhcp-transfer-contact-list button { background:transparent; border:0; border-inline-start:3px solid transparent; color:inherit; cursor:pointer; display:grid; gap:.15rem; grid-template-columns:2.7rem 1fr; padding:.75rem; text-align:start; }
8
+ .uhcp-transfer-contact-list button[aria-pressed=true] { background:var(--uhcp-surface-muted,#eaf8fd); border-inline-start-color:var(--uhcp-text,#09a9dc); }
9
+ .uhcp-transfer-contact-list button>span { align-items:center; background:var(--uhcp-surface-muted,#d7e7f1); border-radius:50%; display:flex; font-weight:800; grid-row:span 2; height:2.4rem; justify-content:center; width:2.4rem; }
10
+ .uhcp-transfer-contact-list small { color:var(--uhcp-text,#58708e); }
11
+ .uhcp-transfer-contact-actions { display:grid; gap:.55rem; padding:1rem 0; }
12
+ .uhcp-transfer-contact-actions button,.uhcp-transfer-mode button,.uhcp-transfer-composer fieldset button { align-items:center; background:var(--uhcp-surface,#fff); border:1px solid #cad7e2; border-radius:.55rem; color:inherit; cursor:pointer; display:flex; gap:.7rem; padding:.7rem .85rem; }
13
+ .uhcp-transfer-contact-actions button[aria-pressed=true],.uhcp-transfer-mode button[aria-pressed=true] { background:var(--uhcp-surface-muted,#eaf8fd); border-color:var(--uhcp-text,#09a9dc); color:var(--uhcp-text,#006f96); font-weight:800; }
14
+ .uhcp-transfer-composer fieldset button[aria-pressed=true] { background:var(--uhcp-surface-muted,#eaf8fd); border-color:var(--uhcp-text,#09a9dc); color:var(--uhcp-text,#006f96); font-weight:800; }
15
+ .uhcp-transfer-composer { display:grid; gap:.8rem; }
16
+ .uhcp-transfer-composer h3 { font-size:.95rem; margin:.2rem 0 0; }
17
+ .uhcp-transfer-mode { display:grid; grid-template-columns:1fr 1fr; }
18
+ .uhcp-transfer-mode button { justify-content:center; }
19
+ .uhcp-transfer-composer label { display:grid; font-size:.82rem; font-weight:750; gap:.35rem; }
20
+ .uhcp-transfer-composer textarea { border:1px solid #cad7e2; border-radius:.55rem; color:inherit; resize:vertical; padding:.75rem; }
21
+ .uhcp-transfer-composer fieldset { border:0; margin:0; padding:0; }
22
+ .uhcp-transfer-composer legend { font-size:.82rem; font-weight:750; margin-bottom:.4rem; }
23
+ .uhcp-transfer-composer fieldset>div { display:flex; flex-wrap:wrap; gap:.4rem; }
24
+ .uhcp-transfer-record { background:var(--uhcp-surface,#fff); border:1px dashed #09a9dc; border-radius:.55rem; color:var(--uhcp-text,#006f96); padding:1rem; }
25
+ .uhcp-transfer-primary { background:#0796a8!important; border-color:#0796a8!important; color:#fff!important; font-weight:850!important; }
26
+ .uhcp-transfer-main { min-width:0; padding:1rem; }
27
+ .uhcp-transfer-patient,.uhcp-transfer-journey,.uhcp-transfer-review { border:1px solid #dce5ec; border-radius:.7rem; box-shadow:0 4px 16px rgb(16 39 84 / 5%); }
28
+ .uhcp-transfer-patient { padding:1rem; }
29
+ .uhcp-transfer-patient h2,.uhcp-transfer-journey h2,.uhcp-transfer-review h2 { font-size:1.18rem; margin:0; }
30
+ .uhcp-transfer-patient>div { align-items:center; display:grid; gap:.75rem; grid-template-columns:minmax(11rem,.85fr) 1px minmax(13rem,1fr) auto; margin-top:.75rem; }
31
+ .uhcp-transfer-patient button,.uhcp-transfer-patient label { align-items:center; background:var(--uhcp-surface,#fff); border:1px solid #9fb3c8; border-radius:.45rem; display:flex; gap:.65rem; min-height:3rem; padding:.7rem .9rem; }
32
+ .uhcp-transfer-patient button { color:inherit; cursor:pointer; font-weight:800; justify-content:center; }
33
+ .uhcp-transfer-patient button:last-child { background:var(--uhcp-surface-muted,#0796a8); border-color:var(--uhcp-text,#0796a8); color:#fff; }
34
+ .uhcp-transfer-patient>div>span { background:var(--uhcp-surface-muted,#cbd7e1); height:2rem; }
35
+ .uhcp-transfer-patient label { color:var(--uhcp-text,#64748b); }
36
+ .uhcp-transfer-patient input { border:0; color:var(--uhcp-text,#102754); min-width:0; outline:0; width:100%; }
37
+ .uhcp-transfer-journey { margin-top:.8rem; overflow:hidden; padding:1rem; }
38
+ .uhcp-transfer-journey>header,.uhcp-transfer-review>header { align-items:center; display:flex; justify-content:space-between; }
39
+ .uhcp-transfer-journey>header>div { display:flex; gap:.4rem; }
40
+ .uhcp-transfer-journey>header button { align-items:center; background:var(--uhcp-surface,#fff); border:1px solid #cad7e2; border-radius:.45rem; color:inherit; display:flex; padding:.45rem; }
41
+ .uhcp-transfer-journey>header button:first-child svg { transform:rotate(180deg); }
42
+ .uhcp-transfer-rail { align-items:center; display:flex; gap:.8rem; min-height:18rem; overflow-x:auto; padding:1rem .25rem; scrollbar-color:#aebfce #edf2f5; }
43
+ .uhcp-transfer-card { border:1px solid #cad7e2; border-radius:.5rem; flex:0 0 10rem; min-height:12rem; overflow:hidden; }
44
+ .uhcp-transfer-card h3 { background:var(--uhcp-surface-muted,#087db8); color:var(--uhcp-text,#fff); font-size:.82rem; margin:0; padding:.65rem; }
45
+ .uhcp-transfer-card-body { display:grid; gap:.45rem; padding:.85rem; }
46
+ .uhcp-transfer-card-body time,.uhcp-transfer-card-body span,.uhcp-transfer-card-body code { color:var(--uhcp-text,#60738c); font-size:.72rem; }
47
+ .uhcp-transfer-card-body small { background:var(--uhcp-surface-muted,#edf2f5); border-radius:999px; color:var(--uhcp-text,#466079); font-size:.7rem; justify-self:start; padding:.25rem .55rem; }
48
+ .uhcp-transfer-card-body small[data-status=in-progress] { background:var(--uhcp-surface-muted,#d7f4e5); color:var(--uhcp-text,#087a47); }
49
+ .uhcp-transfer-card-body small[data-status=completed] { background:var(--uhcp-surface-muted,#dff6e8); color:var(--uhcp-text,#087a47); }
50
+ .uhcp-transfer-card-body small[data-status=on-hold] { background:var(--uhcp-surface-muted,#fff1d2); color:var(--uhcp-text,#9a5a00); }
51
+ .uhcp-transfer-source { border-color:var(--uhcp-text,#078dcc); flex-basis:13.5rem; }
52
+ .uhcp-transfer-destination { border-color:var(--uhcp-text,#069f69); flex-basis:13rem; }
53
+ .uhcp-transfer-destination h3 { background:var(--uhcp-surface-muted,#069f69); }
54
+ .uhcp-transfer-source fieldset { border:0; border-top:1px solid #dce5ec; margin:.2rem .7rem .7rem; padding:.7rem 0 0; }
55
+ .uhcp-transfer-source legend { font-size:.72rem; font-weight:800; }
56
+ .uhcp-transfer-source label { align-items:start; display:flex; gap:.45rem; padding:.35rem 0; }
57
+ .uhcp-transfer-source label span { display:grid; }
58
+ .uhcp-transfer-source label small { color:var(--uhcp-text,#60738c); font-size:.68rem; }
59
+ .uhcp-transfer-arrow { align-items:center; color:var(--uhcp-text,#0796a8); display:grid; flex:0 0 5rem; grid-template-columns:1fr auto; text-align:center; }
60
+ .uhcp-transfer-arrow span { font-size:.7rem; font-weight:800; grid-column:1/-1; }
61
+ .uhcp-transfer-arrow i { background:var(--uhcp-surface-muted,#0796a8); height:2px; }
62
+ .uhcp-transfer-arrow svg { margin-left:-.45rem; }
63
+ .uhcp-transfer-help { background:var(--uhcp-surface-muted,#f4f9fc); border-radius:.5rem; padding:.65rem .8rem; }
64
+ .uhcp-transfer-help summary { cursor:pointer; font-size:.78rem; font-weight:800; }
65
+ .uhcp-transfer-help p { color:var(--uhcp-text,#51677e); font-size:.78rem; margin:.4rem 0 0; }
66
+ .uhcp-transfer-controls { display:flex; gap:.55rem; justify-content:flex-end; padding-top:.75rem; }
67
+ .uhcp-transfer-controls button { background:var(--uhcp-surface,#fff); border:1px solid #0796a8; border-radius:.45rem; color:var(--uhcp-text,#08738a); padding:.7rem 1rem; }
68
+ .uhcp-transfer-review { margin-top:.8rem; padding:1rem; }
69
+ .uhcp-transfer-review header p { background:var(--uhcp-surface-muted,#fff5dd); border:1px solid #f3ce79; border-radius:.4rem; color:var(--uhcp-text,#925800); font-size:.72rem; margin:0; padding:.5rem .7rem; }
70
+ .uhcp-transfer-review ol { list-style:none; margin:.7rem 0 0; padding:0; }
71
+ .uhcp-transfer-review li { align-items:center; border-top:1px solid #e1e8ee; display:grid; gap:.7rem; grid-template-columns:1.8rem 1fr auto; padding:.55rem; }
72
+ .uhcp-transfer-review li>span { align-items:center; background:var(--uhcp-surface-muted,#e8f6fc); border-radius:50%; color:var(--uhcp-text,#087db8); display:flex; font-size:.72rem; font-weight:900; height:1.7rem; justify-content:center; width:1.7rem; }
73
+ .uhcp-transfer-review li strong { font-size:.8rem; }
74
+ .uhcp-transfer-review details { font-size:.68rem; }
75
+ .uhcp-transfer-review summary { color:var(--uhcp-text,#60738c); cursor:pointer; }
76
+ .uhcp-transfer-status { background:var(--uhcp-surface-muted,#dff6e8); border-radius:.45rem; color:var(--uhcp-text,#087a47); font-weight:750; padding:.75rem; }
77
+ @media(max-width:900px){.uhcp-transfer-console{grid-template-columns:1fr}.uhcp-transfer-contacts{border-bottom:1px solid #dce5ec;border-inline-end:0}.uhcp-transfer-contact-actions{grid-template-columns:repeat(3,1fr)}.uhcp-transfer-patient>div{grid-template-columns:1fr}.uhcp-transfer-patient>div>span{display:none}.uhcp-transfer-review>header{align-items:flex-start;gap:.7rem;flex-direction:column}}
78
+ @media(max-width:560px){.uhcp-transfer-main{padding:.55rem}.uhcp-transfer-contact-actions{grid-template-columns:1fr}.uhcp-transfer-rail{align-items:stretch}.uhcp-transfer-review li{grid-template-columns:1.8rem 1fr}.uhcp-transfer-review li details{grid-column:2}.uhcp-transfer-controls button{flex:1}.uhcp-transfer-review header p{font-size:.65rem}}
79
+
80
+ .sos-encounter-journey { min-width:0; color:var(--uhcp-text,inherit); border:1px solid var(--uhcp-border,#dce5ec); border-radius:1rem; padding:clamp(.75rem,2vw,1.5rem); }
81
+ .sos-encounter-journey>header,.sos-encounter-journey>form,.sos-encounter-actions { display:flex; align-items:center; flex-wrap:wrap; gap:.75rem; margin-bottom:1rem; }
82
+ .sos-encounter-journey>header { justify-content:space-between; }
83
+ .sos-encounter-journey h2 { margin:0; font-size:1.25rem; }
84
+ .sos-encounter-journey label { display:grid; gap:.35rem; min-width:0; }
85
+ .sos-encounter-journey select { max-width:100%; color:inherit; background:var(--uhcp-surface,#fff); border:1px solid var(--uhcp-border,#dce5ec); border-radius:.4rem; padding:.5rem; }
86
+ .sos-encounter-journey button { cursor:pointer; border:1px solid var(--uhcp-border,#9bbfd1); border-radius:.5rem; padding:.55rem .8rem; color:inherit; background:var(--uhcp-surface-muted,#eef6fa); }
87
+ .sos-encounter-journey button:disabled { opacity:.5; cursor:not-allowed; }
88
+ .sos-encounter-journey button:focus-visible,.sos-encounter-journey select:focus-visible { outline:3px solid #1388c9; outline-offset:2px; }
89
+ .sos-encounter-journey time,.sos-encounter-journey code { overflow-wrap:anywhere; }
90
+ .sos-encounter-journey [role=alert] { color:var(--uhcp-danger,#b42318); }
91
+ .sos-encounter-journey [role=status] { color:var(--uhcp-success,#087a47); }
package/package.json CHANGED
@@ -1,110 +1,111 @@
1
- {
2
- "name": "sos-portal-components-react",
3
- "version": "0.3.4",
4
- "description": "Shared portal UI for base components",
5
- "license": "Apache-2.0",
6
- "type": "module",
7
- "main": "./dist/index.js",
8
- "types": "./dist/index.d.ts",
9
- "exports": {
10
- "./subject-card-locator-fields": {
11
- "types": "./dist/SubjectCardLocatorFields.d.ts",
12
- "default": "./dist/SubjectCardLocatorFields.js"
13
- },
14
- "./device-assistance-preferences": {
15
- "types": "./dist/DeviceAssistancePreferences.d.ts",
16
- "default": "./dist/DeviceAssistancePreferences.js"
17
- },
18
- ".": {
19
- "types": "./dist/index.d.ts",
20
- "default": "./dist/index.js"
21
- },
22
- "./subject-conversation-chat": {
23
- "types": "./dist/SubjectConversationChat.d.ts",
24
- "default": "./dist/SubjectConversationChat.js"
25
- },
26
- "./encounter-journey": {
27
- "types": "./dist/EncounterJourneyPanel.d.ts",
28
- "default": "./dist/EncounterJourneyPanel.js"
29
- },
30
- "./encounter-transfer-console": {
31
- "types": "./dist/EncounterTransferConsole.d.ts",
32
- "default": "./dist/EncounterTransferConsole.js"
33
- },
34
- "./encounter-journey.css": "./dist/encounter-journey.css"
35
- },
36
- "files": [
37
- "dist",
38
- "README.md",
39
- "CHANGELOG.md"
40
- ],
41
- "scripts": {
42
- "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
43
- "build": "npm run clean && tsc -p tsconfig.build.json && node -e \"require('node:fs').copyFileSync('src/encounter-journey.css','dist/encounter-journey.css')\"",
44
- "typecheck": "tsc -p tsconfig.json --noEmit",
45
- "test": "vitest run --maxWorkers=1",
46
- "check": "npm run typecheck && npm test && npm run build",
47
- "prepack": "npm run check"
48
- },
49
- "engines": {
50
- "node": ">=24.0.0"
51
- },
52
- "peerDependencies": {
53
- "@kesha-antonov/react-native-chat": "^6.0.1",
54
- "livekit-client": ">=2.23.0 <3",
55
- "react": ">=18.3.0",
56
- "react-dom": ">=18.3.0",
57
- "react-native": ">=0.82.0",
58
- "react-native-gesture-handler": ">=3.0.0",
59
- "react-native-keyboard-controller": ">=1.0.0",
60
- "react-native-reanimated": ">=3.0.0",
61
- "react-native-safe-area-context": ">=5.0.0"
62
- },
63
- "peerDependenciesMeta": {
64
- "@kesha-antonov/react-native-chat": {
65
- "optional": true
66
- },
67
- "livekit-client": {
68
- "optional": true
69
- },
70
- "react-native": {
71
- "optional": true
72
- },
73
- "react-native-gesture-handler": {
74
- "optional": true
75
- },
76
- "react-native-keyboard-controller": {
77
- "optional": true
78
- },
79
- "react-native-reanimated": {
80
- "optional": true
81
- },
82
- "react-native-safe-area-context": {
83
- "optional": true
84
- }
85
- },
86
- "dependencies": {
87
- "antifraud-portal-components-react": "0.3.0",
88
- "fhir-data-utils-ts": "0.6.24",
89
- "sos-data-utils-ts": "0.6.34"
90
- },
91
- "devDependencies": {
92
- "@testing-library/react": "^16.3.2",
93
- "@types/node": "22.19.15",
94
- "@types/react": "19.2.17",
95
- "@types/react-dom": "19.2.3",
96
- "jsdom": "26.1.0",
97
- "livekit-client": "2.23.0",
98
- "react": "19.2.8",
99
- "react-dom": "19.2.8",
100
- "typescript": "5.9.3",
101
- "vitest": "4.1.12"
102
- },
103
- "publishConfig": {
104
- "access": "public"
105
- },
106
- "repository": {
107
- "type": "git",
108
- "url": "git+https://github.com/soschain/sos-portal-components-react.git"
109
- }
110
- }
1
+ {
2
+ "name": "sos-portal-components-react",
3
+ "version": "0.4.0",
4
+ "description": "Shared portal UI for base components",
5
+ "license": "Apache-2.0",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ "./subject-card-locator-fields": {
11
+ "types": "./dist/SubjectCardLocatorFields.d.ts",
12
+ "default": "./dist/SubjectCardLocatorFields.js"
13
+ },
14
+ "./device-assistance-preferences": {
15
+ "types": "./dist/DeviceAssistancePreferences.d.ts",
16
+ "default": "./dist/DeviceAssistancePreferences.js"
17
+ },
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "default": "./dist/index.js"
21
+ },
22
+ "./subject-conversation-chat": {
23
+ "types": "./dist/SubjectConversationChat.d.ts",
24
+ "default": "./dist/SubjectConversationChat.js"
25
+ },
26
+ "./encounter-journey": {
27
+ "types": "./dist/EncounterJourneyPanel.d.ts",
28
+ "default": "./dist/EncounterJourneyPanel.js"
29
+ },
30
+ "./encounter-transfer-console": {
31
+ "types": "./dist/EncounterTransferConsole.d.ts",
32
+ "default": "./dist/EncounterTransferConsole.js"
33
+ },
34
+ "./encounter-journey.css": "./dist/encounter-journey.css"
35
+ },
36
+ "files": [
37
+ "dist",
38
+ "README.md",
39
+ "CHANGELOG.md"
40
+ ],
41
+ "scripts": {
42
+ "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
43
+ "build": "npm run clean && tsc -p tsconfig.build.json && node -e \"require('node:fs').copyFileSync('src/encounter-journey.css','dist/encounter-journey.css')\"",
44
+ "typecheck": "tsc -p tsconfig.json --noEmit",
45
+ "test": "vitest run --maxWorkers=1",
46
+ "check:independent-dependencies": "node --test tests/no-gdc-dependencies.contract.mjs",
47
+ "check": "npm run typecheck && npm test && npm run build && npm run check:independent-dependencies",
48
+ "prepack": "npm run check"
49
+ },
50
+ "engines": {
51
+ "node": ">=24.0.0"
52
+ },
53
+ "peerDependencies": {
54
+ "@kesha-antonov/react-native-chat": "^6.0.1",
55
+ "livekit-client": ">=2.23.0 <3",
56
+ "react": ">=18.3.0",
57
+ "react-dom": ">=18.3.0",
58
+ "react-native": ">=0.82.0",
59
+ "react-native-gesture-handler": ">=3.0.0",
60
+ "react-native-keyboard-controller": ">=1.0.0",
61
+ "react-native-reanimated": ">=3.0.0",
62
+ "react-native-safe-area-context": ">=5.0.0"
63
+ },
64
+ "peerDependenciesMeta": {
65
+ "@kesha-antonov/react-native-chat": {
66
+ "optional": true
67
+ },
68
+ "livekit-client": {
69
+ "optional": true
70
+ },
71
+ "react-native": {
72
+ "optional": true
73
+ },
74
+ "react-native-gesture-handler": {
75
+ "optional": true
76
+ },
77
+ "react-native-keyboard-controller": {
78
+ "optional": true
79
+ },
80
+ "react-native-reanimated": {
81
+ "optional": true
82
+ },
83
+ "react-native-safe-area-context": {
84
+ "optional": true
85
+ }
86
+ },
87
+ "dependencies": {
88
+ "antifraud-portal-components-react": "0.3.0",
89
+ "fhir-data-utils-ts": "0.7.0",
90
+ "sos-data-utils-ts": "0.7.0"
91
+ },
92
+ "devDependencies": {
93
+ "@testing-library/react": "^16.3.2",
94
+ "@types/node": "22.19.15",
95
+ "@types/react": "19.2.17",
96
+ "@types/react-dom": "19.2.3",
97
+ "jsdom": "26.1.0",
98
+ "livekit-client": "2.23.0",
99
+ "react": "19.2.8",
100
+ "react-dom": "19.2.8",
101
+ "typescript": "5.9.3",
102
+ "vitest": "4.1.12"
103
+ },
104
+ "publishConfig": {
105
+ "access": "public"
106
+ },
107
+ "repository": {
108
+ "type": "git",
109
+ "url": "git+https://github.com/soschain/sos-portal-components-react.git"
110
+ }
111
+ }