FHIR Timenotifikasjon

Beskrivelse

Timenotifikasjon gir mulighet til å sende innbygger en notifikasjon om ny eller endret avtale. Eksterne aktører kan anvende Helsenorge's FHIR-endepunkt for å levere/synkronisere basisinformasjon om avtaler til innbyggere som er aktive på Helsenorge. Sekvensdiagram for funksjonen er vist i figuren under.

Helsenorge er ikke kildesystem for disse timene og i første omgang vil ikke Helsenorge tilby et endepunkt som støtter spørring/uthenting av timeinformasjonen som er lagret. Avsender/kildesystemet må dermed holde status på oversendte timer, og eventuelt overføre timenotifikasjoner på nytt hvis det er tvil om timer er synkronisert eller en innbygger blir digitalt aktiv. Helsenorge sitt endepunkt vil vite om innslaget er ny time (ikke sett før), en allerede overført time som har blitt endret siden sist overføring, eller identisk time (ingen endringer siden sist overføring), og vil kun varsle innbygger om relevante endringer. Se "Hendelser som gir varsel til innbygger" under.

Endepunkt

Operasjoner

 

FHIR-tjenesten forventer en PUT mot Appointment-endepunktet, der innholdet (body) er av type Appointment (som også inneholder støtteinformasjonen som behøves for kalenderobjektet til timen). For å støtte både opprettelse og oppdatering av timer i samme type kall så må en egen header-verdi legges med i PUT-kallet; If-None-Exist, sammen med en søkeparameter.

Verdien til If-None-Exist blir: "identifier=no-citizenportal-client|klientnavn&identifier=no-citizenportal-sourcesystem|systemnavn&identifier=no-citizenportal-instanceidentifier|timeidentifikator&participant.actor:Patient=urn:oid:2.16.578.1.12.4.1.4.1|fødselsnummer".

Denne anvendes for å finne ut om timen finnes fra før av, dvs. om timen skal opprettes eller oppdateres, og har også et krav om å matche med verdiene inne i Appointment-objektet som sendes med i body. I første omgang vil vi ikke støtte POST og/eller vanlig PUT (PUT uten If-None-Exist), fordi det krever at vi speiler ut ekstern identifikator (.id) på timen, og det gjør vi ikke i denne versjonen.

URL

Timenotifikasjon: forespørsel vil være på formen https://<miljø>/timeavtaler/api/<versjon>/Appointment
Eksempel fra integrasjonstestmiljø: https://eksternapi-hn-mas-02.int-hn.nhn.no/timeavtaler/api/v1/Appointment

Token: Uthenting av token gjøres fra STS, for informasjon se https://helsenorge.atlassian.net/wiki/spaces/HELSENORGE/pages/23789578

Offentlig sertifikat kan anvendes for avsender til å validere tokenet fra Helsenorge sin STS-tjeneste.
Eksempel for mas-02: https://eksternapi-hn-mas-02.int-hn.nhn.no/sts/helsenorge-oidc-provider/v1/jwk

Sikkerhet

Endepunktet har krav om at aktøren som utfører spørringen har sikkerhetsbillett/token utstedt fra Helsenorge sin STS-tjeneste.  I tillegg må timens verdi for identifikator no-citizenportal-client stemme overens med client_name i sikkerhetsbilletten (client_name-verdien settes når tilgangen opprettes i STS), se kapittel "Respons fra helsenorge.no" - "Sjekk av kildesystem" under.

Mapping

Datafelter

Tabellen under viser hvilken informasjon som skal overføres for en time som sendes til helsenorge og mapping til informasjonsjomodell i helsenorge.no. Ressursen er Appointment, med en egen profil som også inneholder contained-ressurser. Dekker påkrevde felter for timer i primærhelsetjenesten.

Appointment-attributt

Beskrivelse

Eksempel

Påkrevd

Logikk

Database

Internmapping primær

GUI

Extension

Cancel
Valgfritt felt i FHIR-extension communicationoptions, som kan anvendes på timen.

True

Nei

Et ja her gir funksjonalitet/knapp for å kansellere timen.

