API معاہدہ
سندھ آئی ٹی پورٹل — سہولت ڈیسک (SITP) کے مستند REST API معاہدے کی دستاویز: بیس URL، ورژننگ، تصدیق و اجازت، ریٹ لمٹنگ، پیجینیشن، لفافہ، نقائص، idempotency، OpenAPI 3.1 خاکہ، مکمل وسائل کی فہرست، باہر نکالنے والے ویب ہوک کا معاہدہ، SDK/codegen منصوبہ، deprecation، سینڈ باکس، اور مشاہدہ پذیری۔
| فیلڈ | قدر |
|---|---|
| دستاویز آئی ڈی | 12 |
| حیثیت | مسودہ |
| مالک | S&ITD / MAAHIR |
| زبانیں | EN (مرجع) · UR · SD |
| API انداز | REST (NestJS)، JSON، OpenAPI 3.1 |
| بیس URL | https://sindhitportal.maahir.io/api/v1 |
| متعلقہ دستاویزات | /specs/ur/08-integrations-spec/ · /specs/ur/05-data-model/ · /specs/ur/04-roles-permissions/ · /specs/ur/11-security-compliance/ · 03-non-functional-requirements/en.md · /specs/ur/15-tech-architecture/ |
1. دائرہ کار اور اس دستاویز کو پڑھنے کا طریقہ
یہ دستاویز SITP کے عوامی REST API کا انجینئرنگ معاہدہ ہے۔ اسے درج ذیل استعمال کرتے ہیں:
- پارٹنر ڈویلپرز — دیگر حکومتی پورٹلز، انضمام کے پارٹنرز، اور بڑی کمپنی ٹیننٹس جو پروگرامی سطح پر ٹکٹ درج کرتے اور ان کی پیروی کرتے ہیں۔
- اندرونی فرنٹ اینڈ/موبائل ٹیمیں — Next.js پورٹل اور مستقبل کا React Native ایپ اسی API کو کال کرتے ہیں۔
- QA اور ٹیسٹ انجینئرز — §7 (نقائص) اور §10 (وسائل کی فہرست) کے خلاف معاہدہ ٹیسٹ مرتب کرنے کے لیے۔
- سیکیورٹی جائزہ — §3 (تصدیق و اجازت)، §4 (ریٹ لمٹس)، اور §16 (مشاہدہ پذیری)
/specs/ur/11-security-compliance/سے حوالہ دیتے ہیں۔
یہ دستاویز API کے خدوخال کے لیے مستند ماخذ ہے۔ یہ /specs/ur/08-integrations-spec/ کے §8 (عوامی API) کو ایک مکمل معاہدے میں توسیع دیتی ہے۔ انضمام کی تفصیلی دستاویز انفرادی انضمام ایڈاپٹرز (NADRA، SECP، Mailjet وغیرہ) کے لیے مستند ماخذ برقرار رہتی ہے؛ یہ دستاویز صرف اس سطح کا احاطہ کرتی ہے جو SITP خود بے نقاب کرتا ہے۔ جہاں دونوں کسی عوامی-API تفصیل پر متفق نہ ہوں، یہ دستاویز حاوی ہے۔
ہر وسیلہ کے پیچھے ڈیٹا ماڈل /specs/ur/05-data-model/ میں متعین ہے؛ API فیلڈ کے نام وہاں دستاویز کردہ snake_case کالموں کے camelCase منعکس ہیں۔
2. بیس URL، ورژننگ اور میڈیا اقسام
2.1 بیس URL
| ماحول | بیس URL |
|---|---|
| پروڈکشن | https://sindhitportal.maahir.io/api/v1 |
| سینڈ باکس | https://sandbox.sindhitportal.maahir.io/api/v1 (دیکھیں §15) |
| OpenAPI دستاویز | GET /api/v1/openapi.json |
| انٹرایکٹو دستاویزات (Swagger UI) | https://sindhitportal.maahir.io/docs/api |
اس دستاویز کے تمام پاتھ مکمل طور پر لکھے جانے کے بغیر بیس URL کے نسبت سے ہیں۔
2.2 ورژننگ کی حکمت عملی
SITP URL سیگمنٹ میجر ورژننگ (/api/v1، /api/v2) استعمال کرتا ہے۔ قواعد:
- پیچ/مائنر تبدیلیاں (اضافی، غیر توڑنے والی) موجودہ میجر ورژن میں جاری ہوتی ہیں۔ مثالیں: ایک نیا اختیاری فیلڈ، نیا endپوائنٹ، ایک نئی enum قدر جسے کلائنٹ نظر انداز کر سکیں، نیا query پیرامیٹر۔
- توڑنے والی تبدیلیاں نئے میجر ورژن کا تقاضا کرتی ہیں۔ مثالیں: فیلڈ ہٹانا، فیلڈ کی قسم بدلنا، ڈیفالٹ رویہ بدلنا، enum کو تنگ کرنا، اسٹیٹس کوڈ بدلنا۔
- جب نیا میجر ورژن جاری ہو تو پچھلا ورژن کم از کم 12 ماہ تک متوازی طور پر معاون رہتا ہے (دیکھیں §14 Deprecation)۔ دونوں ورژن ایک ہی ڈپلائمنٹ پر چلتے ہیں؛ روٹنگ URL سیگمنٹ کے ذریعے ہوتی ہے۔
- کوئی
Accept-ہیڈر ورژننگ نہیں — URL سیگمنٹ واحد ورژن منتخب کار ہے۔ اس سے کلائنٹ کوڈ، پراکسیاں، اور ڈی بگنگ آسان رہتی ہے۔ - ہر جواب ایک
X-SITP-API-Version: v1ہیڈر رکھتا ہے تاکہ کلائنٹس اور لاگز تصدیق کر سکیں کہ کس ورژن نے درخواست پیش کی۔
یہ کہ توڑنے والی کیا ہے §14.2 میں دستاویز ہے اور /api/v1/openapi.json پر پیش کردہ چینج لاگ میں ظاہر ہے (OpenAPI کا info.version ایک میجر کے اندر SemVer پر کاربند ہے)۔
2.3 میڈیا اقسام
| پہلو | قاعدہ |
|---|---|
| درخواست باڈی | Content-Type: application/json (UTF-8)۔ Multipart صرف براہ راست فائل اپ لوڈ کے لیے استعمال ہوتا ہے جب کوئی پارٹنر presigned-URL فلو استعمال نہیں کر سکتا (دیکھیں §10 Attachments)، SITP کے زیرِ ملکیت endپوائنٹ پر۔ |
| جواب باڈی | تمام وسائل کے لیے application/json۔ نقائص application/problem+json ہیں (§7)۔ |
| لوکیل | Accept-Language: en | ur | sd انسان کے پڑھنے کے قابل فیلڈز (title، displayName، message) کی زبان کنٹرول کرتا ہے۔ نامعلوم قدریں en پر واپس آتی ہیں۔ |
| کیلنڈر | Prefer: calendar=hijri تاریخ رکھنے والے فیلڈز میں دوہری گریگورین+ہجری تاریخیں لوٹاتا ہے (_context.md §2 کے مطابق)۔ |
| کمپریشن | gzip اور br Accept-Encoding کے ذریعے معاون ہیں۔ |
2.4 عام ہیڈرز (ہر درخواست)
| ہیڈر | ضروری | مقصد |
|---|---|---|
Authorization |
ہاں (عوامی + ٹوکن ایکسچینج endپوائنٹس کے سوا) | Bearer <access_token> — OAuth2 یا OIDC (§3)۔ |
Accept-Language |
نہیں (ڈیفالٹ en) |
انسان کے پڑھنے کے قابل فیلڈز کی لوکیل۔ |
X-Request-Id |
نہیں | کلائنٹ کی فراہم کردہ corelation آئی ڈی؛ جواب میں لوٹائی جاتی ہے (§16)۔ اگر غیر حاضر ہو تو SITP ایک تیار کرتا ہے۔ |
Idempotency-Key |
تحریروں پر لازم (§8) | UUID v4/v7؛ 24 گھنٹوں کے اندر duplicate ہٹاتا ہے۔ |
User-Agent |
تجویز کردہ | تشخیص کے لیے پارٹنر شناخت کنندہ۔ |
3. تصدیق و اجازت
SITP دو تصدیقی انداز بے نقاب کرتا ہے، دونوں خود میزبان Keycloak مثال پر ختم ہوتے ہیں (/specs/ur/08-integrations-spec/ §7 کے مطابق):
- OAuth 2.0 client-credentials — پارٹنر ایپس کے لیے (مشین سے مشین تک)۔ کوئی آخری صارف عمل میں نہیں۔
- OIDC bearer (Authorization Code + PKCE) — انٹرایکٹو صارفین کے لیے (کمپنی نمائندے، حکومتی عملہ) جو SITP UI یا کوئی وفاقی حکومتی IdP کے ذریعے لاگ ان ہوتے ہیں۔
دونوں مختصر مدت کے bearer رسائی ٹوکنز (JWTs) پیدا کرتے ہیں جو Authorization: Bearer <token> ہیڈر میں بھیجے جاتے ہیں۔ ٹوکنز کبھی بھی query پیرامیٹرز کے طور پر نہیں بھیجے جاتے۔
3.1 OAuth 2.0 client-credentials (پارٹنر ایپس)
پارٹنر ایپس SITP پارٹنر کنسول میں رجسٹرڈ ہوتی ہیں اور ایک client_id اور client_secret وصول کرتی ہیں۔ ہر پارٹنر ایک یا زیادہ companyId قدروں سے بندھا ہوتا ہے جس کے لیے وہ مجاز ہے (کمپنی پارٹنر کو پورٹل میں OAuth انداز کی رضامندی سے اجازت دیتی ہے)۔ فلو:
ٹوکن درخواست
POST /api/v1/partners/tokens
Content-Type: application/json
{
"grant_type": "client_credentials",
"client_id": "partner_acmeintegrator",
"client_secret": "••••••••••••••••",
"scope": "tickets:write tickets:read kb:read"
}
ٹوکن جواب
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "tickets:write tickets:read kb:read",
"issued_token_type": "urn:ietf:params:oauth:token-type:access_token"
}
- ٹوکن TTL: 1 گھنٹہ (3600 s)۔ پارٹنرز کو ختم ہونے سے پہلے refresh کرنا چاہیے؛ SITP کسی ٹوکن کو طویل نہیں کرتا، بلکہ نیا جاری کرتا ہے۔
client_secretرجسٹریشن پر ایک بار دکھایا جاتا ہے؛ اس کی rotation ایک دستاویز کردہ رن بک ہے (دیکھیں/specs/ur/11-security-compliance/)۔- ٹوکنز اسکوپ محدود ہیں (§3.3)۔ غیر دی گئی اسکوپ کی درخواست
SITP-AUTH-003نقص لوٹاتی ہے (§7.3)۔
ٹوکن منسوخی
POST /api/v1/partners/tokens/revoke
Authorization: Bearer <partner admin token>
Content-Type: application/json
{ "token": "eyJhbGciOi...", "token_type_hint": "access_token" }
یہ 204 No Content لوٹاتا ہے۔ ایک denylist کو Redis میں عکس بند کیا جاتا ہے تاکہ منسوخی چند سیکنڈوں میں اثر انداز ہو۔
3.2 OIDC bearer (انٹرایکٹو صارفین)
کمپنی نمائندے اور حکومتی عملہ SITP UI کے ذریعے تصدیق کرتے ہیں، جو Keycloak کے خلاف PKCE کے ساتھ OIDC Authorization Code فلو انجام دیتا ہے۔ نتیجے کا رسائی ٹوکن ایک bearer کے طور پر API کو بالکل پارٹنر ٹوکن کی طرح بھیجا جاتا ہے۔ Claims میں sub، email، realm (gov-staff | company)، roles[]، deptCode، اور 2fa_verified شامل ہیں (/specs/ur/08-integrations-spec/ §7 کے مطابق)۔ حکومتی عملہ کے ٹوکنز additionally ایک SITP کردار (Staff، POC، DG، Secretary، SuperAdmin) رکھتے ہیں جو RolesGuard/PermissionsGuard استعمال کرتا ہے۔
SITP کے اپنے فرنٹ اینڈ کے لیے، یہ شفاف ہے — SPA ٹوکن کو محفوظ سیشن میں رکھتا ہے۔ تیسرے فریق UI کے لیے جو اسی Keycloak realm سے وفاقی بنتی ہیں، وہی طریقہ کار لاگو ہوتا ہے۔
3.3 اسکوپس
اسکوپس پارٹنر ایپس کے لیے اجازت کی اکائی ہیں۔ انٹرایکٹو صارفین کو کردار + صلاحیت کے ذریعے اجازت دی جاتی ہے (/specs/ur/04-roles-permissions/ کے مطابق)، اسکوپ کے ذریعے نہیں؛ ان کا ٹوکن پھر بھی endپوائنٹ کی مطلوبہ صلاحیت کو پورا کرنا چاہیے۔
| اسکوپ | اجازتیں |
|---|---|
tickets:read |
مجاز کمپنیوں کے ٹکٹس، پیغامات، اور منسلکات پڑھنا۔ |
tickets:write |
ٹکٹ بنانا، پیغامات شامل کرنا، قبول/بند کرنا، منسلکات اپ لوڈ کرنا۔ |
orgs:read |
مجاز کمپنیوں کے تنظیمی + نمائندہ ریکارڈز پڑھنا۔ |
orgs:write |
تنظیم رجسٹر کرنا، نمائندگان کو مدعو/اپڈیٹ کرنا۔ |
reps:write |
نمائندگان کا انتظام (orgs:write کا ذیلی سیٹ)۔ |
kb:read |
شائع کردہ KB مضامین اور SOPs پڑھنا۔ |
stats:read |
غیر عوامی تجزیاتی حصے پڑھنا (عوامی stats endپوائنٹ کو کوئی اسکوپ درکار نہیں)۔ |
files:read |
presigned URL کے ذریعے منسلکہ مواد ڈاؤن لوڈ کرنا۔ |
files:write |
اپ لوڈ شروع کرنا / فائلیں منسلک کرنا۔ |
webhooks:manage |
ویب ہوک سبسکرپشنز بنانا، فہرست، حذف، دوبارہ چلانا۔ |
* |
سوپر-اسکوپ؛ صرف فرسٹ پارٹی SITP کلائنٹس کے لیے محفوظ ہے۔ |
ایک endپوائنٹ کا مطلوبہ اسکوپ وسائل کی فہرست (§10) اور OpenAPI کے security بلاک (§9) میں درج ہے۔ اسکوپ کی کمی → SITP-AUTH-004 (§7.3)۔
3.4 عوامی (no-auth) endپوائنٹس
کچھ مختصر صرف پڑھنے کے endپوائنٹس عوامی ہیں — کوئی ٹوکن درکار نہیں — تاکہ شہری اور محقق بغیر رجسٹریشن کے انہیں استعمال کر سکیں:
GET /departments،GET /departments/{deptId}GET /service-catalog،GET /service-catalog/{serviceId}GET /kb/articles،GET /kb/articles/{articleId}(شائع شدہ ذیلی سیٹ)GET /stats/public،GET /stats/public/summary
عوامی endپوائنٹس پھر بھی ریٹ لمٹنگ (§4) کے تابع ہیں ایک سخت تر ڈیفالٹ درجے پر۔
4. ریٹ لمٹنگ
ریٹ لمٹس پلیٹ فارم کو غلط استعمال کرنے والے یا بھاگ جانے والے کلائنٹس سے محفوظ رکھتے ہیں۔ لمٹس فی پارٹنر (client_id/ٹوکن سے شناخت کردہ) تصدیق شدہ کالز کے لیے اور فی ماخذ IP عوامی کالز کے لیے ہیں۔ لمٹس int_ratelimit جدول میں تشکیل کے قابل ہیں (/specs/ur/05-data-model/ §3.10 کے مطابق) اور پارٹنر درجے اور آپریشن کلاس کے لحاظ سے مختلف ہیں۔
4.1 درجہ بندی ماڈل
| درجہ | پڑھنے کا بجٹ | لکھنے کا بجٹ (ٹکٹ بنانا) | کون |
|---|---|---|---|
public |
120 درخواست/منٹ فی IP | n/a (کوئی تحریر نہیں) | عوامی endپوائنٹس کے گمنام کالرز۔ |
standard |
600 درخواست/منٹ | 60 درخواست/منٹ | رجسٹرڈ پارٹنرز کے لیے ڈیفالٹ۔ |
premium |
3 000 درخواست/منٹ | 300 درخواست/منٹ | معاہدہ شدہ اعلیٰ حجم پارٹنرز (تجارتی درجہ — TBD، دیکھیں §18)۔ |
first-party |
10 000 درخواست/منٹ | 1 000 درخواست/منٹ | SITP کا اپنا فرنٹ اینڈ، موبائل، اور اندرونی سروسز۔ |
لکھنے کی لمٹس ہر آپریشن کلاس کے لیے الگ ہیں (ٹکٹ بنانا، پیغام شامل کرنا، اپ لوڈ) تاکہ پڑھنے کا اچھال لکھنے کی گنجائش ختم نہ کر سکے۔ اچھالنے والے کلائنٹس کو throttle کیا جاتا ہے (HTTP 429)، بغیر پہلے اطلاع کے خاموشی سے کبھی banned نہیں کیا جاتا۔
4.2 ریٹ لمٹ ہیڈرز
ہر جواب — کامیاب جوابات سمیت — یہ ہیڈرز رکھتا ہے تاکہ کلائنٹس خود کو منظم کر سکیں:
| ہیڈر | معنی |
|---|---|
X-RateLimit-Limit |
موجودہ ونڈو کے لیے بجٹ (مثلاً، 600)۔ |
X-RateLimit-Remaining |
موجودہ ونڈو میں باقی درخواستیں۔ |
X-RateLimit-Reset |
Unix ٹائم اسٹیمپ جس پر ونڈو ری سیٹ ہوتی ہے۔ |
X-RateLimit-Tier |
وہ درجہ جو لاگو ہوا (public/standard/premium/first-party)۔ |
جب تجاوز کر جائے:
HTTP/1.1 429 Too Many Requests
Content-Type: application/problem+json
Retry-After: 28
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1752752522
{
"type": "https://sindhitportal.maahir.io/docs/errors/rate-limited",
"title": "Rate limit exceeded",
"status": 429,
"detail": "You have exceeded 600 requests per minute. Retry after the Retry-After window.",
"instance": "/api/v1/tickets",
"code": "SITP-RATELIMIT-001",
"retryAfterSeconds": 28
}
Retry-After ہمیشہ 429 پر موجود ہوتا ہے اور سیکنڈوں میں دیا جاتا ہے۔
5. پیجینیشن، فلٹرنگ، ترتیب دینا اور Sparse Fieldsets
5.1 پیجینیشن (cursor + page)
SITP فہرست endپوائنٹس کے لیے دو پیجینیشن انداز معاون ہے۔ Cursor اعلیٰ حجم، ترتیب دی گئی فہرستوں کے لیے ترجیحی ہے؛ page سہولت اور ایڈمن UIs کے لیے معاون ہے۔
| انداز | پیرامیٹرز | کب استعمال کریں |
|---|---|---|
| Cursor (ڈیفالٹ) | ?cursor=<opaque>&limit=50 |
/tickets، /tickets/{id}/messages، /kb/articles کے لیے ڈیفالٹ۔ داخلے/حذف ہونے پر مستحکم؛ زیادہ سے زیادہ limit=100، ڈیفالٹ 50۔ |
| Page | ?page=1&pageSize=50 |
/departments، /service-catalog، /stats/public پر اجازت۔ آسان UIs کے لیے آسان؛ page 1-اشاری شدہ ہے؛ زیادہ سے زیادہ pageSize=100۔ |
Cursor ٹوکنز کلائنٹ کے لیے opaque ہیں (ایک base64url-encoded signed سٹرنگ)؛ کلائنٹس کو انہیں black box سمجھنا چاہیے اور صرف واپس بھیج دینا چاہیے۔ جواب ہمیشہ links بلاک (§6) کے ذریعے کلائنٹ کو جاری رکھنے کا طریقہ بتاتا ہے۔
5.2 فلٹرنگ
فلٹرز فی endپوائنٹ whitelist-کی گئی تصدیق شدہ query پیرامیٹرز ہیں۔ نامعلوم فلٹرز SITP-VALIDATION-005 کے ساتھ مسترد کیے جاتے ہیں۔ عام فلٹرز:
| فلٹر | مثال | نوٹس |
|---|---|---|
| حیثیت | ?status=assigned,in_progress |
کومے سے جدا multi-value؛ اندر OR۔ |
| محکمہ | ?dept=SRB |
محکمہ کوڈ۔ |
| زمرہ | ?category=SRB-REFUND |
زمرہ کوڈ۔ |
| تاریخ کی حد | ?since=2026-07-01T00:00:00Z&until=2026-07-31T23:59:59Z |
ISO-8601، UTC۔ |
| تلاش | ?q=refund |
سرور Meilisearch کو تفویض کرتا ہے؛ کثیر لسانی (/specs/ur/05-data-model/ §2.7 کے مطابق)۔ |
| KB پر full-text | ?q=tax&locale=ur |
KB تلاش لوکیل کا احترام کرتی ہے۔ |
5.3 ترتیب دینا
?sort=<field> صعودی؛ ?sort=-<field> نزولی (ابتدائی -)۔ multi-sort: ?sort=-createdAt,priority۔ ترتیب دینے کے قابل فیلڈز فی endپوائنٹ OpenAPI میں درج ہیں؛ غیر ترتیب دینے کے قابل فیلڈ سے ترتیب دینے پر SITP-VALIDATION-006 لوٹتا ہے۔
5.4 Sparse fieldsets
کلائنٹس صرف وہ فیلڈز مانگ سکتے ہیں جو انہیں درکار ہیں تاکہ payload سائز کم ہو، جو موبائل اور میٹرڈ نیٹ ورکس کے لیے مفید ہے:
GET /api/v1/tickets/SITP-2026-SRB-000128?fields=ticketId,status,sla
Authorization: Bearer <token>
صرف data کے اندر مانگے گئے اعلیٰ سطحی فیلڈز لوٹاتا ہے۔ نامعلوم یا غیر مجاز فیلڈز خاموشی سے چھوڑ دیے جاتے ہیں (نقص نہیں) تاکہ کلائنٹس forward-compatible رہیں۔ Nested sparse selection dot-paths استعمال کرتا ہے: ?fields=ticketId,sla.responseBy۔
6. جواب کا لفافہ
ہر کامیاب جواب اسی لفافے کا استعمال کرتا ہے: { data, meta, links }۔ واحد وسیلہ جوابات وسیلہ کو data میں رکھتے ہیں اور خالی ہونے پر meta/links کو چھوڑ دیتے ہیں؛ فہرست جوابات تینوں کو بھرتے ہیں۔
| فیلڈ | ہمیشہ موجود؟ | معنی |
|---|---|---|
data |
ہاں | وسیلہ (آبجیکٹ) یا وسائل (array)۔ صرف 204 جوابات کے لیے null۔ |
meta |
نہیں | Out-of-band میٹا ڈیٹا: requestId، پیجینیشن شمار، ریٹ لمٹ eco، سرور گھڑی، استعمال شدہ لوکیل۔ |
links |
نہیں | پیجینیشن/نیویگیشن لنکس: self، next، prev، first، last۔ |
لفافہ مثال (cursor پیجینیشن کے ساتھ فہرست)
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01HZX9F8K7P4N2Q3R6STV8WXAB
X-SITP-API-Version: v1
{
"data": [
{ "ticketId": "SITP-2026-SRB-000127", "status": "assigned" },
{ "ticketId": "SITP-2026-SRB-000128", "status": "new" }
],
"meta": {
"requestId": "req_01HZX9F8K7P4N2Q3R6STV8WXAB",
"locale": "en",
"serverTime": "2026-07-17T09:18:42.117Z",
"page": { "limit": 50, "returned": 2, "hasMore": true }
},
"links": {
"self": "/api/v1/tickets?cursor=eyJpZCI6MTI3fQ&limit=50",
"next": "/api/v1/tickets?cursor=eyJpZCI6MTIyOH0&limit=50",
"prev": null,
"first": "/api/v1/tickets?limit=50"
}
}
لفافہ مثال (واحد وسیلہ)
{
"data": {
"ticketId": "SITP-2026-SRB-000128",
"status": "new"
},
"meta": { "requestId": "req_01HZX9F8K7P4N2Q3R6STV8WXAB" }
}
نقائص اس لفافے کا استعمال نہیں کرتے — وہ RFC 7807 (§7) استعمال کرتے ہیں۔
7. نقائص (RFC 7807 Problem Details)
تمام نقائص RFC 7807 (application/problem+json) استعمال کرتے ہیں۔ ہر نقص معیاری فیلڈز کے علاوہ ایک SITP مخصوص code (مستحکم، مشین کے پڑھنے کے قابل) رکھتا ہے۔ کلائنٹس کو code پر branch کرنا چاہیے، کبھی detail پر نہیں (جو انسان کے پڑھنے کے قابل اور localized ہے)۔
7.1 معیاری فیلڈز
| فیلڈ | قسم | معنی |
|---|---|---|
type |
URI | نقص کی زمرہ بندی کے لیے ایک دستاویزی صفحہ (dereferenceable)۔ |
title |
سٹرنگ | مختصر، مستحکم، انگریزی خلاصہ۔ |
status |
int | HTTP اسٹیٹس (echoed)۔ |
detail |
سٹرنگ | انسان کے پڑھنے کے قابل وضاحت، Accept-Language کے ذریعے localized۔ |
instance |
URI | وہ درخواست پاتھ جو ناکام ہوا۔ |
code |
سٹرنگ | SITP نقص کوڈ، مثلاً، SITP-VALIDATION-042۔ |
errors[] |
array | (صرف validation) فی فیلڈ تفصیل field اور code کے ساتھ۔ |
requestId |
سٹرنگ | corelation آئی ڈی (§16)، ہمیشہ موجود۔ |
7.2 Validation نقص کی مثال
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/problem+json
X-Request-Id: req_01HZX9F8K7P4N2Q3R6STV8WXAC
{
"type": "https://sindhitportal.maahir.io/docs/errors/validation",
"title": "Validation failed",
"status": 422,
"detail": "companyId does not match the partner's authorized scope.",
"instance": "/api/v1/tickets",
"code": "SITP-VALIDATION-042",
"requestId": "req_01HZX9F8K7P4N2Q3R6STV8WXAC",
"errors": [
{ "field": "companyId", "code": "SCOPE_MISMATCH" },
{ "field": "attachments[0].size", "code": "MAX_SIZE_EXCEEDED" }
]
}
7.3 نقص کوڈ کی فہرست
اسٹیٹس کوڈز HTTP پر کاربند ہیں۔ SITP نقص کوڈز خاندان کے لحاظ سے گروہ بند ہیں۔ یہ فہرست https://sindhitportal.maahir.io/docs/errors پر live پیش کی جاتی ہے اور OpenAPI دستاویز میں versioned ہے۔
code |
HTTP | خاندان | معنی |
|---|---|---|---|
SITP-AUTH-001 |
401 | Auth | Authorization ہیڈر غیر موجود۔ |
SITP-AUTH-002 |
401 | Auth | ٹوکن ختم یا malformed۔ |
SITP-AUTH-003 |
400 | Auth | مطلوبہ اسکوپ کلائنٹ کو دیا نہیں۔ |
SITP-AUTH-004 |
403 | Auth | ٹوکن درست مگر اس endپوائنٹ کے لیے مطلوبہ اسکوپ غیر موجود۔ |
SITP-AUTH-005 |
403 | Auth | اس عمل کے لیے 2FA لازم (حساس/VIP)۔ |
SITP-AUTH-006 |
403 | Auth | کمپنی نمائندہ certified نہیں (Module O گیٹ)۔ |
SITP-RATELIMIT-001 |
429 | Rate limit | ریٹ لمٹ تجاوز (دیکھیں §4)۔ |
SITP-VALIDATION-001 |
400 | Validation | Malformed JSON باڈی۔ |
SITP-VALIDATION-002 |
400 | Validation | لازم فیلڈ غیر موجود۔ |
SITP-VALIDATION-003 |
400 | Validation | غلط فیلڈ قدر (format/range)۔ |
SITP-VALIDATION-004 |
422 | Validation | کاروباری اصول کی خلاف ورزی (مثلاً، proof گیٹ پورا نہیں)۔ |
SITP-VALIDATION-005 |
400 | Validation | نامعلوم فلٹر پیرامیٹر۔ |
SITP-VALIDATION-006 |
400 | Validation | غیر ترتیب دینے کے قابل فیلڈ۔ |
SITP-VALIDATION-042 |
422 | Validation | companyId پر اسکوپ عدمِ مطابقت۔ |
SITP-NOTFOUND-001 |
404 | Not found | وسیلہ موجود نہیں۔ |
SITP-NOTFOUND-002 |
404 | Not found | وسیلہ موجود مگر کالر کی visibility نہیں (001 جیسا خدوخال تاکہ موجودگی leak نہ ہو)۔ |
SITP-CONFLICT-001 |
409 | Conflict | موجودہ حیثیت سے اسٹیٹ ٹرانزیشن کی اجازت نہیں۔ |
SITP-CONFLICT-002 |
409 | Conflict | idempotency کلید duplicate مگر مختلف payload۔ |
SITP-CONFLICT-003 |
409 | Conflict | ٹکٹ پہلے ضم/بند ہو چکا۔ |
SITP-UPLOAD-001 |
413 | Upload | منسلکہ فی فائل سائز لمٹ سے تجاوز۔ |
SITP-UPLOAD-002 |
415 | Upload | غیر معاون MIME قسم۔ |
SITP-UPLOAD-003 |
422 | Upload | AV سکین نے فائل کو متاثر قرار دیا۔ |
SITP-DEPENDENCY-001 |
502 | Dependency | اوپرStream انضمام (NADRA/SECP/…) دستیاب نہیں؛ بعد میں دوبارہ کوشش۔ |
SITP-DEPENDENCY-002 |
503 | Dependency | ایک مطلوبہ ایڈاپٹر کے لیے سرکٹ بریکر کھلا ہوا۔ |
SITP-INTERNAL-001 |
500 | Internal | Unhandled سرور نقص؛ corelation آئی ڈی requestId میں۔ |
4xx نقائص (429 کے سوا) کلائنٹس کے ذریعے کبھی دوبارہ کوشش نہیں کیے جاتے۔ 5xx اور 429 کو exponential backoff کے ساتھ دوبارہ کوشش کیا جا سکتا ہے (دیکھیں §8 اور /specs/ur/08-integrations-spec/ §11.2)۔
8. Idempotency
ہر تحریر (POST، PUT، PATCH، DELETE جو state بدلے) Idempotency-Key ہیڈر قبول کرتی ہے۔ ہیڈر کلائنٹ کا پیدا کردہ UUID v4 یا v7 ہے۔ 24 گھنٹے کی idempotency ونڈو کے اندر (/specs/ur/08-integrations-spec/ §11 میں NFR-INT-004 کے مطابق):
- کسی دی گئی کلید کی پہلی درخواست عمل میں لائی جاتی ہے اور اس کا مکمل جواب (status، body، headers) cache ہوتا ہے۔
- اسی کلید کی دہرائی درخواست cached جواب لوٹاتی ہے، چاہے اصل validation کے لحاظ سے ناکام ہوئی ہو — اس لیے کلائنٹس کو payload بدلنے پر نیا کلید تیار کرنا چاہیے۔
- اسی کلید مگر مختلف payload باڈی کی دہرائی درخواست
SITP-CONFLICT-002(409) لوٹاتی ہے، جو ایک مختلف intent کے لیے کلید کے حادثاتی استعمال سے بچاتا ہے۔ GETدرخواستیں ہیڈر کو نظر انداز کرتی ہیں۔
تحریر پر Idempotency-Key کی کمی SITP-VALIDATION-001 لوٹاتی ہے جس میں ہیڈر کی طرف اشارہ ہوتا ہے۔ یہ ہیڈر audit_logs.request_id correlation میں بھی ظاہر ہوتا ہے (/specs/ur/05-data-model/ §3.10 کے مطابق) تاکہ ایک تحریر اور اس کے نتیجے میں ہونے والے انضمام کالز ایک thread میں شریک ہوں۔
POST /api/v1/tickets
Authorization: Bearer <token>
Idempotency-Key: 9a2c4e6b-1f3d-4a2c-9e8b-7d6c5b4a3f2e
Content-Type: application/json
{ "companyId": "cmp_01HZX7K4P9N2Q3R6STV8WXYPJ", "title": "..." }
24 گھنٹوں کے اندر مماثل درخواست دہرانا اصل 201 Created اسی ticketId کے ساتھ لوٹاتا ہے، نہ کہ duplicate ٹکٹ۔
9. OpenAPI 3.1 خاکہ
مکمل OpenAPI 3.1 دستاویز NestJS کنٹرولرز سے @nestjs/swagger کے ذریعے پیدا کی جاتی ہے اور /api/v1/openapi.json پر پیش کی جاتی ہے، پھر /docs/api پر render ہوتی ہے۔ نیچے دیا گیا خاکہ اعلیٰ سطحی دستاویزی خدوخال اور تین نمائندگی کرنے والے آپریشنز (POST /partners/tokens، POST /tickets، GET /tickets/{ticketId}) دکھاتا ہے۔ یہ مثالی ہے، مکمل نہیں۔
openapi: 3.1.0
info:
title: Sindh IT Portal — Facilitation Desk Public API
version: 1.4.0
description: >
REST API for partner apps and interactive clients of the Sindh IT Portal.
Base URL: https://sindhitportal.maahir.io/api/v1
contact:
name: SITP API Support
email: api-support@sindhitportal.maahir.io
license:
name: Proprietary — Government of Sindh
servers:
- url: https://sindhitportal.maahir.io/api/v1
description: Production
- url: https://sandbox.sindhitportal.maahir.io/api/v1
description: Sandbox
tags:
- name: Auth
- name: Tickets
- name: TicketMessages
- name: Attachments
- name: Organizations
- name: Representatives
- name: Departments
- name: ServiceCatalog
- name: KnowledgeBase
- name: PublicStats
- name: Webhooks
security:
- bearerAuth: []
- oauth2: [tickets:read]
paths:
/partners/tokens:
post:
tags: [Auth]
summary: Exchange client credentials for a bearer token (OAuth2 client-credentials)
operationId: createPartnerToken
security: [] # public endpoint
parameters:
- $ref: '#/components/parameters/IdempotencyKey'
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/TokenRequest' }
responses:
'200':
description: Token issued
content:
application/json:
schema: { $ref: '#/components/schemas/TokenResponse' }
'400': { $ref: '#/components/responses/Problem' }
'401': { $ref: '#/components/responses/Problem' }
/tickets:
post:
tags: [Tickets]
summary: Create a ticket on behalf of a company
operationId: createTicket
security:
- bearerAuth: []
- oauth2: [tickets:write]
parameters:
- $ref: '#/components/parameters/IdempotencyKey'
- $ref: '#/components/parameters/AcceptLanguage'
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/TicketCreateRequest' }
responses:
'201':
description: Ticket created
headers:
Location: { schema: { type: string } }
content:
application/json:
schema: { $ref: '#/components/schemas/TicketEnvelope' }
'400': { $ref: '#/components/responses/Problem' }
'401': { $ref: '#/components/responses/Problem' }
'403': { $ref: '#/components/responses/Problem' }
'422': { $ref: '#/components/responses/Problem' }
'429': { $ref: '#/components/responses/Problem' }
get:
tags: [Tickets]
summary: List tickets for the authorized company (cursor pagination)
operationId: listTickets
security:
- bearerAuth: []
- oauth2: [tickets:read]
parameters:
- in: query
name: cursor
schema: { type: string }
- in: query
name: limit
schema: { type: integer, minimum: 1, maximum: 100, default: 50 }
- in: query
name: status
schema: { type: array, items: { type: string } }
- in: query
name: dept
schema: { type: string }
- in: query
name: since
schema: { type: string, format: date-time }
responses:
'200':
description: A page of tickets
content:
application/json:
schema: { $ref: '#/components/schemas/TicketListEnvelope' }
'401': { $ref: '#/components/responses/Problem' }
'429': { $ref: '#/components/responses/Problem' }
/tickets/{ticketId}:
get:
tags: [Tickets]
summary: Get a single ticket by tracking id
operationId: getTicket
security:
- bearerAuth: []
- oauth2: [tickets:read]
parameters:
- in: path
name: ticketId
required: true
schema: { type: string, example: SITP-2026-SRB-000128 }
- in: query
name: fields
description: Sparse fieldset
schema: { type: string, example: ticketId,status,sla }
responses:
'200':
description: The ticket
content:
application/json:
schema: { $ref: '#/components/schemas/TicketEnvelope' }
'404': { $ref: '#/components/responses/Problem' }
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
oauth2:
type: oauth2
flows:
clientCredentials:
tokenUrl: /api/v1/partners/tokens
scopes:
tickets:read: Read tickets, messages, attachments
tickets:write: Create and mutate tickets
orgs:read: Read organization records
orgs:write: Register and manage organizations
reps:write: Manage representatives
kb:read: Read published KB articles
stats:read: Read non-public analytics slices
files:read: Download attachments
files:write: Upload and attach files
webhooks:manage: Manage webhook subscriptions
parameters:
IdempotencyKey:
in: header
name: Idempotency-Key
required: true
schema: { type: string, format: uuid }
AcceptLanguage:
in: header
name: Accept-Language
required: false
schema: { type: string, enum: [en, ur, sd], default: en }
responses:
Problem:
description: An RFC 7807 problem document
content:
application/problem+json:
schema: { $ref: '#/components/schemas/Problem' }
schemas:
Problem:
type: object
required: [type, title, status, code]
properties:
type: { type: string, format: uri }
title: { type: string }
status: { type: integer }
detail: { type: string }
instance: { type: string }
code: { type: string, example: SITP-VALIDATION-042 }
requestId:{ type: string }
errors:
type: array
items:
type: object
properties:
field: { type: string }
code: { type: string }
مکمل دستاویز §10 کے ہر آپریشن کے لیے یہی پیٹرن دہراتی ہے، بشمول request-body schemas، response envelopes، ہر دستاویزی status کے لیے problem-details، اور §12 کے واقعات کے لیے webhooks: ایکسٹینشن (OpenAPI 3.1 native webhooks کی معاونت رکھتا ہے)۔
10. وسائل کی فہرست
نیچے دی گئی فہرست v1 کا ہر endپوائنٹ درج کرتی ہے۔ فیلڈ نام مستحکم ہیں؛ مکمل schemas /api/v1/openapi.json میں ہیں۔ ہر قطار رکھتی ہے: HTTP میتھڈ، پاتھ، مقصد، مطلوبہ auth اسکوپ (یا public)، اور آیا تحریر idempotent ہے (Idempotency-Key قبول کرتی ہے)۔
ضابطے:
GET/HEADکبھی idempotent-keyed نہیں۔{ticketId}صارف کا سامنے کا ٹریکنگ آئی ڈیSITP-YYYY-DEPT-NNNNNNہے۔ تمام{orgId}/{repId}opaque SITP ids ہیں۔
10.1 Auth
| میتھڈ | پاتھ | مقصد | اسکوپ | Idempotent؟ |
|---|---|---|---|---|
| POST | /partners/tokens |
client credentials کا bearer ٹوکن سے تبادلہ۔ | — (public) | ہاں |
| POST | /partners/tokens/revoke |
ٹوکن منسوخ کرنا۔ | * (partner admin) |
ہاں |
10.2 Tickets
| میتھڈ | پاتھ | مقصد | اسکوپ | Idempotent؟ |
|---|---|---|---|---|
| POST | /tickets |
کسی کمپنی کی طرف سے ٹکٹ بنانا۔ | tickets:write |
ہاں |
| GET | /tickets |
مجاز کمپنی کے ٹکٹس کی فہرست۔ | tickets:read |
نہیں |
| GET | /tickets/{ticketId} |
حیثیت، SLA، تاریخ کے ساتھ ایک ٹکٹ حاصل کریں۔ | tickets:read |
نہیں |
| PATCH | /tickets/{ticketId} |
قابلِ ترمیم ٹکٹ فیلڈز (ترجیح، زمرہ) اپڈیٹ کریں۔ | tickets:write |
ہاں |
| POST | /tickets/{ticketId}/accept |
کمپنی حل قبول کرتی ہے → آٹو کلوز ٹرگر۔ | tickets:write |
ہاں |
10.3 TicketMessages
| میتھڈ | پاتھ | مقصد | اسکوپ | Idempotent؟ |
|---|---|---|---|---|
| GET | /tickets/{ticketId}/messages |
عوامی-thread پیغامات کی فہرست۔ | tickets:read |
نہیں |
| POST | /tickets/{ticketId}/messages |
ایک عوامی پیغام شامل کرنا۔ | tickets:write |
ہاں |
10.4 Attachments
| میتھڈ | پاتھ | مقصد | اسکوپ | Idempotent؟ |
|---|---|---|---|---|
| POST | /uploads |
اپ لوڈ شروع کرنا؛ presigned URL + uploadId لوٹاتا ہے۔ |
files:write |
ہاں |
| GET | /tickets/{ticketId}/attachments |
ٹکٹ پر منسلکات کی فہرست۔ | tickets:read |
نہیں |
| GET | /attachments/{attachmentId} |
منسلکہ میٹا ڈیٹا + مختصر مدت کا ڈاؤن لوڈ URL حاصل کریں۔ | files:read |
نہیں |
تجویز کردہ پارٹنر فلو MinIO تک presigned-URL اپ لوڈ ہے (پارٹنر bytes براہ راست آبجیکٹ اسٹوریج کو PUT کرتا ہے؛ SITP bytes کبھی proxy نہیں کرتا)۔ PUT مکمل ہونے کے بعد، پارٹنر uploadId کو POST /tickets میں refer کرتا ہے (/specs/ur/08-integrations-spec/ کے §11.3 کو دیکھیں)۔ ہر اپ لوڈ قابلِ اتصال ہونے سے پہلے ClamAV کے ذریعے AV-scan ہوتا ہے (متاثر ہو تو SITP-UPLOAD-003 — /specs/ur/05-data-model/ §4.4 media_library.av_status کے مطابق)۔
10.5 Organizations
| میتھڈ | پاتھ | مقصد | اسکوپ | Idempotent؟ |
|---|---|---|---|---|
| POST | /organizations |
نئی تنظیم رجسٹر کرنا (file-first → عارضی)۔ | orgs:write |
ہاں |
| GET | /organizations/{orgId} |
تنظیم ریکارڈ + تصدیقی حیثیت حاصل کریں۔ | orgs:read |
نہیں |
| GET | /organizations/me |
کالر کی اپنی تنظیم حاصل کریں (ٹوکن سے)۔ | orgs:read |
نہیں |
10.6 Representatives
| میتھڈ | پاتھ | مقصد | اسکوپ | Idempotent؟ |
|---|---|---|---|---|
| GET | /organizations/{orgId}/representatives |
نمائندگان کی فہرست۔ | orgs:read |
نہیں |
| POST | /organizations/{orgId}/representatives |
ایک نمائندہ مدعو کرنا۔ | reps:write |
ہاں |
| PATCH | /representatives/{repId} |
نمائندہ اپڈیٹ کرنا (کردار، رابطہ، حیثیت)۔ | reps:write |
ہاں |
10.7 Departments
| میتھڈ | پاتھ | مقصد | اسکوپ | Idempotent؟ |
|---|---|---|---|---|
| GET | /departments |
محکموں کی فہرست (شجرہ)۔ | public | نہیں |
| GET | /departments/{deptId} |
شعبوں، اوقات، چھٹیوں کے ساتھ ایک محکمہ حاصل کریں۔ | public | نہیں |
10.8 ServiceCatalog
| میتھڈ | پاتھ | مقصد | اسکوپ | Idempotent؟ |
|---|---|---|---|---|
| GET | /service-catalog |
زمرہ جات اور SLAs کے ساتھ پیش کردہ سروسز کی فہرست۔ | public | نہیں |
| GET | /service-catalog/{serviceId} |
لازم فیلڈز اور ڈیفالٹ SLA کے ساتھ ایک سروس حاصل کریں۔ | public | نہیں |
10.9 KnowledgeBase
| میتھڈ | پاتھ | مقصد | اسکوپ | Idempotent؟ |
|---|---|---|---|---|
| GET | /kb/articles |
شائع شدہ KB مضامین کی فہرست/تلاش (کثیر لسانی)۔ | public (subset) / kb:read (full) |
نہیں |
| GET | /kb/articles/{articleId} |
مطلوبہ لوکیل میں ایک KB مضمون حاصل کریں۔ | public / kb:read |
نہیں |
10.10 PublicStats
| میتھڈ | پاتھ | مقصد | اسکوپ | Idempotent؟ |
|---|---|---|---|---|
| GET | /stats/public |
عوامی شفافیت ڈیش بورڈ مجموعات (gumnami شدہ)۔ | public | نہیں |
| GET | /stats/public/summary |
سرخی KPIs (کل، محکمے کے لحاظ سے، حیثیت کے لحاظ سے)۔ | public | نہیں |
عوامی-stats payloads /specs/ur/17-analytics-kpis/ میں تجزیاتی ماڈل سے اخذ کردہ gumnami شدہ مجموعات ہیں۔ کوئی انفرادی ٹکٹ یا کمپنی شناخت کے قابل نہیں۔
10.11 Webhooks
| میتھڈ | پاتھ | مقصد | اسکوپ | Idempotent؟ |
|---|---|---|---|---|
| GET | /webhooks/subscriptions |
کالر کی ویب ہوک سبسکرپشنز کی فہرست۔ | webhooks:manage |
نہیں |
| POST | /webhooks/subscriptions |
ایک ویب ہوک سبسکرپشن بنانا (URL + events + secret)۔ | webhooks:manage |
ہاں |
| DELETE | /webhooks/subscriptions/{subId} |
ایک سبسکرپشن حذف کرنا۔ | webhooks:manage |
ہاں |
| POST | /webhooks/subscriptions/{subId}/replay |
ماضی کے واقعات کی ایک ونڈو دوبارہ چلانا۔ | webhooks:manage |
ہاں |
کل v1 endپوائنٹس: 30۔
11. نمونہ درخواست/جواب Flows
تین end-to-end flows جو لفافہ، idempotency، نقائص، اور پیجینیشن کو استعمال کرتے ہیں۔ فیلڈ نام /specs/ur/05-data-model/ کا عکس ہیں (API کے لیے camelCased)۔
11.1 ٹکٹ بنانا (پارٹنر، کسی کمپنی کی طرف سے)
ایک پارٹنر ایپ مجاز کمپنی کی طرف سے ٹکٹ درج کرتی ہے، پہلے اپ لوڈ کردہ فائل منسلک کرتی ہے۔ کال idempotent ہے؛ اسی Idempotency-Key کو 24 گھنٹوں کے اندر دہرانا مماثل 201 جواب لوٹاتا ہے (کوئی duplicate ٹکٹ نہیں)۔
درخواست
POST /api/v1/tickets
Host: sindhitportal.maahir.io
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIs...
Idempotency-Key: 9a2c4e6b-1f3d-4a2c-9e8b-7d6c5b4a3f2e
X-Request-Id: req_01HZX9F8K7P4N2Q3R6STV8WXAB
Accept-Language: en
Content-Type: application/json
{
"companyId": "cmp_01HZX7K4P9N2Q3R6STV8WXYPJ",
"title": "Pending sales tax refund for Q4 2025",
"description": "Our company filed the Q4 2025 SRB refund on 15 Jan 2026; no acknowledgment received.",
"category": "SRB-REFUND",
"targetDept": "SRB",
"priority": "normal",
"language": "en",
"attachments": [
{
"filename": "SRB-Q4-2025-filing.pdf",
"mimeType": "application/pdf",
"size": 482310,
"uploadId": "fil_upl_01HZX9F8K7P4N2Q3R6STV8WXY"
}
],
"requestedBy": { "repId": "rep_01HZX7K4P9N2Q3R6STV8WXYPJ" }
}
جواب
HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/v1/tickets/SITP-2026-SRB-000128
X-Request-Id: req_01HZX9F8K7P4N2Q3R6STV8WXAB
X-SITP-API-Version: v1
X-RateLimit-Tier: standard
X-RateLimit-Remaining: 599
{
"data": {
"ticketId": "SITP-2026-SRB-000128",
"status": "new",
"state": "triage-pending",
"category": "SRB-REFUND",
"targetDept": "SRB",
"priority": "normal",
"sla": {
"responseBy": "2026-07-19T09:00:00Z",
"resolveBy": "2026-07-27T09:00:00Z",
"paused": false
},
"createdAt": "2026-07-17T09:18:42.117Z",
"portalUrl": "https://sindhitportal.maahir.io/tickets/SITP-2026-SRB-000128",
"attachments": [
{
"filename": "SRB-Q4-2025-filing.pdf",
"attachmentId": "fil_att_01HZX9F8K7P4N2Q3R6STV8WXZ",
"size": 482310,
"isEvidence": false
}
]
},
"meta": {
"requestId": "req_01HZX9F8K7P4N2Q3R6STV8WXAB",
"locale": "en",
"serverTime": "2026-07-17T09:18:42.117Z"
}
}
اسی Idempotency-Key اور مماثل باڈی کے ساتھ duplicate POST اسی 201 (اسی ticketId کے ساتھ) لوٹاتا ہے، 409/duplicate کے بجائے؛ اسی کلید کے ساتھ مختلف باڈی 409 SITP-CONFLICT-002 لوٹاتی ہے (§8)۔
11.2 ٹکٹ حیثیت حاصل کرنا (پڑھنا، sparse fieldset)
ایک پارٹنر ایک ٹکٹ poll کرتا ہے اور صرف حیثیت + SLA فیلڈز مانگتا ہے تاکہ میٹرڈ موبائل لنک پر payload کم سے کم رہے۔ یہ sparse-fieldset query (§5.4) استعمال کرتا ہے۔
درخواست
GET /api/v1/tickets/SITP-2026-SRB-000128?fields=ticketId,status,sla,assignedTo
Host: sindhitportal.maahir.io
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIs...
Accept-Language: en
X-Request-Id: req_01HZX9F8K7P4N2Q3R6STV8WXAE
جواب
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01HZX9F8K7P4N2Q3R6STV8WXAE
X-SITP-API-Version: v1
X-RateLimit-Remaining: 587
{
"data": {
"ticketId": "SITP-2026-SRB-000128",
"status": "assigned",
"assignedTo": { "dept": "SRB", "section": "Refunds" },
"sla": {
"responseBy": "2026-07-19T09:00:00Z",
"resolveBy": "2026-07-27T09:00:00Z",
"paused": false,
"firstResponseAt": null
}
},
"meta": {
"requestId": "req_01HZX9F8K7P4N2Q3R6STV8WXAE",
"locale": "en",
"serverTime": "2026-07-17T10:02:13.004Z",
"requestedFields": ["ticketId", "status", "sla", "assignedTo"]
}
}
جن فیلڈز کی درخواست نہیں (title، description، attachments، createdAt، …) انہیں چھوڑ دیا جاتا ہے۔ اگر ٹکٹ موجود نہ ہو یا کالر کی visibility نہ ہو تو جواب 404 SITP-NOTFOUND-001 (§7.3) ہے — دونوں کے لیے ایک ہی خدوخال، تاکہ موجودگی leak نہ ہو۔
11.3 عوامی stats کی فہرست (گمنام، کوئی auth نہیں)
ایک شہری یا محقق gumnami شدہ عوامی-شفافیت مجموعات لاتا ہے۔ کوئی ٹوکن درکار نہیں؛ public ریٹ لمٹ درجے (§4.1) کا تابع۔
درخواست
GET /api/v1/stats/public?since=2026-07-01T00:00:00Z&until=2026-07-31T23:59:59Z&limit=20
Host: sindhitportal.maahir.io
Accept-Language: en
X-Request-Id: req_01HZX9F8K7P4N2Q3R6STV8WXAF
جواب
HTTP/1.1 200 OK
Content-Type: application/json
X-Request-Id: req_01HZX9F8K7P4N2Q3R6STV8WXAF
X-SITP-API-Version: v1
X-RateLimit-Tier: public
X-RateLimit-Remaining: 118
{
"data": {
"window": { "since": "2026-07-01T00:00:00Z", "until": "2026-07-31T23:59:59Z" },
"totals": {
"ticketsReceived": 4821,
"ticketsResolved": 3104,
"ticketsClosed": 2877,
"avgResolutionHours": 53.2,
"medianResolutionHours": 38.0,
"csatAverage": 4.2,
"withinSlaPercent": 87.4
},
"byDepartment": [
{ "dept": "SRB", "received": 1210, "resolved": 902, "withinSlaPercent": 91.1 },
{ "dept": "SITD", "received": 988, "resolved": 741, "withinSlaPercent": 89.0 },
{ "dept": "LBR", "received": 612, "resolved": 388, "withinSlaPercent": 81.3 },
{ "dept": "FIN", "received": 457, "resolved": 290, "withinSlaPercent": 84.6 }
],
"byStatus": {
"new": 612, "triaged": 233, "assigned": 410,
"in_progress": 374, "resolved": 227, "closed": 2877, "reopened": 88
},
"generatedAt": "2026-07-17T10:05:00.000Z"
},
"meta": {
"requestId": "req_01HZX9F8K7P4N2Q3R6STV8WXAF",
"locale": "en",
"serverTime": "2026-07-17T10:05:11.882Z",
"anonymized": true,
"page": { "limit": 20, "returned": 4, "hasMore": false }
},
"links": {
"self": "/api/v1/stats/public?since=2026-07-01T00:00:00Z&until=2026-07-31T23:59:59Z&limit=20"
}
}
byDepartment اور byStatus تفصیلات nightly pre-aggregate ہوتی ہیں (/specs/ur/17-analytics-kpis/ کے مطابق) اور cache ہوتی ہیں؛ meta.anonymized: true flag عوامی-stats جوابات پر ہمیشہ موجود ہوتا ہے۔ کسی بھی عوامی-stats payload میں کوئی انفرادی ٹکٹ، کمپنی، یا نمائندہ شناخت کے قابل نہیں۔
12. ویب ہوک معاہدہ
ویب ہوکس پارٹنر ایپس کو polling کے بغیر real time میں SITP واقعات پر ردعمل ظاہر کرنے کی سہولت دیتے ہیں۔ یہ سیکشن پارٹنر کا سامنے کا معاہدہ ہے؛ وصول کنندہ طرف کے میکانکس (دستخط verify، replay protect، enqueue) /specs/ur/08-integrations-spec/ §9 میں بیان ہیں۔
12.1 واقعات
| واقعہ | ٹرگر | عام صارف |
|---|---|---|
ticket.created |
کسی پارٹنر کی کمپنی کی طرف سے/کے لیے نیا ٹکٹ درج۔ | پارٹنر CRM۔ |
ticket.assigned |
ٹکٹ کسی محکمے/شعبے کو تفویض۔ | پارٹنر۔ |
ticket.status_changed |
کوئی بھی حیثیت ٹرانزیشن (triaged، in_progress، resolved، closed، reopened، appealed)۔ | پارٹنر۔ |
ticket.escalated |
اسکیلیشن لیڈر درجہ فائر ہوا۔ | پارٹنر + نگرانی ڈیش بورڈ۔ |
ticket.resolved |
Resolution-proof گیٹ پورا ہوا۔ | پارٹنر۔ |
ticket.closed |
آٹو کلوز یا کمپنی قبول۔ | پارٹنر۔ |
ticket.message_appended |
عوامی پیغام شامل کیا گیا (کمپنی یا محکمے کی طرف سے)۔ | پارٹنر۔ |
mom.published |
ٹکٹ پر MoM شائع ہوا۔ | پارٹنر۔ |
organization.verified |
بیک گراؤنڈ چیکس کامیاب → تصدیق شدہ بیج۔ | پارٹنر۔ |
organization.on_hold |
بیک گراؤنڈ چیک ناکام → on hold + اپیل۔ | پارٹنر۔ |
12.2 ترسیل کا معاہدہ
- Transport: پارٹنر کے رجسٹرڈ endپوائنٹ تک HTTPS
POST، JSON باڈی،Content-Type: application/json۔ - Signing: ہر payload سبسکرپشن کی shared secret کے ساتھ HMAC-SHA256 دستخط شدہ ہے۔ دستخط
<ts>.<raw-body>سٹرنگ پرX-SITP-Signatureہیڈر میںt=<unix-ts>,v1=<hex-signature>کے طور پر بھیجا جاتا ہے۔ پارٹنرز HMAC دوبارہ compute کر کے verify کرتے ہیں۔ - Replay تحفظ: timestamp
tچیک کیا جاتا ہے؛ 5 منٹ پرانے درخواستوں کو پارٹنر کے ذریعے مسترد کیا جانا چاہیے۔ ہر ترسیلeventIdاورdeliveryIdرکھتی ہے؛ SITP دونوں کوwebhookترسیل لاگ میں ریکارڈ کرتا ہے (/specs/ur/05-data-model/§3.10 اور/specs/ur/08-integrations-spec/§9.1 کے مطابق)۔ - Retry: non-2xx جوابات کو exponential backoff کے ساتھ دوبارہ کوشش کی جاتی ہے —
10s, 30s, 2m, 10m, 1h, 6h, 24h(7 کوششیں)۔ ختم ہونے کے بعد ترسیلfailedmark ہو جاتی ہے اور پارٹنر ڈیش بورڈ میںPOST /webhooks/subscriptions/{subId}/replayکے ذریعے دستی دوبارہ چلانے کے لیے پیش کی جاتی ہے۔ - Ordering: ایک ہی
ticketIdکے واقعات فی-endپوائنٹ قطار کے ذریعے ترتیب میں بھیجے جاتے ہیں۔ cross-ٹکٹ ترتیب کی ضمانت نہیں۔ - Idempotency: پارٹنرز کو
eventIdپر duplicate ہٹانا لازم ہے؛ SITP دوبارہ بھیج سکتا ہے۔ - Versioning:
dataبلاک ایکversionفیلڈ رکھتا ہے؛ ایک بڑی شکل کی تبدیلی ایک نئےversionکے طور پر parallel ترسیل کے ساتھ جاری ہوتی ہے جب تک پارٹنرز migrate نہ کر لیں۔
12.3 HMAC-signed payload نمونہ
POST https://partner.example.org/sitp/webhook
Content-Type: application/json
X-SITP-Event: ticket.status_changed
X-SITP-Signature: t=1752752322,v1=5b1c3729d4f8a2e6b0c1d9e7f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2
X-SITP-Delivery: dlv_01HZX9F8K7P4N2Q3R6STV8WXZ
X-Request-Id: req_01HZX9F8K7P4N2Q3R6STV8WXAD
{
"eventId": "evt_01HZX9F8K7P4N2Q3R6STV8WXAB",
"eventType": "ticket.status_changed",
"occurredAt": "2026-07-17T09:38:42.000Z",
"version": "1",
"data": {
"ticketId": "SITP-2026-SRB-000128",
"companyId": "cmp_01HZX7K4P9N2Q3R6STV8WXYPJ",
"previousStatus": "new",
"status": "assigned",
"assignedTo": { "dept": "SRB", "section": "Refunds" },
"sla": { "responseBy": "2026-07-19T09:00:00Z" },
"portalUrl": "https://sindhitportal.maahir.io/tickets/SITP-2026-SRB-000128"
},
"delivery": { "deliveryId": "dlv_01HZX9F8K7P4N2Q3R6STV8WXZ", "attempt": 1 }
}
Verify کرنے کا pseudocode (پارٹنر طرف):
t, v1 = parse(X-SITP-Signature) # "1752752322", "5b1c..."
if abs(now() - t) > 300: reject # replay window
expected = HMAC_SHA256(secret, t + "." + raw_request_body)
if not constant_time_eq(expected, v1): reject
event = JSON.parse(raw_request_body)
if seen(event.eventId): ignore # idempotency
handle(event)
دستخط SITP کے ذریعے HMAC_SHA256(secret, "<t>.<rawRequestBody>") کے طور پر compute ہوتا ہے اور v1 کے طور پر hex-encode ہوتا ہے۔
13. SDK اور Codegen منصوبہ
SITP کی OpenAPI 3.1 دستاویز کلائنٹ SDK پیدا کرنے کا واحد input ہے۔ منصوبہ:
| چینل | جنریٹر | آؤٹ پٹ | حیثیت |
|---|---|---|---|
| TypeScript / browser | openapi-typescript + openapi-fetch |
Type-safe fetch کلائنٹ جو Next.js پورٹل استعمال کرتا ہے۔ | Phase 1۔ |
| TypeScript / Node | @hey-api/openapi-ts (یا openapi-generator-cli typescript-axios) |
پارٹنر SDK جو private npm scope پر شائع ہو۔ | Phase 1۔ |
| Python | openapi-generator-cli python |
پارٹنر SDK (PyPI) — تحقیق/ڈیٹا پارٹنرز کی ترجیح۔ | Phase 2۔ |
| React Native | TS کلائنٹ کو دوبارہ استعمال۔ | — | Phase 4۔ |
| Postman / Bruno | OpenAPI سے auto-پیدا کردہ collection۔ | پارٹنر آن بورڈنگ پیک۔ | Phase 1۔ |
| Mock server | OpenAPI دستاویز سے prism (Stoplight)۔ |
سینڈ باکس معاہدہ ٹیسٹنگ (§15)۔ | Phase 1۔ |
ضابطے:
- پیدا کردہ، کبھی ہاتھ سے نہیں لکھا۔ SDKs ہر معاہدے کی تبدیلی پر
openapi.jsonسے دوبارہ پیدا ہوتے ہیں؛ دستی ترامیم ممنوع ہیں۔ - مستحکم میتھڈ نام۔ OpenAPI دستاویز میں
operationIdکو ایک عوامی symbol سمجھا جاتا ہے اور صرف میجر ورژن کے پار بدلا جاتا ہے۔ - Versioning۔ SDK پیکیجز آزادانہ طور پر versioned ہوتے ہیں اور ایک میجر API ورژن کو pin کرتے ہیں (
sitp-sdk-ts@^1↔ APIv1)۔ - Bundled ماڈلز۔ Request/response اقسام bundled ہیں تاکہ پارٹنرز کو compile-time تحفظ ملے۔
- Retry اور idempotency built in۔ سرکاری SDKs تحریروں کے لیے خود
Idempotency-Keyتیار کرتے ہیں اور 5xx/429 پر idempotently exponential backoff (capped) کے ساتھ دوبارہ کوشش کرتے ہیں — پارٹنرز یہ خود لاگو نہیں کرتے۔
14. Deprecation پالیسی
14.1 Lifecycle
ہر API عنصر (endپوائنٹ، فیلڈ، پیرامیٹر، enum قدر، واقعہ) ان مراحل سے گزرتا ہے:
experimental → current → deprecated → sunset → removed
- experimental: ایک feature flag کے پیچھے، بغیر اطلاع کے بدل سکتا ہے؛ OpenAPI میں بطور
x-sitp-experimental: trueدستاویز ہے۔ پارٹنرز کو ان پر انحصار نہیں کرنا چاہیے۔ - current: مستحکم، versioning ضمانت کے تحت۔
- deprecated: ابھی functional؛ ایک ہٹانے کی تاریخ کا اعلان کرتا ہے۔ ہر متاثرہ جواب پر
DeprecationاورSunsetHTTP response ہیڈرز (RFC 8594 / RFC 9745) شامل کرتا ہے، اور OpenAPI دستاویز اسےdeprecated: truemark کرتی ہے۔ - sunset: معیاری
Sunsetہیڈر ہٹانے کی تاریخ کے ساتھ لوٹاتا ہے؛ کالیں کامیاب ہوتی ہیں مگر telemetry کے لیے log ہوتی ہیں۔ - removed: کسی endپوائنٹ پر
SITP-NOTFOUND-001(404) لوٹاتا ہے، یا فیلڈ جوابات سے غیر موجود ہوتا ہے۔
14.2 کیا توڑنے والی ہے (نیا میجر لازمی)
- کسی endپوائنٹ، فیلڈ، پیرامیٹر، یا enum قدر کو ہٹانا یا نام بدلنا۔
- کسی فیلڈ کی قسم، nullability، یا semantics بدلنا۔
- ڈیفالٹ رویہ بدلنا جس پر کلائنٹ انحصار کرتے ہیں۔
- اسٹیٹس کوڈ یا نقص
codeبدلنا۔ - Paginated
limitmaximum کو تنگ کرنا۔
14.3 کیا غیر توڑنے والی ہے (in-version جاری)
- نیا endپوائنٹ، فیلڈ، پیرامیٹر، یا enum قدر شامل کرنا (کلائنٹس کو unknowns نظر انداز کرنے چاہئیں)۔
- نیا اختیاری request فیلڈ شامل کرنا۔
- validation ڈھیلا کرنا (مثلاً، max length بڑھانا)۔
- JSON آبجیکٹ میں فیلڈز کی ترتیب بدلنا (کلائنٹس key order پر انحصار نہیں کرنے چاہئیں)۔
14.4 Timelines
- ایک deprecated عنصر deprecated کے اعلان سے کم از کم 12 ماہ تک معاون رہتا ہے اس سے پہلے کہ اسے ہٹایا جا سکے (اور صرف نئے میجر ورژن میں)۔
- پچھلا میجر ورژن اگلے میجر کے جاری ہونے کے بعد کم از کم 12 ماہ parallel run کے لیے معاون ہے۔
- Deprecation کے اعلانات رجسٹرڈ پارٹنرز کو ای میل کیے جاتے ہیں،
/docs/api/changelogپر شائع ہوتے ہیں، اور پارٹنر ڈیش بورڈ میں ظاہر ہوتے ہیں۔
15. سینڈ باکس اور ٹیسٹ ماحول
ایک مخصوص Sینڈ باکس ماحول پارٹنرز کو پروڈکشن ڈیٹا کو چھوئے بغیر بنانے اور ٹیسٹ کرنے کی سہولت دیتا ہے۔
| پہلو | سینڈ باکس | پروڈکشن |
|---|---|---|
| بیس URL | https://sandbox.sindhitportal.maahir.io/api/v1 |
https://sindhitportal.maahir.io/api/v1 |
| ڈیٹا | الگ ڈیٹا بیس؛ synthetic کمپنیوں، ٹکٹس، محکموں سے seeded۔ | حقیقی۔ |
| Integrations | Mocked۔ NADRA/SECP/FBR/SRB/PSEB canned جوابات لوٹاتے ہیں (ایڈاپٹر mock موڈ کے مطابق)۔ Mailjet/SMS/WhatsApp ایک اندرونی mailbox کی طرف divert ہوتے ہیں — سینڈ باکس سے کوئی حقیقی ای میل/SMS نہیں نکلتا۔ | Live۔ |
| ٹوکنز | Self-service پارٹنر کنسول؛ client secrets آزادی سے rotated۔ | Vetted۔ |
| ریٹ لمٹس | وہی درجے، کم ceilings (tunable)۔ | §4.1 کے مطابق۔ |
| ویب ہوکس | پارٹنر endپوائنٹس سینڈ باکس سے واقعات وصول کرتے ہیں؛ پارٹنرز offline معاہدہ ٹیسٹنگ کے لیے mock server (prism) بھی استعمال کر سکتے ہیں۔ |
Live۔ |
| OpenAPI | سینڈ باکس host پر /api/v1/openapi.json۔ |
/api/v1/openapi.json۔ |
15.1 ٹیسٹ ڈیٹا
- Synthetic تنظیمیں معلوم
companyIds (cmp_test_*) جو سینڈ باکس آن بورڈنگ پیک میں دستاویز ہیں۔ - Synthetic CNICs/NTNs جو قابلِ پیش بینش mock نتائج لوٹاتے ہیں (مثلاً،
active،not-found،cancelled) تاکہ پارٹنرز ہر تصدیقی branch کو استعمال کر سکیں۔ - ایک reset endپوائنٹ (
POST /sandbox/reset) repeatable ٹیسٹس کے لیے seed ڈیٹا سیٹ بحال کرتا ہے۔ پروڈکشن میں ایسا کوئی endپوائنٹ نہیں۔
15.2 معاہدہ ٹیسٹنگ
- ہری release OpenAPI دستاویز کو live سینڈ باکس کے خلاف
prismکا استعمال کر کے چلاتی ہے تاکہ verify ہو کہ implementation معاہدے سے مطابقت رکھتی ہے۔ - اس دستاویز میں پارٹنر کے سامنے کی مثالیں ایک CI job کے ذریعے validate ہوتی ہیں جو انہیں ہر تبدیلی پر سینڈ باکس کے خلاف دوبارہ چلاتی ہے۔
16. مشاودہ پذیری — corelation IDs
ہر درخواست — کامیاب یا ناکام — ایک corelation آئی ڈی کے ذریعے end-to-end قابلِ سراغ ہے۔
| ہیڈر | سمت | مقصد |
|---|---|---|
X-Request-Id |
In (optional) / Out (ہمیشہ) | کلائنٹ کی فراہم کردہ یا SITP کا پیدا کردہ؛ جواب پر echoed اور ہر log لائن، OTel span، اور audit_logs.request_id میں thread کیا (/specs/ur/05-data-model/ §3.10 کے مطابق)۔ |
X-Correlation-Id |
In (optional) / Out (اگر دی گئی) | ایک upstream آئی ڈی carry کرتا ہے جب SITP خود کسی اور نظام (مثلاً، ایک والد حکومتی پورٹل) کے ذریعے کالا جائے۔ |
Traceparent (W3C) |
In/Out | معیاری W3C trace context؛ SITP ایک OTel participant ہے اور trace کو انضمام ایڈاپٹرز تک propagate کرتا ہے (/specs/ur/08-integrations-spec/ §11 میں NFR-INT-008 کے مطابق)۔ |
روےہ:
- اگر کلائنٹ
X-Request-Idبھیجے تو SITP اسے validate کرتا ہے (UUID یاreq_<ulid>شکل) اور دوبارہ استعمال کرتا ہے؛ بصورت دیگر SITP ایک تیار کرتا ہے (req_<ulid>)۔ - آئی ڈی ظاہر ہوتا ہے: HTTP response ہیڈر میں، لفافے کے
meta.requestIdفیلڈ میں، نقائص پر RFC 7807 کےrequestIdفیلڈ میں، ہر structured log لائن میں، ہر OTel span میں،audit_logs.request_idکالم میں، اور درخواست سے ٹرگر ہونے والے انضمام کالز کے لیے ہرint_callقطار میں۔ - پارٹنرز کے ذریعہ support ٹکٹ میں آئی ڈی quote کرنے سے SITP کو Grafana/Loki میں مکمل درخواست trace چند سیکنڈوں میں مل جاتا ہے۔
- PII آئی ڈی یا log tags میں کبھی نہیں رکھی جاتی؛ صرف opaque شناخت کنندے اور outcome کوڈز log ہوتے ہیں (
/specs/ur/11-security-compliance/کے مطابق)۔
17. درخواست Lifecycle (end-to-end)
ڈایاگرام ایک واحد تصدیق شدہ تحریر — POST /tickets — کا مکمل lifecycle دکھاتا ہے، پارٹنر کی HTTP کال سے ہر cross-cutting تشویش کے ذریعے آخری جواب تک۔
تحریری وضاحت۔ ایک پارٹنر POST /tickets ایک Authorization bearer، ایک Idempotency-Key، اور (اختیاری طور پر) ایک X-Request-Id کے ساتھ جاری کرتا ہے۔ nginx گیٹ وے کال forward کرتا ہے، اور کوئی traceparent موجود نہ ہو تو W3C traceparent تیار کرتا ہے۔ NestJS کے اندر، cross-cutting middleware chain ایک مقرر ترتیب میں چلتا ہے: CORS → rate limit → authentication → authorization (scope/role) → idempotency lookup → request validation → audit/OTel span open۔ کوئی بھی ناکامی اصل X-Request-Id رکھنے والے RFC 7807 problem دستاویز کے ساتھ short-circuit ہو جاتی ہے۔ اگر idempotency کلید 24 گھنٹوں کے اندر دیکھی گئی ہو اور payload مطابقت رکھتا ہو، تو اصل جواب verbatim دوبارہ چلایا جاتا ہے اور کوئی ڈومین کام نہیں چلتا۔ cache miss پر، کنٹرولر validated DTO کو TicketsService کے حوالے کرتا ہے، جو ایک MariaDB ٹرانزیکشن کھولتا ہے، SITP-YYYY-DEPT-NNNNNN ٹریکنگ آئی ڈی پیدا کرتا ہے، ٹکٹ insert کرتا ہے، ایک ticket_history قطار اور ایک audit_logs قطار لکھتا ہے، اور side-effects (SLA کلاک start، notifications، اختیاری e-Office فائل push، registry تصدیقی jobs) کو BullMQ میں enqueue کرتا ہے — یہ ٹرانزیکشن commit ہونے کے بعد چلتے ہیں تاکہ جواب کبھی بیرونی latency سے block نہ ہو۔ ٹرانزیکشن commit ہوتا ہے، کنٹرولر نیا ٹکٹ {data, meta, links} لفافے میں لپیٹتا ہے، middleware ریٹ لمٹ اور version ہیڈرز attach کرتا ہے، اور گیٹ وے نیے وسیلے کی طرف اشارہ کرتے ہوئے Location ہیڈر کے ساتھ 201 Created لوٹاتا ہے۔ اس دوران، BullMQ workers fan out ہوتے ہیں: notifications communications ایڈاپٹرز کے ذریعے بھیجے جاتے ہیں، ticket.created ویب ہوک HMAC-signed اور deliver (اور §12.2 کے مطابق retry) ہوتا ہے، اور SLA کلاک محکمے کے کاروباری اوقات کے اندر چلنا شروع ہوتا ہے۔ ہر قدم — گیٹ وے، middleware، ڈومین، انضمام، قطار — ایک OTel span emit کرتا ہے جو اسی X-Request-Id کے ساتھ tag ہے، اس لیے پارٹنر کے آئی ڈی report کرنے سے ops کو Grafana/Loki میں پورا trace reconsruct مل جاتا ہے۔
18. کھلے سوالات / TBD
| # | شے | حیثیت |
|---|---|---|
| 1 | Premium پارٹنر درجہ ceilings اور تجارتی شرائط۔ | TBD (procurement)۔ |
| 2 | آیا سینڈ باکس high-trust flows کی ٹیسٹنگ کے لیے synthetic NADRA بائیو میٹرک ٹوکنز بے نقاب کرے۔ | NADRA mock spec کے ساتھ TBD۔ |
| 3 | TS اور Python کے علاوہ final SDK زبانیں (Go؟ Java؟)۔ | TBD (پارٹنر طلب)۔ |
| 4 | Analytics-heavy پارٹنرز کے لیے GraphQL facet، یا صرف REST۔ | TBD (Phase 2 evaluation)۔ |
| 5 | عوامی read API کلید پروگرام (صرف پڑھنے کے عوامی ڈیٹا صارفین کے لیے OAuth کا ہلکا متبادل)۔ | TBD۔ |
| 6 | آیا POST /sandbox/reset تمام پارٹنرز کو بے نقاب ہو یا gated۔ |
TBD۔ |
| 7 | NestJS ↔ AI مائکروسروس boundary کے لیے gRPC / protobuf اندرونی معاہدہ (اس عوامی REST دستاویز کے دائرہ کار سے باہر)۔ | /specs/ur/15-tech-architecture/ دیکھیں۔ |
دستاویز کا اختتام۔