Planer za sistem upućivanja: za stavke uputa (LOINC šifre lekara i/ili NLU kodovi) i lokaciju pacijenta vraća rangirane planove izvršenja u traženom periodu. Plan kaže GDE i KOG DANA se pacijent uzorkuje, GDE se koja analiza radi — u istoj ustanovi (kind=single) ili se uzorak šalje deklarisanom rutom uzorka u partnersku laboratoriju (kind=split: dan kurira, cut-off, dani transporta, datum prijema) — očekivani datum rezultata (resultEta, samo kad pravilo analize nosi TAT) i TAČNE reserve pozive koji plan izvršavaju. score 0–100 je transparentan kroz scoreBreakdown (udaljenost, čekanje, predaja uzorka, TAT, zauzeće), pa sistem upućivanja može da ga preteži. Za pretragu kandidata koristi dnevni kapacitet ustanova — puni i zatvoreni dani se preskaču. JEDAN PUNKT PRVO: svaki plan ima jedno mesto uzorkovanja, a planovi koji sa tog mesta izvršavaju CEO uput (complete=true — sve vrste uzorkovanja koje usluge traže i sve analize) uvek su rangirani iznad delimičnih; samplingPlan.verdict kaže može li uput uopšte iz jednog punkta i, ako ne, zašto.
| Parametar | Gde | Tip | Obavezan | Opis |
|---|
| services | query | string | da | Stavke uputa, razdvojene zarezom: LOINC šifre (jezik lekara, npr. 2345-7) i/ili NLU kodovi, slobodno pomešani (prihvata se i service= sa jednim kodom; loinc= je alias za čistu LOINC listu). LOINC se na ulazu prevodi u svoje NLU varijante — jedan LOINC = jedan zahtev čiji je anyOf skup varijanti („ILI“ za LIS); LOINC komponente (hemoglobin 718-7) ⇒ paneli koji je sadrže. OPERATOR „ILI“: alternative jednog zahteva razdvojite znakom | — „bilo koja od ovih mi je dovoljna“ (npr. NLU-0242,NLU-0509|NLU-0510 = NLU-0242 I (NLU-0509 ILI NLU-0510)); LOINC u grupi unosi uniju svojih varijanti; redosled je redosled želje lekara. POST: ["2345-7", "NLU-0242", ["NLU-0509","NLU-0510"]] ili [{ "anyOf": [...] }]. Nepoznat/nemapiran LOINC ⇒ translation[].reason + unknownServices, ne 400. Do 50 zahteva, do 10 alternativa po grupi. |
| patientAge | query | integer | da | SEKCIJA PACIJENT — OBAVEZNO: uzrast pacijenta u navršenim godinama (0–130, 0 = odojče; POST: patient.age). Ustanova može vrstu uzorkovanja ograničiti na uzrast za koji je osoblje obučeno (npr. samo odrasli); van tog opsega se ne nudi za usluge koje traže taj uzorak — razlog je u coverage.ageRestricted (requirement, samplingType, ageRange, label). Uzrast ide i u reserve pozive (patientAge). Bez njega 400 required. |
| patientLat | query | number | ne | SEKCIJA PACIJENT — geografska širina pacijenta (uz patientLng; POST: patient.lat; stari alias lat). Kad nije poslata, referentna tačka je upućivačka ustanova (originSource). |
| patientLng | query | number | ne | Geografska dužina pacijenta (POST: patient.lng; stari alias lng). |
| patientFilijala | query | integer | ne | RFZO id filijale kojoj pacijent pripada (1–32; POST: patient.filijala). Opcije se ograničavaju na mesta uzorkovanja u toj filijali; tek kad u njoj nema nijedne opcije nude se najbliže druge filijale sa eksplicitnom oznakom (filijalaScope=nearby, filijalaNote). Bez nje referenca je filijala upućivačke ustanove. |
| near | query | string | ne | Šifra UPUĆIVAČKE ustanove (alias referringInstitution; POST: referringInstitution) — njen lab-pult je preferirano mesto uzorkovanja, a njene koordinate referentna tačka kad pacijent nema geolokaciju. Ako je u drugoj filijali od pacijenta, uput se zaustavlja: 422 referring_institution_outside_patient_filijala. |
| from | query | string | ne | Prvi prihvatljiv datum (YYYY-MM-DD, podrazumevano danas). |
| days | query | integer | ne | Dužina perioda u danima (1–60); alternativa: to. |
| to | query | string | ne | Poslednji prihvatljiv datum (uključivo); podrazumevano from + 6. |
| priority | query | string | ne | routine (podrazumevano) | urgent = CITO uput (prihvata se i cito / hitno). CITO TOK: kapacitet nikad ne isključuje mesto uzorkovanja — popunjena kvota (dan, vrsta uzorkovanja, pravilo analize) se prijavljuje (sampling.overQuota, analysis[].overQuota) umesto da izbaci datum, a reserve pozivi se prihvataju preko kvote; danas ostaje dostupno i posle isteka termina (sampling.afterWindows — hitan uzorak se uzima van redovnih termina); rang je najraniji dan pa najbliža ustanova (score informativan). Filijala prvo važi i dalje: van filijale pacijenta samo za ono što niko u njoj ne izvodi. Ne menja sposobnost: zatvoren dan, isključena/zatvorena vrsta uzorkovanja, uzrast i ruta i dalje isključuju. |
| cito | query | boolean | ne | Zastavica CITO uputa (cito=1; POST cito: true) — isto što i priority=urgent. |
| mode | query | string | ne | any (podrazumevano) | single (sve u jednoj ustanovi) | split (uzorkovanje + slanje rutom). |
| maxKm | query | number | ne | Odbacuje mesta uzorkovanja udaljenija od ovoga od ishodišta. |
| allowPartial | query | boolean | ne | Vraća i delimične opcije (coverage.missing) — gradivne blokove sastavljenog plana (samplingPlan.recommended), nikad samostalne planove. Bez njega se vraćaju samo opcije koje su same ceo plan (complete); plan filijale (verdict, filijalaPlan) je isti u oba slučaja, a recommended koji bi se oslanjao na nevraćene opcije je prazan. |
| home | query | boolean | ne | KUĆNO UZORKOVANJE: samo ustanove koje nude kućne posete, rangirane po odvojenoj kvoti kućnih poseta i unutar deklarisanog kruga poseta; lat/lng (ili near) je adresa pacijenta. Reserve pozivi nose mode: "home". |
| limit | query | integer | ne | Maks. planova (podrazumevano 10, maks. 50). |
| sets | query | string | ne | SETOVI ANALIZA (NLS): NLS-0001 (važeća odobrena revizija) ili NLS-0001@3 (zakucana revizija — ono što izdati uput beleži), razdvojeni zarezom; ista šifra sme stajati i u services. Set se raspakuje u OBAVEZNE članove, svaki član je običan zahtev (LOINC → NLU „ILI“). POST: { "orderSet": "NLS-0001", "revision": 3, "include": ["9830-1"] | "all", "exclude": ["2571-8"] } u services ili u listi orderSets. Odgovor: orderSets[] (korišćena revizija, svaki član sa included/why, reason) i requirements[].fromOrderSets. Set ne sme biti alternativa u ILI grupi (400); nepoznat/neodobren/povučen set ⇒ unknownServices + orderSets[].reason. |
Primer poziva
curl "https://BASE_URL/api/registry/lab-options?services=NLU-0242,NLU-0509&patientAge=34&patientFilijala=9&near=ZC-VALJEVO&days=7&mode=any" \
-H "x-api-key: YOUR_API_KEY" -H "x-institution-id: YOUR_INSTITUTION_ID"
# POST sa sekcijom pacijenta (geolokacija + filijala)
curl -X POST "https://BASE_URL/api/registry/lab-options" -H "x-api-key: YOUR_API_KEY" -H "x-institution-id: YOUR_INSTITUTION_ID" -H "content-type: application/json" \
-d '{"services":["NLU-0242"],"patient":{"age":34,"lat":44.27,"lng":19.89,"filijala":9},"referringInstitution":"ZC-VALJEVO","days":7}'
# kućno uzorkovanje — adresa pacijenta, samo ustanove sa kućnim posetama
curl "https://BASE_URL/api/registry/lab-options?services=NLU-0242&patientAge=34&lat=44.2712&lng=19.8908&days=5&home=1" \
-H "x-api-key: YOUR_API_KEY" -H "x-institution-id: YOUR_INSTITUTION_ID"Primer odgovora
{
"services": [{ "id": 242, "code": "NLU-0242", "name": "Glukoza u krvi/serumu/plazmi, POCT", "category": "Biohemija" }],
"requirements": [{ "key": "NLU-0242", "kind": "service", "anyOf": ["NLU-0242"], "unknown": [] }],
"unknownServices": [],
"uncoveredServices": [],
"window": { "from": "2026-09-29", "to": "2026-10-05", "days": 7 },
"origin": { "lat": 44.3081, "lng": 20.0116 },
"nearInstitution": { "code": "ZC-VALJEVO", "name": "Zdravstveni centar Valjevo", "city": "Valjevo", "type": "laboratory", "distanceKm": 0 },
"priority": "routine",
"mode": "any",
"home": false,
"candidatesConsidered": 11,
"returned": 2,
"samplingPlan": {
"requiredTypes": [{ "code": "TU-001", "name": "Venska krv — serum/plazma", "services": ["NLU-0242"] }],
"alternativeGroups": [],
"sitesWithAllTypes": 11, "sitesCoveringAll": 9, "completeOptions": 2,
"verdict": "one_site", "blocker": null,
"recommended": [{ "rank": 1, "role": "primary", "requirements": ["NLU-0242"] }]
},
"options": [{
"rank": 1,
"kind": "split",
"complete": true,
"outsideWindow": false,
"filijalaScope": "home", "filijalaNote": null, "supplementsFor": [],
"score": 92,
"scoreBreakdown": { "base": 100, "distance": 0, "wait": 0, "handoff": -8, "turnaround": 0, "samplingCapacity": 0, "analysisCapacity": 0, "partialCoverage": 0, "secondSite": 0 },
"sampling": {
"institution": { "code": "ZC-VALJEVO", "name": "Zdravstveni centar Valjevo", "city": "Valjevo", "distanceKm": 0 },
"mode": "site", "atOrigin": true, "date": "2026-09-29", "state": "open", "free": 25,
"overQuota": false, "afterWindows": false,
"windows": [{ "label": "Jutarnje uzorkovanje", "startTime": "07:00:00", "endTime": "10:00:00" }],
"home": null
},
"analysis": [{
"institution": { "code": "ELAB-374006", "name": "Univerzitetski klinički centar Srbije", "city": "Beograd", "distanceKm": 63.5 },
"inHouse": false, "services": ["NLU-0242"],
"date": "2026-09-30", "transportDays": 1, "transportWeekdays": [1, 2, 3, 4, 5], "cutoffTime": "10:30",
"tatHours": null, "state": "open", "overQuota": false
}],
"coverage": { "covered": ["NLU-0242"], "missing": [], "leftInFilijala": [], "notSampleable": [], "alternatives": [] },
"resultEta": null,
"alternativeDates": [{ "date": "2026-09-30", "kind": "split", "complete": true }],
"reserve": [
{ "method": "POST", "path": "/api/registry/institutions/ZC-VALJEVO/capacity/reservations", "body": { "referralRef": "{referralRef}", "date": "2026-09-29", "priority": "routine", "samplings": 1, "mode": "site", "services": [] } },
{ "method": "POST", "path": "/api/registry/institutions/ELAB-374006/capacity/reservations", "body": { "referralRef": "{referralRef}", "date": "2026-09-30", "priority": "routine", "samplings": 0, "mode": "site", "services": [{ "code": "NLU-0242", "quantity": 1 }] } }
]
}],
"reserveNote": "Pozivi u reserve se izvršavaju redom sa istim referralRef; prvi rezerviše uzorkovanje, ostali analize u laboratorijama koje primaju uzorak."
}Plan je PREPORUKA — ništa se ne rezerviše dok sistem upućivanja ne izvrši reserve pozive (redom, sa istim referralRef umesto {referralRef}).
kind=single: jedan reserve poziv (uzorkovanje + analize u istoj ustanovi). kind=split: prvi poziv rezerviše uzorkovanje (services: []), sledeći analize (samplings: 0) u laboratorijama koje primaju uzorak.
Mesto uzorkovanja nikad ne dobija uslugu čiju je vrstu uzorkovanja (TU) isključilo u portalu — takve usluge stoje u coverage.notSampleable i plan ih ne pokriva.
JEDAN PUNKT PRVO: plan je complete=true kad to jedno mesto uzorkovanja uzima SVE uzorke koje uput traži (nijedna potrebna TU nije isključena, kvote po TU otvorene tog dana) i svaka analiza ima izvršioca (u kući ili rutom). Complete planovi su uvek ispred delimičnih bez obzira na score; delimičan plan dodatno nosi secondSite −20 u scoreBreakdown (pacijent mora na drugi punkt). Kad ista ustanova ima i delimične i complete datume, vodeći datum je najraniji complete.
samplingPlan (verdikt za ceo uput): one_site = uzmite opciju 1; one_site_other_window = neka ustanova može sve (sitesCoveringAll > 0), ali nijedan datum u ovom periodu ne prolazi (kvote, horizont) — proširite period pre nego što delite uput; split_referral = nijedna ustanova ne može ceo uput, blocker kaže zašto (sampling_types = niko ne uzima sve potrebne TU; analysis = ustanove koje uzimaju sve uzorke nemaju ko da uradi sve analize, ni u kući ni potvrđenom rutom; uncovered = uslugu niko ne radi) — tek tada sistem upućivanja pravi dva uputa na dva punkta, od delimičnih planova koje vraća allowPartial=1; none = nema šta da se izvrši. requiredTypes navodi TU koje uput traži i usluge iza svake.
home=1 (kućno uzorkovanje): kandidati su samo ustanove koje nude kućne posete, unutar svog kruga poseta od adrese pacijenta; sampling.mode je "home", sampling.home nosi uslove i krug, a reserve pozivi mode: "home" — troše ODVOJENU kvotu kućnih poseta, ne mesta u ustanovi.
OPERATOR „ILI“ (services=NLU-A,NLU-B|NLU-C): grupa alternativa je JEDAN zahtev koji je ispunjen bilo kojom od njih — lekaru je svejedno koja. Planer za svako mesto uzorkovanja bira alternativu koju to mesto najjednostavnije izvršava (u kući pre slanja rutom, ista vrsta uzorkovanja kao ostatak uputa pre dodatne epruvete, pa redosled lekara), a kad izabrana tog dana nema mesta (kvota analize, kvota TU) proba drugu. Zato grupa povećava šansu da se nađe ustanova koja izvršava CEO uput (complete). Rezultat: requirements (eho zahteva, kind service | any_of), coverage.alternatives po opciji ({ requirement: "NLU-B|NLU-C", anyOf, chosen } — chosen = izabrana šifra, null kad nijedna ne staje), coverage.covered i reserve pozivi nose KONKRETNU izabranu šifru; coverage.missing / notSampleable / uncoveredServices imenuju zahtev (za grupu ključ "NLU-B|NLU-C"). samplingPlan.requiredTypes važi za obične usluge, alternativeGroups navodi TU svake alternative. Grupa koja sadrži uslugu traženu i samostalno je već ispunjena i izostavlja se; nepoznate šifre u grupi stoje u unknownServices i requirements[].unknown.
LOINC NA ULAZU (jezik lekara): translation[] objašnjava svaku LOINC šifru sa uputa — canonical (posle presavijanja alijasa), nameSr, kind (service | component | unknown), anyOf (NLU varijante koje planer sme da izvrši; za komponentu paneli koji je sadrže, viaComponent), requirement (ključ zahteva koji je postala; null kad ju je pokrio zasebno tražen NLU), reason (loinc_unknown | loinc_unmapped), listed/notListedReason (šifra koju katalog lekara ne nudi, ali planer je ipak izvršava — član panela se izvršava kao panel), performedBy (broj ustanova koje planer može da ponudi za tu šifru — isti broj kao availability.institutions u katalogu; 0 znači da je katalog ne nudi, pa je odsustvo opcije praznina registra, a ne rasporeda) i related (usluge vezane preširoko — stimulacioni test, dnevni profil — koje se preko te šifre NE izvršavaju). Po opciji: options[].loincResolution[] = { loinc, component, executedAt, allowed, chosen, available } — RASPAKIVANJE LOINC šifre u ustanovi analize: executedAt je šifra laboratorije koja u tom planu izvršava šifru (sam punkt ili laboratorija na ruti), allowed su varijante koje BAŠ TA laboratorija izvodi i TO sistem uputa upisuje na uput kao allowed (allowed.length > 1 ⇒ njen LIS bira metodu i u nalazu vraća izvršeni NLU), chosen je varijanta koju plan računa, component je NLK rezultat kad je LOINC član panela (hemoglobin u KKS — na uput ide panel + komponenta), available je širi skup koji punkt uopšte može da izvrši (u kući ili rutom) — zadržan zbog starijih klijenata, NE upisuje se kao allowed.
resultEta je null kad pravilo analize ne nosi TAT; unknownServices navodi nepoznate NLU kodove, uncoveredServices kodove koje nijedna kandidat-laboratorija ne radi.
CITO TOK (priority=urgent | cito=1): hitan uput ide u NAJBLIŽU ustanovu BEZ OBZIRA NA KAPACITET. Kvota nikad ne izbacuje datum — popunjen dan / podkvota vrste uzorkovanja daje sampling.overQuota=true (free 0, state limited), popunjeno pravilo analize analysis[].overQuota=true, a reserve pozivi (priority: "urgent") se PRIHVATAJU preko kvote i vraćaju reservation.overQuota sa prekoračenjem (rutinski uput bi dobio 409 full / sampling_type_full / analysis_full). Danas ostaje mogući dan i kad su svi termini istekli — sampling.afterWindows=true znači da se hitan uzorak uzima van redovnih termina. Rang unutar filijale: najraniji dan, pa najbliža ustanova (score ostaje informativan). Pravilo filijale je isto kao za rutinski uput: prvo filijala pacijenta, van nje (home_plus_nearby / nearby) samo za ono što niko u filijali ne izvodi — samo što sada ni to „ne izvodi“ nikad ne znači „nema mesta“. Ono što ustanova ne ume se ne nudi ni za CITO: zatvoren dan, dan bez kvote, isključena ili tog dana zatvorena vrsta uzorkovanja, uzrast, nepostojeća ruta. Preporuka: from=danas, days=1–2.
FILIJALA PRVO: filijalaPlan.reference je filijala pacijenta (ili upućivačke ustanove kad pacijent nema filijalu). scope=home — sve opcije su u toj filijali; scope=home_plus_nearby — matična filijala ima opcije, ali NIJEDNO mesto u njoj ne može da izvede neku stavku (home.uncovered = ključevi zahteva koje niko u filijali ne izvršava: nema mesta uzorkovanja koje je radi u kući niti potvrđene rute do laboratorije koja je radi, a neko u Srbiji je radi) — za te stavke se DODAJU opcije iz najbližih drugih filijala (nearbyFilijale) kao gradivni blokovi za dodatni nalog uzorkovanja van matične filijale (VMF): svaka nosi filijalaScope=nearby ili unknown_filijala, filijalaNote i supplementsFor (koje stavke iz home.uncovered to mesto izvršava) i SUŽENA JE SAMO NA TE STAVKE — šta god bi to mesto još moglo da uradi ide u coverage.leftInFilijala (radi se u matičnoj filijali, nije „bez mesta“), a coverage.covered, analysis, reserve, loincResolution i sampling.samplingTypes sadrže samo VMF stavke; dopuna nikad nije complete, pa se ne može pročitati kao „sve na jednom mestu“ van filijale; opcije matične filijale uvek rangiraju ispred njih, najbolja dopuna za svaku stavku preživljava limit, a samplingPlan (verdict, completeOptions, sitesCoveringAll) i dalje opisuje matičnu filijalu (split_referral · analysis), ne dopune. SASTAVLJEN PLAN: samplingPlan.recommended = redosled naloga za uzorkovanje koje treba napraviti — { rank, role, requirements }: role=primary je opcija matične filijale koja izvršava najviše (sve što filijala može), role=vmf je po jedan nalog van filijale samo za stavke iz home.uncovered (traži odobrenje komisije); kod verdict=one_site jedan primary; prazno kad registar ne ume da sastavi podelu (nema filijale, podela po vrsti uzorkovanja). Pravilo: pacijent se nikad ne šalje van filijale za ono što filijala radi, i nijedna naručena stavka koju neko u Srbiji radi se ne ispušta. DOPUSTIVI PLANOVI su tačno: complete opcija sama, ili samplingPlan.recommended — delimična opcija (coverage.missing) je gradivni blok sastavljenog plana i NE SME se nuditi kao plan sama za sebe, ni kao „bez komisije“ alternativa: plan koji ostavlja naručenu stavku bez mesta nije plan; stavke koje niko u Srbiji ne radi su uncoveredServices — uput mora da se promeni, nijedan plan ih ne „upija“. SAT I PERIOD: današnji dan važi samo dok je bar jedan prijavljeni termin još otvoren (kraj termina > sada + 30 min po srpskom vremenu) — mesto čiji su termini danas prošli ne dobija današnji datum; mesta bez liste termina (bez šablona, prepisan kapacitet) se ne ocenjuju po satu. Dopuna sme da padne IZVAN traženog perioda: kad u matičnoj filijali niko ne radi stavku, a dopuna nema dan unutar perioda (npr. današnji termin prošao), nudi se njen prvi mogući dan do 7 dana posle `to` i opcija nosi outsideWindow=true (filijalaNote imenuje dan) — svaki nalog u recommended ima svoje mesto i svoj dan; sve ostale opcije (home, nearby bez matičnih opcija, bez filijale) ostaju unutar perioda; scope=nearby — u matičnoj filijali nema nijedne opcije u periodu, pa opcije dolaze iz najbližih filijala (nearbyFilijale, najbliža prva) i svaka nosi filijalaScope=nearby + filijalaNote; ustanove još nepovezane sa šifarnikom (filijala nepoznata) pojavljuju se samo u rezervnom nivou kao unknown_filijala; scope=none — nema opcija; scope=unfiltered — filijala nepoznata. home.sitesCoveringAll > 0 uz scope=nearby znači da bi matična filijala mogla, ali ne u ovom periodu — proširite period.
Zaustavljanje (uz filijalu pacijenta): 422 referring_institution_outside_patient_filijala kad upućivačka ustanova nije iz matične filijale pacijenta (opisna poruka navodi obe filijale); 422 referring_institution_not_linked kad upućivačka ustanova nije povezana sa nacionalnim šifarnikom (filijala se ne može proveriti); 422 unknown_referring_institution za nepostojeću šifru upućivačke ustanove; 400 unknown_patient_filijala za nepostojeću filijalu. POST sa JSON telom { services, patient: { lat, lng, filijala }, referringInstitution, days, … } je ekvivalentan GET-u.