KanAvbestilles
(Kalenderelement - Nytt felt)

CancelAppointmentHash

Vise knapp for avbestill time

CancelTimeUntil
(krever at Cancel er true)
NB: ikke i bruk enda

Valgfritt felt i FHIR-extension communicationoptions, som kan anvendes på timen.

2019-06-02T08:30:00.000+01:00

Nei

Sjekkes først hvis Cancel er true. Gir tidspunktet for når timen ikke lengre skal være mulig å kansellere (for eksempel en dag før timen).





Fjerner avbestill-knappen når tidspunktet har passert.

Identifier

Timeidentifikator i avsenders system
(no-citizenportal-instanceidentifier)
Anvendes for å unikt identifisere timer
Anvendes i spørringer

3546c8f7-3cd3-4693-929e-66501642504c

Ja



EksternAvtaleId
(Kalenderelement)





Identifier

Id for underliggende system/tjeneste som
leverer timeavtalen
(no-citizenportal-sourcesystem)
Anvendes i spørringer

15-3fb9c0f4-1d9b-44b6-8d64-d36820115274

Ja



EksternSystemId
(Kalenderelement)





Identifier

Id for aktør som leverer dataene
(no-citizenportal-client)
Anvendes i spørringer
Kan anvendes for å finne endepunkt
dersom ytterligere detaljer om timen skal hentes.

Opus

Ja

Ved mottak valideres denne verdien (timens aktør/kilde) opp mot systemet som kaller APIet (hentes fra token)

EksternAktorId
(Kalenderelement - Nytt felt)





Status

Status på timen

"booked", "cancelled", "entered-in-error"

Ja

Mapper alle statusene vi får over til AvtaleStatusId (sjekk også AppointmentStatus)
booked = 2 (ReservertBekreftet) 
cancelled = 5 (AvbestiltBekreftet)
entered-in-error = 14 (Feilregistrering)

AvtalestatusId
(Kalenderelement)

Status

Status (ikon og tekst)

serviceCategory

Timens tjenestekategori

10 (Dental)
27 (Specialist Medical)
17 (General Practice)
7 (Community Health Care)

Nei

Mappes over til motparttype-verdien.
10 (Dental) mappes over til motparttype 11 (Primarhelsetjeneste).
Defaulter til "Primarhelsetjeneste".

KalenderElementMotpartTypeId
(Kalenderelement)

AppointmentType



appointmentType

Timetype fra kodeverk 7617 - "Timetype innbyggerportal"

"Ordinær", "Hastetime", "Video"

Nei

Mappe appointmentType til AvtaleTypeId.
Ordinær = NULL (ingen verdi gir GUI-verdi "Time")
Hastetime = 11 (Hastetime)
Video = 10 (Video).
Defaulter til "Ordinær".

AvtaleTypeId
(Kalenderelement)

AvtaleType

Tittel (en del av teksten)

description

Beskrivelse av timen/timen gjelder

"Oppfølging av kontrolltime"

Nei



Emne
(Kalenderelement)

Subject

Timen gjelder

supportingInformation

Contained ressurs av type Organization. Definerer tjenesten, og har referanse til organisasjonen.

Identifier definerer HerId-nivå 2
Name definerer tjenestenavnet

partOf.reference.identifier definerer Organisasjonsnummeret
partOf.reference.display definerer organisasjonsnavnet

supportingInformation.type: "Organization"
supportingInformation.reference: #54321

Ja









identifier.system: "urn:oid:2.16.578.1.12.4.1.2"
identifier.value: "140890"

Nei



HerId2
(Kalenderelement)

OrganizationHerIdLevel2



name: "Allmen tannhelse"

Ja



MotpartTjeneste
(Kalenderelement)

ServiceDescription

Tittel (en del av teksten)

partOf.reference.type: "Organization"

Ja









partOf.reference.identifier.system: "urn:oid:2.16.578.1.12.4.1.4.101"
partOf.reference.identifier.value: "948554062"

Ja

Behøves for å ha en unik referanse til organisasjonsressursen, men anvendes ikke (lagres ikke).







partOf.reference.display: "SiO Helse"

Ja



