Skip to main content

8. Add the coach relationship

What we are building​

A member can invite a human coach and, after the sharing flow succeeds, the coach can review the member's tutorial-project record. The app records a CareTeam relationship separately from the access grant.

What you should already have​

The implementation​

Invite and share​

Use the current Core hook for the documented patient-to-practitioner flow:

import { useClient, useInvitePractitioner } from "@ovok/core";
import { Button, Text, View } from "react-native";

export function InviteCoachButton({
email,
firstName,
lastName,
}: {
email: string;
firstName: string;
lastName: string;
}) {
const { mutate, loading, error } = useInvitePractitioner();

async function invite() {
try {
await mutate({ email, firstName, lastName });
} catch {
// Keep the hook's error visible near this action.
}
}

return (
<View>
<Button
title="Invite my coach"
disabled={loading}
onPress={() => void invite()}
/>
{error ? <Text accessibilityRole="alert">{error.message}</Text> : null}
</View>
);
}

The invitation endpoint intentionally returns the same accepted response for several address outcomes. Do not use it to reveal whether an email already has an account. The practitioner accepts through their own signed-in app. The share is active only after the acceptance flow succeeds. See the full route and response contract.

The built-in share covers the whole Patient record in this project. It is not a wellness-only share. Keep this tutorial isolated in a project whose full record is appropriate for this coach. If the product requires a narrower data scope, stop here and implement a server-enforced sharing/authorization design before using real member data.

Record the care-team relationship​

Practitioner registration creates the account's Practitioner resource. A PractitionerRole can describe the person's actual role and organization; it does not verify a credential. After the invitation has been accepted, an authorized workflow may record the relationship as a FHIR CareTeam:

export function useCreateCareTeamAssignment() {
const client = useClient();

return async (patientId: string, practitionerId: string) => {
const careTeam = {
resourceType: "CareTeam" as const,
status: "active",
name: "Wellness coaching",
subject: { reference: "Patient/" + patientId },
participant: [
{
member: { reference: "Practitioner/" + practitionerId },
role: [{ text: "Wellness coach" }],
},
],
};

// Run only in a trusted, authorized flow whose AccessPolicy permits this write.
return client.createResource(careTeam);
};
}

Create the CareTeam only if the project workflow and authorization policy allow it. Do not let an arbitrary patient or coach assign arbitrary resource references. The resource documents the relationship; it does not grant access.

Coach review​

The coach dashboard loads the assigned Patient's records using the coach's authenticated Ovok client. Query only after the server has authorized that coach for the Patient:

const observations = await client.searchResources("Observation", {
patient: "Patient/" + patientId,
});

const reflections = await client.searchResources("QuestionnaireResponse", {
patient: "Patient/" + patientId,
});

Render only what those authorized responses return. Never fetch a project-wide list and filter it in React. A route parameter or a CareTeam participant entry is not proof of permission.

Important Ovok decisions​

  • FHIR Practitioner describes a person; PractitionerRole describes a role at an organization; CareTeam relates people to a Patient.
  • Identity, relationship and authorization are separate. AccessPolicy and the accepted share enforce access on the server.
  • The current built-in patient-to-practitioner share is whole-record and cannot be narrowed to only wellness resources.
  • Use the AccessPolicy model and sharing route to verify access. Test both assigned and unassigned patients.
  • Do not imply that a coach is a licensed clinician unless that is true and represented appropriately by the product.

Expected result​

A member can send a coach invitation, the practitioner accepts it, and the server permits authorized reads for the shared Patient. A CareTeam can document the assignment without being treated as the permission mechanism.

Common errors and troubleshooting​

SymptomCheck
Invitation returns accepted but coach cannot see a PatientThe response is intentionally non-disclosing; verify acceptance, project membership and share state using the documented flow.
A coach can see an unrelated PatientFix the server-side policy immediately. Client-side filtering is not an access boundary.
Creating CareTeam failsCheck project CapabilityStatement and the caller's AccessPolicy. Do not grant broad project access just to make the write succeed.
Product needs wellness-only sharingDo not reuse the whole-record flow. Define a narrower server-enforced authorization design first.

Previous / next​