معماری چندکسبوکاری، تجاری و تجارت الکترونیک · فصل ۷ — Connector، Order، Packing، Barcode، Carrier و Notification · 270
Custom Connector Architecture
workflow تجاری را به UI یا integration منفرد تقلیل میدهد و state، rights، approval و measurement را یکپارچه نمیکند. موضوع جاری: «Custom Connector Architecture». میتواند «Custom Connector Architecture» را برای یک workflow محدود با state/contract/approval و verification مناسب طراحی کند.
خلاصهٔ درس
workflow تجاری را به UI یا integration منفرد تقلیل میدهد و state، rights، approval و measurement را یکپارچه نمیکند. موضوع جاری: «Custom Connector Architecture».
میتواند «Custom Connector Architecture» را برای یک workflow محدود با state/contract/approval و verification مناسب طراحی کند.
خروجی این درس
میتواند «Custom Connector Architecture» را برای یک workflow محدود با state/contract/approval و verification مناسب طراحی کند.
وقتی connector از «چند endpoint» به یک تودهی غیرقابلتشخیص تبدیل میشود
فرض کن provider پاسخ 200 داده، اما connection قبل از دریافت body قطع شده است. چند ثانیه بعد webhook همان عملیات میرسد، و همزمان provider یک فیلد پاسخ را deprecated کرده است. اگر transport، auth، schema، retry، webhook و business mapping در یک تابع مخلوط شده باشند، دیگر نمیتوانی جواب بدهی: آیا write واقعاً انجام شد؟ retry امن است؟ webhook تکراری است؟ تغییر schema فقط adapter را میشکند یا domain داخلی را هم؟
خروجی این درس Custom Connector Boundary and Contract Matrix v1 است. هر تصمیم باید از قرارداد provider تا promotion به canonical domain قابل بازسازی باشد؛ بدون secret واقعی، tenant واقعی یا hidden reasoning.
مرز مالکیت COM-029
COM-029 مالک معماری connector، لایههای contract و failure boundary است. COM-028 integration مشخص WooCommerce را مالک است و COM-030 canonical Order State Machine را. این درس نه vendor status را state داخلی اعلام میکند و نه success HTTP را permission برای تغییر business state میداند.
سه خط قرمز:
API description != runtime guaranteeprovider payload != canonical domaintimeout != safe retry
مدل ذهنی: Provider contract → Transport/Auth → Schemas → Events → Retry/Rate limit → Adapter mapping → Canonical promotion → Reconciliation
مسیر قابلممیزی:
provider contract/version → base URL + scoped auth → request/response schema → webhook/callback semantics → event identity → idempotency/retry/backoff/rate limit → mapping adapter/version → canonical command/event → reconciliation → evidence
هر لایه باید failure خودش را داشته باشد. اگر auth scope مشکل دارد، mapping را متهم نکن. اگر schema drift کرده، domain model را بیصدا عوض نکن. اگر write timeout شده، نتیجه را قبل از reconciliation «failed» یا «success» فرض نکن.
FACT، INFERENCE و DESIGN را جدا نگه دار
FACT: OpenAPI Specification 3.2.1 در 10 سپتامبر 2026 منتشر شده و نسخهی جاری منتشرشدهی OAS است. OAS یک interface description مستقل از زبان برای HTTP APIها تعریف میکند.
FACT: در OAS 3.2.1، webhooks برای inbound requestهایی است که مستقل از یک API call دیگر رخ میدهند؛ callbacks به parent operation وابستهاند. توصیف این دو، delivery guarantee یا exactly-once semantics ایجاد نمیکند.
INFERENCE: وقتی contract، transport/auth، schema، delivery، retry/idempotency و mapping مستقل observable باشند، failure isolation و migration کمریسکتر میشود.
DESIGN: MAKNOW provider quirk را در adapter نگه میدارد، mapping را version میکند، write نامطمئن را reconcile میکند و تا evidence decisive کامل نشود canonical success صادر نمیکند. اینها design محلیاند، نه requirement خود OpenAPI.
قرارداد ۲۳بعدی Connector
| Case | Contract | Auth scope | Schema درخواست/پاسخ | Inbound | Event ID | Idempotency | Retry/backoff | Rate limit | Mapping | Reconcile | Deprecation | Decision |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| baseline_versioned | 2.4.0 | orders.read orders.write | req-v4/res-v7 | order.updated webhook v3 | event_id + provider_id | Idempotency-Key per logical write | retry transient network/5xx only / bounded exponential + jitter | 429 + Retry-After | map-v9 | GET-by-provider-id after uncertain write | ACTIVE | ACCEPT_CONTRACT |
| schema_drift | 2.4.0 | orders.read orders.write | req-v4/res-v8 | order.updated webhook v3 | event_id + provider_id | Idempotency-Key per logical write | retry transient network/5xx only / bounded exponential + jitter | 429 + Retry-After | map-v9 | GET-by-provider-id after uncertain write | ACTIVE | HOLD_MAPPING_VERSION |
| unsafe_retry | 2.4.0 | orders.write | req-v4/res-v7 | order.updated webhook v3 | event_id + provider_id | NONE | retry timeout blindly / fixed 100ms | 429 + Retry-After | map-v9 | NONE | ACTIVE | HOLD_IDEMPOTENCY_GAP |
| transfer_webhook | 3.0.0 | orders.read orders.write webhooks.verify | req-v4/res-v8 | order.updated webhook v4; signature verified | event_id + provider_id | event ledger + write key | bounded transient retries / bounded exponential + jitter | 429 + Retry-After | map-v10 | event ledger + GET snapshot | CALLBACK_DEPRECATED | ACCEPT_CONTRACT |
Gate 1 — Connector و Provider را هویتدار کن
connector_id و provider_id اجازه میدهند failure و migration را به نمونهی مشخص وصل کنی. «API خارجی» یک identity کافی نیست.
Gate 2 — Contract version را مستقل از implementation version ثبت کن
contract_version مرز سازگاری provider را نشان میدهد. تغییر contract بدون ثبت version یعنی نمیتوانی بفهمی کدام mapping و test معتبر بودهاند.
Gate 3 — OpenAPI ref evidence است، نه تضمین رفتار
openapi_ref نشان میدهد چه interfaceای توصیف شده؛ اما runtime behavior، semantic compatibility، latency و delivery guarantee را ثابت نمیکند.
Gate 4 — Base URL و credential باید reference باشند، نه secret داخل package
base_url_ref و credential_scope باید قابلردیابی باشند ولی credential واقعی نباید در artifact آموزشی/connector contract embed شود.
Gate 5 — Auth scheme بدون scope کافی نیست
دانستن OAuth/API key نوع credential را میگوید، نه اینکه این credential مجاز به همان operation باشد. scope کم یا مبهم → HOLD_AUTH_SCOPE.
Gate 6 — Request و Response schema را جدا version کن
provider ممکن است response field را deprecate کند بدون اینکه request تغییر کند. اگر response_schema_version عوض شد ولی mapping_version ثابت ماند، promotion باید متوقف شود.
Gate 7 — Webhook و Callback را یکی نکن
Callback به parent operation وابسته است؛ webhook میتواند مستقل وارد شود. مهاجرت callback→webhook معمولاً endpoint rename ساده نیست: identity، verification، replay/retry و lifecycle ممکن است عوض شوند.
Gate 8 — Inbound event باید identity قابلdedupe داشته باشد
بدون event_identity نمیتوان retry provider، replay یا duplicate delivery را از event جدید جدا کرد. «provider گفت webhook است» exactly-once نیست.
Gate 9 — Retryable write به idempotency یا reconciliation نیاز دارد
برای writeای که timeout شده، blind retry میتواند اثر را دو بار بسازد. اگر idempotency key پشتیبانی نمیشود، باید reconciliation بتواند effect قبلی را پیدا کند.
Gate 10 — Backoff باید rate-limit signal را بفهمد
429، Retry-After یا signal معادل باید policy را کنترل کند. retry loop سریع و ثابت هم provider را تشدید میکند و هم outage را طولانیتر.
Gate 11 — Provider quirk داخل mapping adapter میماند
status یا field نام provider نباید مستقیم وارد canonical domain شود. adapter آن را به canonical_command_or_event نگاشت میکند و version خودش را دارد.
Gate 12 — Reconciliation قبل از promotion نامطمئن
اگر response قطع شد، webhook دیر رسید یا event order مبهم شد، reconciliation_strategy تعیین میکند با چه evidenceای external effect به canonical truth تبدیل میشود.
Gate 13 — Deprecation یک state عملیاتی است
deprecation_state باید ACTIVE/DEPRECATED/REMOVAL_DATE یا state صریح مشابه داشته باشد. فیلد deprecated نباید تا روز حذف «نامرئی» بماند.
Gate 14 — Missing decisive evidence باید fail-closed باشد
اگر version، auth scope، event identity، mapping version یا reconciliation ناقص است، HOLD_* مناسب صادر کن؛ dashboard تمیز مهمتر از boundary درست نیست.
مثالهای حلشده
1. Baseline versioned connector → ACCEPT_CONTRACT
Contract، schemaها، scoped auth، event identity، idempotency، backoff، mapping version و reconciliation همگی evidence دارند. canonical interface میتواند با confidence محدود پذیرفته شود.
2. Response res-v7 → res-v8 ولی map-v9 ثابت → HOLD_MAPPING_VERSION
حتی اگر parser crash نکند، semantic mapping دیگر اثبات نشده است. ابتدا impact را بررسی و mapping contract را version کن.
3. POST timeout + blind retry + no idempotency/reconcile → HOLD_IDEMPOTENCY_GAP
Timeout نمیگوید اثر خارجی انجام نشده. بدون write identity یا reconciliation، retry میتواند duplicate effect بسازد.
4. Provider status مستقیم وارد Order domain → HOLD_PROVIDER_LEAKAGE
Provider-specific vocabulary باید داخل adapter بماند. Canonical domain فقط command/event خودش را میبیند.
5. Webhook بدون event identity با فرض exactly-once → HOLD_EVENT_IDENTITY
Delivery type بهتنهایی uniqueness نمیسازد. replay و duplicate باید طراحیشده باشند.
6. Transfer: callback حذف، webhook v4 اضافه، response field deprecated
contract_version و mapping_version bump میشوند، webhook verification و event identity صریح میشوند، callback به deprecated میرود؛ اما canonical_command_or_event اگر semantic meaning ثابت است بدون تغییر باقی میماند.
Failure modeهای رایج
- یک client class که auth، retry، mapping و business mutation را با هم انجام میدهد؛
- OpenAPI-valid را معادل semantically-compatible دانستن؛
- embedding secret داخل config/package؛
- auth scheme بدون credential scope؛
- schema change بدون mapping-version bump؛
- webhook را exactly-once فرض کردن؛
- blind retry روی write timeout؛
- ignore کردن
Retry-Afterیا rate-limit signal؛ - provider status leakage به canonical model؛
- success code را canonical completion دانستن؛
- deprecation بدون owner/removal plan؛
- transfer با copy کردن تصمیم baseline بدون recompute.
Alternatives و trade-offها
Endpoint glue: شروع سریع، اما failure boundaries و migration سخت.
Generated client from OpenAPI: برای transport/types بسیار مفید است، اما semantic mapping، retry safety، event identity و reconciliation را بهتنهایی حل نمیکند.
Unified provider model: کد consumer را ساده میکند، اما اگر lowest-common-denominator شود featureهای provider را پنهان میکند. adapter باید loss را صریح کند.
Event-driven only: latency خوب برای inbound changes، ولی بدون pull/reconcile ممکن است missed/replayed events کشف نشوند.
Layered connector + canonical boundary: کمی قرارداد و instrumentation بیشتر میخواهد، اما failure isolation، migration و auditability بهتر میدهد. این pattern محدود این درس است.
Experienced bridge: شانزده سؤال review
- connector/provider identity چیست؟
- contract version کجاست؟
- OpenAPI ref به چه نسخهای اشاره دارد؟
- base URL و secret چگونه reference شدهاند؟
- auth scope دقیقاً همان operation را پوشش میدهد؟
- request/response schema مستقل version شدهاند؟
- inbound flow webhook است یا callback و چرا؟
- event identity چیست؟
- duplicate/replay چگونه تشخیص داده میشود؟
- write timeout با چه idempotency/reconciliation policy بسته میشود؟
- retry policy چه failureهایی را retry میکند؟
- rate-limit signal چگونه backoff را تغییر میدهد؟
- mapping version چه زمانی bump میشود؟
- provider-specific vocabulary کجا متوقف میشود؟
- deprecation چه owner و removal plan دارد؟
- آیا canonical promotion فقط از evidence قابلبازسازی است؟
تمرین هدایتشده و مستقل
Lab آفلاین ۸ fixture دارد: baseline، schema drift، unsafe timeout retry، provider leakage، webhook بدون identity، auth scope ناقص، rate-limit بدون backoff و transfer callback→webhook.
تمرین مستقل: provider فیلد legacy_status را deprecated و status_code را جایگزین میکند؛ callback قدیمی را هم حذف و webhook جدید اضافه میکند. Contract را طوری update کن که adapter mapping تغییر کند، event identity و verification صریح شوند و canonical event interface بدون نیاز واقعی تغییر نکند.
Verification evidence
Artifact پذیرفتنی همهی ۲۳ بُعد را پر میکند یا یک non-success state صریح میدهد. هیچ secret واقعی داخل package نیست؛ schema/mapping version coherence قابلبررسی است؛ unsafe retry fail-closed میشود؛ provider vocabulary قبل از canonical boundary متوقف میشود؛ deprecation و reconciliation قابلردیابیاند؛ و transfer فقط affected layers را تغییر میدهد.
Lab کاملاً synthetic و offline است؛ API key، network، store واقعی یا customer data لازم ندارد.
Assessment و transfer
برای پایان درس باید بتوانی:
- مرز COM-029 را در برابر COM-028 و COM-030 توضیح بدهی؛
- Custom Connector Boundary and Contract Matrix v1 را بسازی؛
- OpenAPI description را از runtime guarantee جدا کنی؛
- webhook و callback را درست تفکیک کنی؛
- unsafe timeout retry را رد کنی؛
- schema drift بدون mapping bump را fail-closed کنی؛
- provider field/status را پشت adapter نگه داری؛
- transfer callback→webhook + deprecation را بدون شکستن canonical interface بازطراحی کنی.
منابع و freshness
- OpenAPI Specification 3.2.1 — منتشرشده 10 سپتامبر 2026؛ rechecked در 15 سپتامبر 2026. مرجع FACT برای interface description، webhooks و callbacks.
- Bible فریزشدهی COM-029 در 3 سپتامبر 2026 نسخه 3.2.0 را current ثبت کرده بود؛ bytes Bible تغییر نکرده و freshness overlay فقط FACT خارجی را به 3.2.1 بهروز کرده است.
- Layer boundaries، typed HOLD states، retry/reconciliation policy و canonical promotion در این درس MAKNOW DESIGN هستند و به OpenAPI نسبت داده نمیشوند.
ارزیابی
پاسخنامهی این درس در بستهی آموزش وجود ندارد؛ خودت جواب بده و صادقانه علامت بزن. «نیاز به مرور» درس را به صف تکرار میفرستد.
COM-029-S1 retrieval
Explain what COM-029 owns and one adjacent non-goal.
COM-029-S2 application
Build Custom Connector Boundary and Contract Matrix v1 for the baseline fixture.
COM-029-S3 diagnosis
Response schema changes without mapping-version bump. Diagnose the invalidated boundary and repair.
COM-029-S4 transfer
Replace a callback with a webhook and deprecate one response field. Update affected connector layers while preserving unchanged canonical interfaces.
ملاکهای ارزیابی (rubric)
Blocking dimensions:
- boundary ownership is explicit;
- version/schema/mapping evidence is complete or typed HOLD is emitted;
- unsafe retry and duplicate-delivery assumptions are rejected;
- provider vocabulary does not leak across the adapter boundary;
- transfer is recomputed from changed evidence;
- final decision is reproducible without hidden reasoning.
منابع و تازگی
مطالعهٔ موارد (case studies)
تصاویر درس
فایلهای آزمایشگاه
python run_checks.py را اجرا کنید. هشت fixture مصنوعی coherence نسخه، auth scope، هویت webhook، retry/idempotency، rate-limit/backoff، provider leakage و انتقال callback→webhook را میسنجند. هیچ شبکه یا credential واقعی لازم نیست.