MotpartOrganisasjon
(Kalenderelement)

Organization

Tittel (en del av teksten)

supportingInformation

Contained ressurs av type Location som gir oppmøtested.

supportingInformation.type: "Location"
supportingInformation.reference: #12345



Nei









address.text: "Skiringssalveien 20, Sandefjord"



OppmoteSted
(Kalenderelement)

Location

Oppmøtested
(ikke aktuelt for videotimer)

Start

Start-tidspunktet

2019-06-03T08:00:00.000+01:00

Ja



Starttidspunkt
(Kalenderelement)

StartTime

Starttidspunkt

End

Slutt-tidspunktet

2019-06-03T08:30:00.000+01:00

Ja



Slutttidspunkt
(Kalenderelement)

EndTime

Antallvarighet? (brukes i utregning)

Slot

Referanse til innslaget i timebok.

type: "Slot"



Nei









identifier:system: "urn:ietf:rfc:3986"
identifier.value: "c12cc3a3-56cd-4c1d-afbe-24620f6c2a94"



TimeslotId
(Kalenderelement)

AppointmentId



patientInstruction

Beskrivelse om timen som vil vises i detaljvisningen.

"Husk å utføre forberedelsene til timen før oppmøtet."

Nei



Beskrivelse
(Kalenderelement)

Description

Beskrivelse (når en går inn på detaljer om en time)

participant.actor

Logisk ressursreferanse av type Patient. Identifikatoren er fødselsnummer/d-nummer.

actor.type: "Patient"

Ja









identifier.system: "urn:oid:2.16.578.1.12.4.1.4.1"
identifier.value: "13116900216"

Ja

Slår opp ArkivId basert på fødselsnummer/d-nummer

ArkivId
(Kalenderelement)





participant.actor

Contained ressurs av typen Practitioner.

actor.type: Practitioner



Nei









name:family "Adam"



MotpartFornavn
(Kalenderelement)

Behandler.FirstName

Behandler (en del av teksten)

name:given: "Careful"



MotpartEtternavn
(Kalenderelement)

Behandler.Lastname

Behandler (en del av teksten)

GUI

 

FHIR-profiler

 

  

 

 

 

Appointment - Profil-URL: http://ehelse.no/fhir/StructureDefinition/hn-primary-appointment
Organization (contained) - Profil-URL: http://ehelse.no/fhir/StructureDefinition/hn-primary-appointment_containedorganization
Location (contained) - Profil-URL: http://ehelse.no/fhir/StructureDefinition/hn-primary-appointment_containedlocation
Practitioner (contained) - Profil-URL: http://ehelse.no/fhir/StructureDefinition/hn-primary-appointment_containedpractitioner
Extension - Profil-URL: http://ehelse.no/fhir/StructureDefinition/hn-primary-appointment_extension-communicationoptions

Eksempel

Timenotifikasjon 

