Skip to content

feat: client.partner.* — company-kapsamlı /outher yüzeyi - #1

Merged
muhammetsafak merged 3 commits into
mainfrom
feat/partner-outher-surface
Jul 30, 2026
Merged

feat: client.partner.* — company-kapsamlı /outher yüzeyi#1
muhammetsafak merged 3 commits into
mainfrom
feat/partner-outher-surface

Conversation

@muhammetsafak

Copy link
Copy Markdown
Member

Mevcut hasta personasının yanına ikinci bir persona ekler. Tamamen eklemeli — mevcut yüzey hiç değişmedi, breaking change yok.

patient (client.*) partner (client.partner.*)
Auth hasta girişi, access token önceden verilen partner token
Veri kime ait giriş yapan hasta, tüm klinikleri yalnız senin şirketin
Hasta nasıl belirtilir örtük (oturum) inline, her istekte

Yüzey — 24 uç

partner.doctors      → search, branches, detail, locations
partner.slots        → schedule
partner.appointments → reserve, reserveWithoutAgreement, instantReserve, create,
                       createWithoutSlot, cancelWithoutSlot, list, info, checkDoctor
partner.diets        → list, detail
partner.laboratory   → catalog, catalogDetail, results, resultDetail
partner.measures     → last, list, graph, addList, add, update, delete,
                       healthInformation (@deprecated)

Transport ve partnerToken altyapısı zaten hazırdı; yalnızca tiplenmiş metotlar eklendi. Sunucu sözleşmeleri uydurulmadı — dokuz Outher FormRequest'inin rules() çıktısından türetildi.

Tasarım kararları

