@primocaredentgroup/chat-ui
v2.1.4
Published
Typed API references, shared types, and React utilities for PrimoUp chat orchestrator
Downloads
706
Readme
@primocaredentgroup/chat-ui
Shared frontend utilities for PrimoUp and PrimoLab. The package contains typed Core API references, presentation types, React hooks for authenticated Lab actions, and a Convex client context. It does not contain the complete chat widget, patient permissions, backend domain logic, or service credentials.
The backend is @primocaredentgroup/chat-backend-component, mounted only in PrimoUpCore as primoChat. The visible chat panels remain in each product's src/components/chat directory.
Entry points
| Import | Contents |
| --- | --- |
| @primocaredentgroup/chat-ui | Core API references, complete Core types, React helpers and provider |
| …/orchestrator, …/advanced, …/primocheckBridge | Typed references to Core's public functions |
| …/types | Complete Core response/argument types; opaque string IDs |
| …/presentation | Minimal shapes rendered by either host |
| …/react | Action query/mutation hooks, explicit SLA clock and per-adapter refresh scope |
| …/bridge | Shared server wire validators; requires backend component 0.3.2, without mounting another Chat instance |
| …/provider | Context for a host-owned Convex client |
PrimoUp: realtime on the existing authenticated client
import { useQuery } from "convex/react";
import { chatOrchestrator } from "@primocaredentgroup/chat-ui/orchestrator";
import { useChatClock } from "@primocaredentgroup/chat-ui/react";
const messages = useQuery(chatOrchestrator.listMessagesFiltered,
authenticated && threadId ? { subchannelId: threadId } : "skip");
const now = useChatClock(30_000);Authentication and resource permissions are enforced by the Core handlers. References exported from /orchestrator, /advanced and /primocheckBridge target Core, not the Lab deployment.
PrimoLab: host adapter and authenticated server bridge
Lab supplies references from its own generated api.api.primoUpChatBridge. The shared library does not import another repository's generated API or construct cross-deployment URLs.
import {
createChatRefreshScope, useChatActionQuery, useChatActionMutation,
} from "@primocaredentgroup/chat-ui/react";
import { api } from "./convex/_generated/api";
// Create once, outside render, in the application's adapter.
const refreshScope = createChatRefreshScope();
function useMessages(threadId: string, serverResolvedUserKey: string | null) {
return useChatActionQuery(api.api.primoUpChatBridge.listMessagesFiltered,
{ subchannelId: threadId }, { sessionKey: serverResolvedUserKey, refreshScope });
}Use the authenticated host query to obtain the user key. An absent identity or "skip" disables reads and hides cached data. Reads refresh every 15 seconds while visible, on focus, after visibility changes and after successful writes through useChatActionMutation with the same refresh scope. In-flight reads coalesce refreshes. Responses from old arguments, old sessions or unmounted components are ignored. Read errors reach the host's error boundary; it owns localized error and retry UI.
A refresh scope belongs to one application adapter. It is not a window-global event. Core may keep its native realtime queries; Lab's action polling is not a cross-deployment websocket subscription.
Client ownership
Prefer the host's existing authenticated client:
<ChatConvexProvider client={hostClient}>{children}</ChatConvexProvider>The package neither changes that client's authentication nor closes it. The legacy convexUrl + authToken props remain only for existing Core integrations; their owned clients now close on unmount and token/URL changes, including React StrictMode. The token is never logged or exposed through the context. Do not use this legacy mode in Lab: Lab authenticates its own client and calls Core exclusively from its backend.
2.1.2 integration
- Adds shared Lab/Core wire validators at
/bridge(backend peer^0.3.2). Hosts that import this server entrypoint install@primocaredentgroup/chat-backend-componentexplicitly. - Adds
listPatientChatswith Convex pagination, pending-treatment counts and clinic IDs. Widget unread totals take{ now, clinicId? }. - Patient structures support a missing fiscal code. Lab matching still requires the canonical fiscal-code/prescription mapping.
- Core uses the existing realtime client; Lab uses only authenticated actions on its own client. No
VITE_CONVEX_URL_CHATis needed.
Contract corrections in 2.1.1
- Upload requires
{ subchannelId }; downloading an attachment requires{ storageId, messageId }. - SLA preview accepts
now, supplied by the UI clock. - PrimoCheck uses the real
revealMessageAuthorendpoint; the formergetMessageRealAuthorexport is a deprecated alias to it. - PrimoCheck channel creation returns
{ channelId, subchannelId }; send operations returnnull. - Added references for PrimoCheck chat info and authorized attachment upload.
Existing clients should recompile against these corrected contracts. The backend decides user identity, roles, side and resource scope; frontend types do not grant access.
Development and release
Source of truth: PrimoUpCore/packages/chat-ui. Do not maintain a second implementation in primoLabCoreV2/vendor/chat-ui. Lab keeps only its adapter to generated APIs and imports the published package.
npm ci
npm run verify
npm pack --dry-runTests cover session isolation, late responses, conversation changes, polling lifecycle, write-triggered refresh and client ownership. Both hosts should consume the same exact published version in their manifests and lockfiles. Package build and tests do not replace host typechecks and browser integration checks.
GitHub Actions validates package changes with React 18 and 19. publish-chat-ui.yml runs on relevant main changes or manual dispatch and publishes through npm Trusted Publishing/OIDC. Configure its GitHub publisher as organization primocaredentgroup, repository PrimoUpCore, workflow filename publish-chat-ui.yml, no environment, with direct publishing allowed. This existing package retains public npm access.
An unchanged committed version receives one automatic patch commit updating both manifests. An explicit stable version increase is preserved; downgrades and prereleases are rejected. The job checks the current remote head before publishing, publishes the verified tarball, compares registry integrity and latest, and installs a fresh consumer. An existing immutable version is accepted only if its integrity matches. A failed run can be retried without inventing another version. Release artifacts are retained even if the registry verification fails. This workflow does not deploy either host application.