<Appointment xmlns="http://hl7.org/fhir"> <meta> <profile value="http://ehelse.no/fhir/StructureDefinition/hn-primary-appointment" /> </meta> <contained> <Location> <meta> <profile value="http://ehelse.no/fhir/StructureDefinition/hn-primary-appointment_containedlocation" /> </meta> <id value="containedLocation" /> <address> <!-- Oppmøtested --> <text value="Skiringssalveien 20, Sandefjord" /> </address> </Location> </contained> <contained> <Organization> <meta> <profile value="http://ehelse.no/fhir/StructureDefinition/hn-primary-appointment_containedorganization" /> </meta> <id value="containedOrganization"/> <identifier> <!-- Tjeneste-identifiaktor - HER-id nivå 2 = --> <system value="urn:oid:2.16.578.1.12.4.1.2" /> <value value="1494" /> </identifier> <!-- Visningsnavn tjeneste --> <name value="Allmen tannlege"/> <partOf> <type value="Organization" /> <identifier> <!-- Organisasjonsnummer --> <system value="urn:oid:2.16.578.1.12.4.1.4.101" /> <value value="948554062" /> </identifier> <!-- Visningsnavn organisasjon --> <display value="Sio Helse"/> </partOf> </Organization> </contained> <contained> <Practitioner> <meta> <profile value="http://ehelse.no/fhir/StructureDefinition/hn-primary-appointment_containedpractitioner" /> </meta> <id value="containedPractitioner"/> <name> <family value="Careful"/> <given value="Adam"/> <prefix value="Dr"/> </name> </Practitioner> </contained> <extension url="http://ehelse.no/fhir/StructureDefinition/hn-primary-appointment_extension-communicationoptions"> <extension url="Cancel"> <valueBoolean value="true" /> </extension> <extension url="CancelTimeUntil"> <valueDateTime value="2019-08-01T08:00:00+02:00" /> </extension> </extension> <identifier> <system value="http://ehelse.no/fhir/CodeSystem/no-citizenportal-instanceidentifier" /> <value value="203" /> </identifier> <identifier> <system value="http://ehelse.no/fhir/CodeSystem/no-citizenportal-sourcesystem" /> <value value="16-3fb9c0f4-1d9b-44b6-8d64-d36820115274" /> </identifier> <identifier> <system value="http://ehelse.no/fhir/CodeSystem/no-citizenportal-client" /> <value value="Opus" /> </identifier> <!-- booked/cancelled/entered-in-error --> <status value="booked" /> <serviceCategory> <coding> <system value="http://hl7.org/fhir/ValueSet/service-category" /> <code value="10" /> <display value="Dental" /> </coding> </serviceCategory> <appointmentType> <coding> <system value="urn:oid:2.16.578.1.12.4.1.1.7617" /> <code value="Ordinær" /> <display value="Ordinær time" /> </coding> </appointmentType> <!-- Timens emne/subject --> <description value="Oppfølging av kontrolltime" /> <supportingInformation> <type value="Organization" /> <reference value="#containedOrganization" /> </supportingInformation> <supportingInformation> <type value="Location" /> <reference value="#containedLocation" /> </supportingInformation> <start value="2019-08-03T08:00:00+02:00" /> <end value="2019-08-03T08:30:00+02:00" /> <!-- Timens beskrivelse --> <patientInstruction value="Husk å utføre forberedelsene til timen før oppmøtet." /> <slot> <type value="Slot" /> <identifier> <system value="urn:ietf:rfc:3986" /> <value value="c12cc3a3-56cd-4c1d-afbe-24620f6c2a94" /> </identifier> </slot> <participant> <actor> <type value="Patient" /> <identifier> <!-- FNR/d-nummer --> <system value="urn:oid:2.16.578.1.12.4.1.4.1" /> <value value="13116900216" /> </identifier> </actor> <required value="required" /> <status value="accepted" /> </participant> <participant> <actor> <type value="Practitioner" /> <reference value="#containedPractitioner" /> </actor> <required value="required" /> <status value="accepted" /> </participant> </Appointment>

Hendelser som gir varsel til innbygger

  • Ny time (inkludert ny kansellert eller entered-in-error timer)

  • Eksisterende time som har følgende felter endret siden sist overføring:

    • Tid (Start og/eller End)

    • Status

    • Timetype (appointmentType)

    • Lokasjon (Location address.text)

Respons fra helsenorge.no

Respons fra helsenorge.no skal være i henhold til FHIR standard og bruk av RESTful api beskrevet her: https://www.hl7.org/fhir/http.html

Responskode

Beskrivelse

200

OK. Oppdatert

201

OK. Opprettet

4xx

Feilkode i henhold til FHIR spesifikasjon 

Verifisering av timenotifikasjoner

Tilgang til endepunkt

For å kunne kalle endepunktet så behøves et token utstedt fra vår STS, med scope "avtaler".

  • Token mangler eller ikke er gyldig

    • lagres ikke på Helsenorge

    • HTTP 401 (unauthorized) og OperationOutcome 

      • issue.severity = fatal

      • issue.Code = forbidden

      • issue.details.text = beskrivelse av feilen

<OperationOutcome> <issue> <severity value="fatal"/> <code value="forbidden"/> <details> <text value="Not authorized to access this end point"/> </details> </issue> </OperationOutcome>

Sjekk av innhold