Okuma/yazma hasta referansı ayrıldı. Okuma için identityNumber/phoneNumber yeterli; yazma için ad/soyad/telefon zorunlu (hasta partner'ın şirketinde yoksa sunucu oluşturur). Sunucudaki okuma/yazma çözümleyici ayrımı böylece tip sisteminde de görünür.

healthInformation deprecated. Paylaşılan tüketici tenant'ına yazdığı için last/list ile geri okunamıyor. Mevcut teusan entegrasyonları için duruyor.

Ölçüm kapsamı. Partner yalnız kendi şirketinde kayıtlı ölçümleri görür; hastanın mobil uygulamaya girdiği ölçümler görünmez — kiracı izolasyonunun doğal sonucu.

Testlerin kanıtladıkları

  • Partner çağrıları her zaman partnerToken gönderiyor — token store'da dolu bir hasta token'ı varken bile
  • Hasta yüzeyi kendi token'ıyla devam ediyor
  • TCKN hiçbir URL'de geçmiyor (access log / proxy log / Sentry breadcrumb sızıntısına karşı doğrudan test)
  • Ölçüm yazma uçlarında verb+path doğru, alanlar patient ile yan yana düzleşiyor
  • Lab id'si -lab son ekiyle değişmeden gidiş-dönüş yapıyor

Doğrulama

47/47 test · ruff All checks passed · mypy Success

Sync ve async yüzeyler aynı _spec.py builder'larını çağırıyor, istek şekilleri ayrışamaz. Bir test bunu doğruluyor. mypy gerçek bir hata buldu: measures sınıflarında list metodu builtin list'i gölgeliyordu, MeasureRows takma adıyla çözüldü.

Bağımlılık

Sunucu tarafı: greenglobaltr/BulutApi#1911 — bu PR'daki uçların 14'ü orada açılıyor. Kalan 10'u (search, branches, doctorInfos, doctorSlots, randevu yaşam döngüsü, healthInformation) zaten canlıda.

Mevcut hasta personasinin yanina ikinci bir persona ekler. Tamamen eklemeli:
client.doctors, client.measures vb. hic degismedi, breaking change yok.

24 uc: doctors (search/branches/detail/locations), slots (schedule),
appointments (reserve, reserveWithoutAgreement, instantReserve, create,
createWithoutSlot, cancelWithoutSlot, list, info, checkDoctor), diets
(list/detail), laboratory (catalog, catalogDetail, results, resultDetail),
measures (last, list, graph, addList, add, update, delete,
healthInformation @deprecated).

Transport ve partnerToken altyapisi zaten hazirdi; yalnizca tiplenmis
metotlar eklendi. Partner cagrilari partnerToken kullanir, hasta erisim
tokeni degil; sessiz token yenileme bu yolda calismaz.

Okuma/yazma hasta referansi tip seviyesinde ayrildi: okuma icin
identityNumber/phoneNumber yeterli, yazma icin ad/soyad/telefon zorunlu
(hasta partner'in sirketinde yoksa sunucu olusturur).

healthInformation @deprecated: paylasilan tuketici tenant'ina yazdigi icin
last/list ile geri okunamiyor. Mevcut teusan entegrasyonlari icin duruyor.

Testler dogruluyor: partner cagrilari her zaman partnerToken gonderiyor
(store'da hasta tokeni varken bile), hasta yuzeyi etkilenmiyor, TCKN hicbir
URL'de gecmiyor, olcum yazma verb+path'leri dogru, lab id'si -lab son ekiyle
degismeden gidip geliyor.

Dogrulama: 47/47 test, ruff + mypy temiz
SDK artik tek persona sunuyor. 0.6.0'da client.partner.* altinda duran
company-kapsamli /outher yuzeyi kok seviyeye tasindi; hasta girisi gerektiren
ne varsa kaldirildi. 6 grup / 28 uc, hepsi /outher uzerinde.

Neden simdi yapilabildi: api tarafinda a2df42a53 ("Partner (/outher) yuzeyi")
hasta uclarinin company-kapsamli muadillerini acti. Kalan bosluk yok.

Yuzey
- client.partner.<grup> -> client.<grup>. Yol, govde ve davranis aynen
  korundu; bu bir yeniden adlandirma. Partner oneki siniflardan ve
  girdi tiplerinden dusuruldu.
- Kaldirilanlar: auth (11 metot), payments (5), skin, meals, addresses (4)
  ve 0.6.0'da kokte duran hasta-persona gruplari. Hicbirinin company
  kapsamli karsiligi yok; gerekcesi DESIGN.md 1.2'de.

Kimlik dogrulama
- partnerToken artik istemcinin tek kimlik bilgisi; clientId/clientSecret
  kaldirildi.
- TokenStore tek bir partner token tutuyor ve her istekte okunuyor, boylece
  uzun omurlu bir surec yeniden kurulmadan token dondurebiliyor.
- Sessiz yenileme yok. Partner token'i disaridan uretiliyor ve buradan
  yenilenemiyor: 401 / resultType 4 artik retry'siz AuthenticationError.
  Bu, resultType 4'un hasta SDK'sindaki anlaminin tam tersi, o yuzden
  sunucu mesajina ne yapilmasi gerektigi ekleniyor.
- Token yokken istek gonderilmiyor; dispatch oncesi hata veriliyor. Aksi
  halde geriye yalnizca anlamsiz bir 401 donuyordu.
- partnerToken ile tokenStore birlikte verilirse kurulum hatasi. Ikisinden
  hangisinin kastedildigini tahmin etmek kimlik bilgisi hatalarinin cikis
  noktasi.

Yapilandirma
- apiVersion secenegi eklendi (v3 varsayilan, v4). Tum yollar surumden
  bagimsiz oldugu icin v4'e gecmek kod degil yapilandirma degisikligi.

DESIGN.md spec 1.0.0'a cikarildi -- 12. bolum 0.6.x -> 1.0.0 gecis rehberi --
ve 6 depoya birebir kopyalandi. README'ler ve CHANGELOG'lar yeni yuzeye gore
yeniden yazildi; ornekler ve canli duman testi partner akisina cevrildi.

Async istemci senkronla birebir ayni yuzeyi sunuyor; iki taraf da ayni
_spec.py builder'larini cagirdigi icin istek sekilleri ayrisamaz. Bir test
bunu acikca dogruluyor.

Dogrulama: 32 test, mypy, ruff check + format.
Surum 1.0.0 (pyproject.toml, __init__.py).
Yayin oncesi 6 SDK ../api kaynagina karsi denetlendi. 28 ucun tamami v3 ve v4
route tablolarinda mevcut, dogru scope grubunda (27 apiouther + setAuthScopeInfo,
healthInformation teusan) ve gonderilen govdeler FormRequest kurallariyla
ortusuyor. Iki uyusmazlik cikti.

1) doctors.search artik searchParams'i bos haritaya dusurmuyor

Sunucu kurali `required|array`; PHP'nin `required` kurali BOS diziyi reddediyor
(Illuminate ValidatesAttributes::validateRequired -> count($value) < 1). JSON
`{}` PHP tarafinda `[]` olarak cozuldugu icin, searchParams verilmediginde
gonderilen istek filtresiz arama degil garantili 422'ydi.

JS'de `input.searchParams ?? {}` varsayilani kaldirildi ve DoctorSearchInput.
searchParams zorunlu yapildi -- degisiklik bu cagriyi yapan bir testi hemen
yakaladi. Diger 5 SDK'da parametre zaten zorunluydu; hepsine en az bir anahtar
gerektigi belgelendi.

2) healthInformation notu duzeltildi

DESIGN.md ve 6 README, `identity` alaninin dogrulama sirasinda null'landigi bir
API hatasini anlatiyordu. O hata 2026-07-21'de api tarafinda duzeltilmis
(65b15f39c); not artik yanlisti.

Gercekte kalan durum daha gevsek ve bilinmeye deger: eslesme
PatientUsersModel::patientUserFindWithOr uzerinden `identity OR phone_number`
seklinde GLOBAL kullanici tablosunda yapiliyor ve ilk satir aliniyor. Yani tek
basina telefon, gonderilen TCKN'den farkli birini cozebilir. Ayni gruptaki
apiouther okumalari bunun tam tersi: kendi sirketine kapali ve belirsizlikte
hata veriyor. Not buna gore yeniden yazildi.

Tel uzerinde baska degisiklik yok; 28 ucun method/path/govdesi aynen duruyor.
Uc bagimsiz HTTP yigini (js fetch, python httpx, go net/http) calisma aninda
28 cagrinin tamaminda birebir ayni govdeyi uretiyor.
@muhammetsafak
muhammetsafak merged commit efcbc6e into main Jul 30, 2026
0 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant