Tərtibatçılar · Connect v1

Connect v1 müqaviləsi

Partnyorlar üçün CoSuite Connect v1 müqaviləsi: sorğu imzası, xəta zərfi, tenant, entitlement, üzv, istifadə və müştəri endpoint-ləri, SSO, versiyalama.

Bu səhifə CoSuite ilə sənin tətbiqin arasındakı tam serverdən-serverə müqavilədir. Müqavilə identifikatoru: cosuite-connect/1.0, cari paket versiyası 1.7. Məqsəd bir cümlədə: tətbiqin daxildə istədiyi qədər dəyişə bilər; bu müqaviləyə əməl etdikcə heç bir tərəfdə heç nə pozulmur.

Prinsiplər

  1. Tətbiqin müstəqil məhsuldur. Öz verilənlər bazasını, istifadəçilərini və interfeysini saxlayır. CoSuite heç vaxt onun içinə müdaxilə etmir; yalnız bu səhifədəki endpoint-ləri çağırır.

  2. Nə kimə aiddir:

    Mövzu Sahibi
    Biznesin (tenant) kimliyi, modul alışları, qiymətlər, fakturalar CoSuite
    Entitlement-lər: hansı modul aktivdir, limitlər, bitmə tarixi CoSuite (tətbiqin onlara riayət edir)
    Tətbiqinin öz məlumatları (xəstələr, rezervasiyalar, fayllar…) Sənin tətbiqin
    İstifadəçinin tətbiqindəki sessiyası Sənin tətbiqin (CoSuite yalnız kimliyi təsdiqləyir)
  3. Ayrı ad sahəsi. Bütün müqavilə endpoint-ləri əsas URL-ində /api/cosuite/v1/* altında yerləşir. Mövcud açıq API-nə toxunulmur.

  4. v1 daxilində yalnız əlavələr. Sahələr, endpoint-lər və enum dəyərləri heç vaxt silinmir, adı dəyişdirilmir və yeni məna almır (bax: versiyalama).

  5. Tanımadığını nəzərə alma. Hər iki tərəf naməlum JSON sahələrini, modul açarlarını və hadisə növlərini səssizcə nəzərə almır. Əlavələri təhlükəsiz edən də budur.

  6. Sənin nasazlığın CoSuite-i dayandırmır. CoSuite-in etdiyi hər çağırışın vaxt limiti, təkrar cəhdləri və növbəsi var (bax: etibarlılıq).

İdentifikatorlar

Termin Mənası
tətbiq açarı Tətbiqinin açarı, kiçik hərflərlə, 2–24 simvol (^[a-z][a-z0-9]{1,23}$), məsələn, dent. Manifestin asist sahəsində və SSO auditoriyası kimi görünür. Heç vaxt dəyişmir.
tenantId Biznesin CoSuite-dəki identifikatoru. Qeyri-şəffaf sətir, 64 simvola qədər ([A-Za-z0-9_.:-]). Formatına güvənmə.
localTenantId Eyni biznes üçün sənin identifikatorun (təşkilat, iş sahəsi, klinika…). Qeyri-şəffafdır, sən yaradırsan.
userId CoSuite istifadəçi identifikatoru. Qeyri-şəffaf, 64 simvola qədər.
module <appKey>.<module> formasında modul açarı, məsələn, dent.treatment. core.* CoSuite üçün ayrılıb.

tenantId ↔ localTenantId uyğunluğunu öz cədvəlində saxla (tövsiyə olunan ad: cosuite_links). Bir tenantId yalnız bir dəfə bağlana bilər.

Ötürmə və imzalama

Bütün serverdən-serverə çağırışlar HTTPS və JSON (application/json; charset=utf-8), UTF-8 mətn və ISO 8601 UTC zaman möhürlərindən (2026-10-26T09:00:00Z) istifadə edir.

Etimadnamələr

CoSuite hər tətbiq və mühit üçün bir açar cütü verir: keyId (məsələn, csk_dent_test) və 32 baytlıq təsadüfi secret. Hər iki tərəf gizli açarı şifrələnmiş saxlayır və heç vaxt loglara yazmır. Eyni gizli açar çağırışları hər iki istiqamətdə imzalayır (CoSuite → tətbiqin və tətbiqin → CoSuite).

İmza

Hər sorğu dörd başlıq daşıyır:

Başlıq Dəyər
X-CoSuite-Key keyId
X-CoSuite-Timestamp Saniyələrlə Unix vaxtı
X-CoSuite-Request-Id Hər sorğu üçün unikal (UUID; [A-Za-z0-9_-] simvollarından 8–128 simvol). Sorğu təkrar göndəriləndə eyni qalır.
X-CoSuite-Signature v1= + hex(HMAC-SHA256(secret, kanonik sətir))

Kanonik sətir | ilə birləşdirilmiş dörd hissədən ibarətdir:

{METHOD}|{pathAndQuery}|{timestamp}|{hex(sha256(body))}
  • METHOD böyük hərflərlə (PUT).
  • pathAndQuery sorğu sətrində olduğu kimi, host olmadan: /api/cosuite/v1/tenants/abc/entitlements?x=1. Reverse proxy yolu yenidən yazırsa, klientin göndərdiyi xam yoldan istifadə et.
  • Boş gövdə üçün boş sətrin SHA-256 dəyərindən istifadə et (e3b0c442…b855).
  • Alındığı kimi xam gövdə baytlarını hash-lə; JSON-u yalnız yoxlamadan sonra parse et.

Yoxlayan tərəf:

  1. Öz saatından ±300 saniyədən çox fərqlənən zaman möhürünü 401 signature_expired ilə rədd edir.
  2. İmzanı sabit vaxtda müqayisə edir; uyğunsuzluqda 401 invalid_signature. Naməlum keyId 401 unknown_key olur.
  3. Yazma sorğularında X-CoSuite-Request-Id dəyərini 10 dəqiqə yadda saxlayır: eyni id fərqli gövdə ilə gəlsə 409 request_id_reused; eyni id eyni gövdə ilə gəlsə ilk cavab yenidən qaytarılır.

256 KB-a qədər sorğu gövdələrini qəbul et. Test vektorları və Node, .NET, PHP və Python üçün hazır funksiyalar SDK səhifəsindədir.

Açar rotasiyası

Rotasiya zamanı eyni keyId üçün iki gizli açar etibarlı ola bilər. Yoxlayan tərəf hər ikisini sınayır. Köhnə gizli açar ən gec 7 gün sonra silinir.

Cavablar və xətalar

Uğur:

{ "ok": true, "data": { } }

Xəta:

{ "ok": false, "error": { "code": "tenant_not_found", "message": "…", "retryable": false }, "requestId": "…" }
  • code sabitdir və maşınlar üçündür; message insanlar üçündür (ingiliscə kifayətdir).
  • retryable true olduqda CoSuite eyni X-CoSuite-Request-Id ilə təkrar cəhd edir.
  • Müqavilə endpoint-lərində server xətaları üçün 5xx qaytar, heç vaxt 4xx yox: CoSuite təkrar cəhd edib-etməyəcəyinə statusa görə qərar verir.
HTTP code Təkrar?
400 invalid_request (+ details: sahə xətaları) yox
401 invalid_signature, signature_expired, unknown_key yox
403 subscription_suspended yox
404 tenant_not_found, member_not_found, not_found yox
409 tenant_already_linked, member_conflict, stale_version, request_id_reused, invalid_link_code yox
413 payload_too_large yox
422 unsupported_module, limit_unsupported, capability_unsupported yox
429 rate_limited (+ Retry-After başlığı) bəli
500/502/503 internal, unavailable bəli

Tətbiqinin təqdim etdiyi endpoint-lər

Hamısı {baseUrl}/api/cosuite/v1 altındadır və hamısı, o cümlədən /health, imza ilə qorunur.

Metod Yol Məqsəd
GET /manifest Tətbiqini və modullarını təsvir edir
GET /health İşləkliyin yoxlanması
POST /tenants Biznes açır və ya bağlayır
GET /tenants/{tenantId} Bağlantı vəziyyəti
PATCH /tenants/{tenantId} Ad, dil, valyuta, saat qurşağı və ya ölkə dəyişib
DELETE /tenants/{tenantId} Bağlantını bağlayır (məlumatların silinməsi planlaşdırılır)
PUT /tenants/{tenantId}/entitlements Entitlement-i yazır (tam sənəd)
GET /tenants/{tenantId}/entitlements Tətbiq etdiyin son entitlement
PUT /tenants/{tenantId}/members/{userId} Üzv əlavə edir və ya yeniləyir
DELETE /tenants/{tenantId}/members/{userId} Üzvü çıxarır
GET /tenants/{tenantId}/members Bağlı üzvlər
GET /tenants/{tenantId}/usage?period=YYYY-MM İstifadə göstəriciləri
GET /tenants/{tenantId}/summary CoSuite idarə paneli üçün qısa kartlar
GET /tenants/{tenantId}/customers?cursor=&limit= Müştərilər, səhifələnmiş (customers imkanı)
GET/POST /sso Brauzerdə giriş (imza yox, token; bax: SSO)

Yol parametrləri URL-kodlaşdırılmış olur; istifadə etməzdən əvvəl onları dekodlaşdır.

GET /manifest

{
  "contract": "cosuite-connect/1.0",
  "asist": "dent",
  "name": "DentCloud",
  "version": "2026.11.1",
  "baseUrl": "https://app.dentcloud.example",
  "locales": ["en", "tr", "az"],
  "modules": [
    {
      "key": "dent.treatment",
      "name": { "en": "Patients and treatment plans", "tr": "Hasta ve tedavi planı", "az": "Xəstə və müalicə planı" },
      "limits": [
        { "key": "chairs", "unit": "count", "name": { "en": "Chairs", "tr": "Koltuk", "az": "Kreslo" } },
        { "key": "smsPerMonth", "unit": "count_per_month" }
      ],
      "usage": ["smsSent", "storageBytes"]
    }
  ],
  "capabilities": ["sso", "members", "usage", "summary"]
}
  • asist sənin tətbiq açarındır; baseUrl müqavilə endpoint-lərinin yerləşdiyi kökdür.
  • CoSuite kataloqunu manifestə qarşı yoxlayır: manifestində olmayan modul satıla bilməz.
  • CoSuite imkanı capabilities siyahısında olmayan endpoint-i heç vaxt çağırmır (sso, members, usage, summary, customers, link). Məsələn, members olmayan tətbiq heç vaxt üzv çağırışları almır.
  • Modullar özlərini daha ətraflı təsvir edə bilər (funksiyalar, API, webhook-lar, bazarlar). Bax: modul tərifi.

GET /health

{ "ok": true, "data": { "status": "ok", "version": "2026.11.1" } }

status ok və ya degraded olur. Tez cavab ver; CoSuite 3 saniyəlik vaxt limitindən istifadə edir.

POST /tenants: açma və ya bağlama

Sorğu:

{
  "tenantId": "org_8f2c",
  "name": "Smile Dental Clinic",
  "locale": "en",
  "currency": "USD",
  "timeZone": "Europe/Istanbul",
  "country": "TR",
  "owner": { "userId": "usr_1a", "email": "owner@smile.example", "name": "Deniz Kaya", "locale": "en" },
  "link": null,
  "test": false
}
  • İdempotentdir: eyni tenantId üçün yenidən çağırış eyni localTenantId ilə 200 qaytarır; yeni hesab yaradılmır.
  • Biznesin tətbiqində artıq hesabı varsa, link doldurulur: { "code": "<one-time link code>" }. Bax: mövcud hesabın bağlanması.
  • test: true olan tenant-lar uyğunluq testindən və sandbox-dan gəlir. Onlara ödəniş yazma, hesabatlarından kənarda saxla və DELETE gələndə dərhal sil.

Cavab 201 (yeni) və ya 200 (artıq bağlıdır):

{ "ok": true, "data": { "localTenantId": "b7c1", "status": "linked", "created": true } }

GET /tenants/{tenantId} eyni formanı qaytarır (status linked və ya deleting olur, istəyə görə entitlementVersion ilə). PATCH /tenants/{tenantId} name, locale, currency, timeZone, country sahələrindən istənilənini daşıyır və eyni formanı qaytarır. Naməlum tenantId 404 tenant_not_found olur.

Biznes tətbiqindən artıq öz abunəsi ilə istifadə edirsə, CoSuite-ə keçid yeni boş hesab yaratmamalıdır; mövcud hesab bağlanır.

  1. Tətbiqində hesab sahibi və ya admin "CoSuite-ə qoş" düyməsinə basır. Sən yalnız həmin hesaba bağlı, ən çoxu 30 dəqiqə etibarlı birdəfəlik kod yaradıb göstərirsən (tövsiyə olunan format LNK-XXXXXXXXXXXX, 8–200 simvol).
  2. İstifadəçi kodu CoSuite-də daxil edir (Abunə › "Mövcud hesabını bağla"). CoSuite modulu abunəyə əlavə edir və link: { code } ilə POST /tenants göndərir.
  3. Sən kodu yoxlayırsan (mövcuddur, vaxtı keçməyib, istifadə olunmayıb), yenisini yaratmadan mövcud hesabı bu tenantId-yə bağlayırsan, kodu istifadə olunmuş sayırsan və 200 { localTenantId, status: "linked", created: false } qaytarırsan. Etibarsız və ya vaxtı keçmiş kod 409 invalid_link_code olur və heç bir hesab yaradılmır; CoSuite istifadəçiyə bildirir və yeni kodla yenidən cəhd edir.
  4. Bağlandıqdan sonra:
    • Hesabın məlumatları və mövcud üzvləri olduğu kimi qalır; CoSuite üzvləri üzv endpoint-ləri vasitəsilə əlavə edilir.
    • billing.managedBy = "cosuite" olan entitlement gələn kimi ödəniş CoSuite-ə keçir: öz təkrarlanan ödənişini dayandır, növbəti dövr üçün ödəniş alma və ödəniş ekranlarını gizlət. Artıq ödənilmiş dövr üçün geri qaytarmalar sənin və CoSuite arasında həll olunur.
    • Entitlement-dəki limit cari istifadədən aşağıdırsa, məlumatları silmə; artıq hissə yalnız oxunan olur.

link elan etməyən tətbiqlər "Mövcud hesabını bağla" seçimini heç vaxt görmür. Buna baxmayaraq, hər tətbiq naməlum kodu 409 invalid_link_code ilə rədd etməlidir; uyğunluq testi bunu yoxlayır. tenant.linked_by_user hadisəsi istəyə bağlıdır və yalnız məlumat xarakteri daşıyır.

PUT /tenants/{tenantId}/entitlements

CoSuite həmişə tam sənədi göndərir, heç vaxt fərqi yox:

{
  "version": 42,
  "status": "active",
  "validUntil": "2026-11-26T00:00:00Z",
  "graceUntil": "2026-12-03T00:00:00Z",
  "modules": [
    { "key": "dent.treatment", "limits": { "chairs": 4, "smsPerMonth": 500 } },
    { "key": "dent.imaging" }
  ],
  "billing": { "managedBy": "cosuite" },
  "issuedAt": "2026-10-26T09:00:00Z"
}

Qaydalar:

  • version yalnız artır. Gələn versiya tətbiq etdiyindən kiçik və ya ona bərabərdirsə, onu tətbiq etmə, amma yenə də applied: false ilə 200 qaytar. Bu, gecikmiş, təkrarlanan və ya sırası pozulmuş çağırışları zərərsiz edir.

  • modules siyahısında olmayan modul söndürülüb.

  • Verilməyən limit üçün həmin modulda sənin standart dəyərin işləyir.

  • Naməlum modul açarlarını nəzərə alma və cavabda ignored siyahısında göstər.

  • status və tətbiqinin davranışı:

    status Sənin tətbiqin
    trial, active Normal işləyir
    past_due Normal işləyir, "ödəniş gözlənilir" bildirişi göstərir
    suspended Yalnız oxumaq: məlumatlar görünür, yazmalar 403 subscription_suspended qaytarır
    canceled Giriş bağlıdır; məlumatlar DELETE gələnə qədər saxlanılır
  • billing.managedBy "cosuite" olduqda bu biznesə öz ödəniş ekranlarını, paket yüksəltmə düymələrini və ya sınaq sayğaclarını göstərmə. Bu, ikiqat ödənişin qarşısını alır. Daxili plan sahələrini bu sənəddən çıxar.

Cavab:

{ "ok": true, "data": { "applied": true, "version": 42, "ignored": [] } }

GET /tenants/{tenantId}/entitlements tətbiq etdiyin son sənədi (və ya null) qaytarır. CoSuite bundan gecəlik tutuşdurma üçün istifadə edir.

Üzvlər

PUT /tenants/{tenantId}/members/{userId}:

{ "email": "ayse@smile.example", "name": "Ayşe Demir", "locale": "tr", "role": "admin" }
  • role owner, admin, member, viewer dəyərlərindən biridir. Onu öz rol modelinə uyğunlaşdır.
  • Bir şəxs bir biznesdə işləyir. Tətbiqin bir e-poçtu yalnız bir hesabda qəbul edirsə və bu e-poçt artıq başqa hesaba aiddirsə, 409 member_conflict qaytar; heç vaxt hesabları öz başına köçürmə. CoSuite üzvü "qoşula bilmədi" kimi işarələyir və adminə göstərir.
  • İnsanlar heç vaxt silinmir, yalnız biznesdən çıxarılır (DELETE). Onların tətbiqindəki sessiyalarını bağla. Naməlum üzv 404 member_not_found olur.
  • GET /tenants/{tenantId}/members { "members": [ { "userId", "email", "name", "locale", "role", "localUserId"? } ] } qaytarır.

GET /tenants/{tenantId}/usage

{ "ok": true, "data": { "period": "2026-10", "metrics": { "smsSent": 212, "storageBytes": 734003200 }, "asOf": "2026-10-26T08:00:00Z" } }

Göstərici açarları manifestindəki modulun usage siyahısından gəlir. Ay bağlandıqdan sonra onun dəyərləri dəyişməməlidir. Etibarsız period 400 invalid_request olur.

GET /tenants/{tenantId}/summary

Biznesin CoSuite ana səhifəsi üçün kartlar. Dil Accept-Language başlığından götürülür.

{ "ok": true, "data": { "cards": [
  { "key": "today", "title": "Appointments today", "value": "18", "trend": null, "url": "https://app.dentcloud.example/calendar" }
] } }
  • Ən çoxu 6 kart.
  • Cavab 1 saniyə ərzində gəlməsə, CoSuite kartları ötürür. Onları keşdən ver, burada heç vaxt ağır sorğular işlətmə.

Müştərilər (customers imkanı)

Müştərilərin CoSuite-in müştəri siyahısında tətbiqinin nişanı, mənbə filtri və tətbiqindəki qeydə keçid ilə görünür. İstiqamət tətbiqin → CoSuite-dir: qeyd sənə aiddir və tətbiqində redaktə olunur; CoSuite bu sahələri kilidli göstərir. CoSuite-də yaradılan müştərilər sənə göndərilmir.

1. Səhifələnmiş siyahı: GET /tenants/{tenantId}/customers?limit=200&cursor=…

{ "ok": true, "data": {
  "customers": [
    { "id": "cus_8x2", "kind": "person", "name": "Ayşe Demir", "email": "ayse@example.com", "phone": "+905321234567",
      "taxNumber": null, "city": "Istanbul", "country": "TR", "url": "https://app.dentcloud.example/patients/cus_8x2",
      "updatedAt": "2026-10-26T09:12:00Z" }
  ],
  "nextCursor": "eyJ1IjoiMjAyNi0xMC0yNlQwOToxMjowMFoiLCJpIjoiY3VzXzh4MiJ9"
} }
  • limit 1–200 arasındadır (standart 200); bu aralıqdan kənar dəyərdə və ya dekodlaşdıra bilmədiyin cursor-da 400 invalid_request qaytar.
  • Sıra sabit olmalıdır (tövsiyə: updatedAt, id artan sırada, cursor hər ikisini daşıyır). Son səhifədə nextCursor: null olur.
  • Silinmiş müştərilər siyahıya düşmür.
  • CoSuite bunu bağlantı yaradılanda (ilkin idxal) və hər gecə (uyğunsuzluq yoxlaması) çağırır.

2. Hadisələr, müştəri yaradılanda, dəyişdiriləndə və ya silinəndə outbox-undan (bax: hadisələr):

{ "id": "evt_01", "type": "customer.upserted", "tenantId": "org_8f2c", "occurredAt": "2026-10-26T09:12:00Z", "data": { "customer": { } } }
{ "id": "evt_02", "type": "customer.deleted", "tenantId": "org_8f2c", "occurredAt": "2026-10-26T09:30:00Z", "data": { "customerId": "cus_8x2", "deletedAt": "2026-10-26T09:30:00Z" } }

data.customer siyahı elementi ilə tam eyni formadadır.

Sahə Qayda
id Sənin öz identifikatorun, heç vaxt dəyişmir (1–64, [A-Za-z0-9_.:-])
kind person və ya company; naməlum dəyərlər person sayılır
name Məcburidir, 1–200 simvol
email, phone, taxNumber, city, country, url İstəyə bağlıdır. phone E.164 formatında (+905…), country ISO 3166 iki hərfli kod, url sənin baseUrl altında. Etibarsız dəyər qeydin itməsinə səbəb olmur; boş sayılır.
updatedAt Məcburidir. CoSuite əlindəkindən köhnə yeniləmələri nəzərə almır, ona görə də sırası pozulmuş hadisələr təhlükəsizdir.

CoSuite-də eyni biznesdə eyni e-poçt və ya telefonu olan müştəri təkrarlanmır, mövcud qeydlə uyğunlaşdırılır. Tətbiqində silinən müştəri CoSuite-də silinmir; yalnız bağlantı qaldırılır (onun fakturaları ola bilər).

DELETE /tenants/{tenantId}

  • Bağlantı bağlanır və giriş dayanır.
  • Məlumatları 30 gün saxla, sonra sil. CoSuite bunu dəyişmək üçün gövdədə { "retentionDays": 0–90 } göndərə bilər. Bu müddət ərzində eyni tenantId üçün POST /tenants gəlsə, hesabı yenidən aç.
  • test: true tenant-lar dərhal silinir.
  • Cavab: 200 { "deleted": true }. Məlumatlar nəhayət silinəndə tenant.data_deleted hadisəsini göndər.

Kodla bağlanmış hesablar (created: false, bax: bağlama) silinmir, ayrılır:

  • Bağlantı və CoSuite üzv uyğunluqları qaldırılır; hesab, onun məlumatları və istifadəçiləri tətbiqində qalır, giriş də açıq qalır.
  • Ödəniş sənə qayıdır (managedBy: "cosuite" təsiri bitir); plan sənin öz qaydalarına tabe olur.
  • retentionDays nəzərə alınmır və tenant.data_deleted göndərilmir.
  • Cavab: 200 { "deleted": false, "detached": true }. CoSuite bağlantını dərhal bağlayır.
  • Eyni tenantId-ni yenidən bağlamaq üçün yeni bağlama kodu lazımdır; kodsuz POST /tenants yeni hesab açır.
  • Bağlanmış hesab, sorğuda test: true yazılsa belə, heç vaxt test hesabı sayılmır.

CoSuite-in təqdim etdiyi endpoint-lər

Əsas URL https://api.cosuite.io/connect/v1. Eyni imza, öz keyId açarınla imzalanır.

Metod Yol Məqsəd
GET /tenants/{tenantId}/entitlements Şübhə olduqda ən son entitlement-i götürür
POST /events CoSuite-ə hadisə göndərir
GET /jwks.json SSO tokenlərini yoxlamaq üçün açıq açarlar (açıq, imzasız)

POST /events

{ "id": "evt_01J9", "type": "usage.threshold_reached", "tenantId": "org_8f2c", "occurredAt": "2026-10-26T09:00:00Z", "data": { "metric": "smsPerMonth", "percent": 80 } }
Hadisə Nə vaxt
tenant.linked_by_user İstifadəçi tətbiqində "CoSuite-ə qoş" düyməsinə basıb (data.linkCode)
usage.threshold_reached Limitin 80%-i və ya 100%-i istifadə olunub
member.left Üzv tətbiqindəki öz hesabını silib
tenant.data_deleted Saxlama müddəti bitib və məlumatlar silinib
customer.upserted Müştəri yaradılıb və ya dəyişdirilib (data.customer; customers imkanı)
customer.deleted Müştəri silinib (data.customerId, data.deletedAt)
  • Hadisələri outbox vasitəsilə göndər: əvvəlcə hadisəni verilənlər bazana yaz, sonra çatdır. Artan intervallarla təkrar cəhd et; 24 saat ərzində çatdırıla bilməsə, onu ölü kimi işarələ.
  • Hadisənin id dəyərini X-CoSuite-Request-Id kimi istifadə et. CoSuite təkrarları id üzrə aradan qaldırır, ona görə də iki dəfə çatdırmaq zərərsizdir.

Vahid giriş (SSO)

İstifadəçi CoSuite-də tətbiqin üçün "Aç" düyməsinə basanda:

  1. CoSuite qısa ömürlü JWT buraxır və brauzer onu avtomatik göndərilən forma ilə POST {baseUrl}/api/cosuite/v1/sso ünvanına göndərir. Token heç vaxt ünvan sətrində və ya loglarda görünmür.

  2. Token ES256 (asimmetrik) ilə imzalanıb. Onu CoSuite-in https://api.cosuite.io/connect/v1/jwks.json ünvanındakı açıq açarları ilə yoxla. Açarları ən azı bir saat keşdə saxla; naməlum kid gəldikdə dəqiqədə ən çoxu bir dəfə yenidən yüklə. Ortaq gizli açar olmadığı üçün heç bir tətbiq başqa tətbiq üçün giriş tokeni yarada bilməz.

  3. Tokenin claim-ləri:

    { "iss": "https://cosuite.io", "aud": "dent", "sub": "usr_1a", "tid": "org_8f2c",
      "email": "owner@smile.example", "name": "Deniz Kaya", "locale": "en", "role": "owner",
      "redirect": "/calendar", "iat": 1761469200, "exp": 1761469260, "jti": "4f1c…" }
    
  4. Bunları yoxla:

    • imza etibarlıdır və alqoritm ES256-dır;
    • iss https://cosuite.io, aud isə sənin tətbiq açarındır;
    • exp keçməyib (ömür ən çoxu 60 saniyə, exp - iat ≤ 60; ±30 saniyə saat fərqinə icazə ver);
    • jti əvvəl istifadə olunmayıb (birdəfəlik; 2 dəqiqə yadda saxla);
    • tid bağlı tenant-dır.
  5. Üzv hələ mövcud deyilsə, amma tenant bağlıdırsa, üzvü yerindəcə yarat (üzvlər ilə eyni qaydalar). Sonra öz sessiyanı başlat və redirect ünvanına yönləndir. redirect yalnız öz domenindəki yol ola bilər: / ilə başlayır, // və ya /\ ilə başlamır.

    • Sessiyanı öz giriş səhifən vasitəsilə də qura bilərsən (məsələn, birdəfəlik bilet və öz kimlik provayderin). Bu halda ilk yönləndirmə redirect yolunu daşıyır, giriş səhifəsi isə sessiya qurulduqdan sonra oraya keçir. Bileti URL fraqmentində (#…) daşı ki, heç vaxt server loglarına düşməsin.
  6. İstənilən xətada CoSuite-ə geri keçidi olan öz giriş səhifəni göstər. Xam xətanı heç vaxt istifadəçiyə göstərmə.

Dil, valyuta, vaxt

  • Dillər en, tr, az kimi kodlardır. Bir dili dəstəkləmirsənsə, dəstəklədiyin ən yaxın dilə keç; heç vaxt xəta vermə.
  • Valyuta (USD, TRY, EUR, AZN…) məlumat xarakterlidir. Qiymətləndirmə və ödənişin yığılması CoSuite-ə aiddir; CoSuite vasitəsilə qoşulmuş biznesə qiymət göstərmə.
  • Saat qurşaqları IANA adlarıdır (Europe/Istanbul, Asia/Baku).

Etibarlılıq (CoSuite-in vədi)

  • CoSuite-in tətbiqinə çağırışları 10 saniyədən sonra vaxt limitinə düşür; summary 1 saniyədən, health 3 saniyədən sonra.
  • Yazma çağırışları (tenants, entitlements, members) CoSuite-in outbox-undan göndərilir. Tətbiqin işləmirsə, satış və ödəniş yenə də tamamlanır; çağırış eyni request id ilə 1 dəq, 5 dəq, 30 dəq, 2 saat və 6 saat sonra təkrarlanır.
  • Ardıcıl 5 uğursuzluqdan sonra CoSuite tətbiqini 2 dəqiqəliyə çağırmağı dayandırır (circuit breaker), sonra tək bir yoxlama sorğusu göndərir.
  • Gecəlik tutuşdurma: hər gecə CoSuite hər bağlı tenant üçün GET …/entitlements oxuyur və sənin version dəyərin geridə qalıbsa, cari sənədi yenidən göndərir.

Versiyalama: "bizi pozma" siyahısı

v1 daxilində icazə verilir:

  • Endpoint əlavə etmək (və onun imkanını manifestə).
  • Cavaba sahə əlavə etmək.
  • Sorğuya istəyə bağlı sahə əlavə etmək.
  • Modul, limit, istifadə göstəricisi, hadisə növü və ya xəta kodu əlavə etmək.

Diqqət: CoSuite-in sənə göndərdiyi sabit siyahılar (status, role, billing.managedBy) v1 daxilində genişləndirilmir, çünki köhnə tətbiq yeni dəyəri tanımaz.

v1 daxilində icazə verilmir:

  • Sahəni, endpoint-i, enum dəyərini və ya xəta kodunu silmək və ya adını dəyişmək.
  • Sahənin tipini və ya mənasını dəyişmək (məsələn, aylıq limiti gündəliyə çevirmək).
  • İstəyə bağlı sahəni məcburi etmək.
  • Uğurlu cavabın HTTP statusunu dəyişmək.
  • Autentifikasiyanı və ya imza formatını dəyişmək.
  • Modul açarının adını dəyişmək. Bunun əvəzinə yeni açar əlavə et; köhnəsi ən azı 6 ay yaşayır.

Nə vaxtsa pozucu dəyişiklik lazım olarsa, v1-in yanında /api/cosuite/v2 açılır; v1 söndürülmür. v1-in bağlanma tarixi ən azı 6 ay əvvəlcədən manifestdəki deprecated sahəsi ({ "sunset": "<ISO date>", "message": "…" }) və Deprecation cavab başlığı ilə elan olunur.

Eyni qaydalar sənə də aiddir: modulun canlıya çıxdıqdan sonra onun açarlarını, limitlərini, scope-larını və webhook növlərini daimi say. CoSuite öz tərəfini SDK-dakı avtomatik müqavilə yoxlaması ilə qoruyur; sənin tərəfin isə uyğunluq testi ilə yoxlanılır.