Ved mottak av timenotifikasjoner verifiseres det at at Appointment-objektet inneholder den påkrevde FHIR-informasjonen, timeobjektet må ha status booked, cancelled eller entered-in-error.

  • Innhold validerer ikke

    • lagres ikke på Helsenorge

    • HTTP 400 (bad request) og OperationOutcome 

      • issue.severity = fatal

      • issue.Code = structure/required/invariant (se issue type)

      • issue.details.text = beskrivelse av feilen

Structure - A structural issue in the content such as wrong namespace, unable to parse the content completely, invalid syntax, etc.

Innhold validerer ikke - structure

 

Required - A required element is missing

Invariant - A content validation rule failed - e.g. a schematron rule

 

Sjekk av kildesystem

Avsendersystem får kun lagre timenotifikasjoner som tilhører sitt kildesystem. Kildesystem er definert av Appointment.identifier-verdien no-citizenportal-client, som må matche med klientnavnet (client_name) som aktøren er registrert med i Helsenorge STS.

  • Kildesystem matcher ikke registrert systemnavn

    • lagres ikke på Helsenorge

    • HTTP 403 (forbidden) og OperationOutcome 

      • issue.severity = fatal

      • issue.Code = forbidden

      • issue.details.text = beskrivelse av feilen

Sjekk om innbygger er aktiv

Ved mottak av timenotifikasjoner må innbygger være digitalt aktiv på Helsenorge.

  • Innbygger/pasient ikke aktiv på helsenorge

    • lagres ikke på Helsenorge

    • HTTP 404 (not found) og OperationOutcome 

      • issue.severity = information

      • issue.Code = not-found

      • issue.details.text = beskrivelse av feilen

Ikke aktiv Utvid kilde

 

  • Den interne digitalt aktiv-sjekken feiler

    • lagres ikke på Helsenorge

    • HTTP 500 (internal server error) og OperationOutcome 

      • issue.severity = fatal

      • issue.Code = exception

      • issue.details.text = beskrivelse av feilen

Lagring av timenotifikasjoner

Etter at timenotifikasjonen har blitt validert så er neste steg å lagre innholdet. Timen er enten ny eller finnes fra før av.

Prosessering av nye timer

For timer som overføres første gangen (ikke er lagret på Helsenorge)

  • Hvis timestatus booked

    • innhold lagres på Helsenorge

    • Returkode HTTP 201 (created

  • Hvis timestatus cancelled eller entered-in-error

    • innhold lagres på Helsenorge

    • Returkode HTTP 200 (OK

Prosessering av allerede overførte timer

For timer som allerede er overført (er lagret på Helsenorge) som blir oppdatert

  • Sjekk om innhold er endret

    • Hvis ja, innhold lagres på Helsenorge, overskriver eksisterende

    • Hvis nei, innhold er allerede lagret på Helsenorge

  • Begge scenarioene gir returkode HTTP 200 (OK

Lagring/oppdatering feilet

Lagring og/eller oppdatering av timer har flere steg, og kan feile prosessering.

  • Lagres ikke på Helsenorge

  • HTTP 500 (internal server error) og OperationOutcome 

    • issue.severity = fatal

    • issue.Code = exception

    • issue.details.text = beskrivelse av feilen

Feiltypen (issue.Code) exception er av type transient, som betyr at man kan forsøke igjen senere.

Testing av endepunkt:

Testing av endepunktet

Testing av eksisterende endepunkt, kan gjøres på denne måten:

  1. Først må man hente AccessToken

Her vises det hvordan man kan bruke POSTMAN, lastes ned som plugin i Chrome. I POSTMAN angir man

  1. URL til testmiljø

  2. Content-Type = application/json

  3. Action type = POST

  4. Velg “raw”

  5. Client_Secret = passordet du har mottatt fra NHN

  1. Deretter bruker man tokenet i Bearer<token> i Authorization i header ved kall til Timeavtaler-tjenesten ved bruk av Swagger

https://eksternapi-hn-mas-02.int-hn.nhn.no/timeavtaler/swagger/index.html

Klikk “Authorize”:

Angi token: