معماری چندکسبوکاری، تجاری و تجارت الکترونیک · فصل ۷ — Connector، Order، Packing، Barcode، Carrier و Notification · 276
End-customer Notifications با Minimal PII
workflow تجاری را به UI یا integration منفرد تقلیل میدهد و state، rights، approval و measurement را یکپارچه نمیکند. موضوع جاری: «End-customer Notifications با Minimal PII». میتواند «End-customer Notifications با Minimal PII» را برای یک workflow محدود با state/contract/approval و verification مناسب طراحی کند.
خلاصهٔ درس
workflow تجاری را به UI یا integration منفرد تقلیل میدهد و state، rights، approval و measurement را یکپارچه نمیکند. موضوع جاری: «End-customer Notifications با Minimal PII».
میتواند «End-customer Notifications با Minimal PII» را برای یک workflow محدود با state/contract/approval و verification مناسب طراحی کند.
خروجی این درس
میتواند «End-customer Notifications با Minimal PII» را برای یک workflow محدود با state/contract/approval و verification مناسب طراحی کند.
مسئلهی واقعی: برای یک پیام کوتاه چرا کل customer/order object را میفرستیم؟
سفارش ارسال شده و سیستم میخواهد به مشتری اطلاع بدهد. object اصلی شامل نام کامل، آدرس دقیق، تلفن، یادداشت داخلی، شناسههای عملیاتی و raw carrier payload است. اما خود پیام فقط به یک مقصد معتبر، یک order reference محدود، وضعیت نرمالشده و در صورت مجاز بودن یک لینک امن نیاز دارد. اگر همان object غنی را وارد template کنیم، سطح افشای PII و coupling بالا میرود؛ اگر provider فقط پیام را accept کند و ما آن را DELIVERED ثبت کنیم، علاوه بر privacy، truth delivery را هم خراب کردهایم.
هدف این درس ساخت Minimal-PII Notification Projection and Delivery Contract v1 است: projection کوچک و purpose-specific، routing جدا از business truth، redaction و template versioned، delivery ledger صریح، retry محدود و retention قابلممیزی.
مرز درس
COM-035 مالک notification projection و delivery evidence است. COM-034 مالک carrier event normalization/truth است؛ COM-036 مالک قابلیت PWA/web push است. این درس از carrier truth استفاده میکند اما آن را تولید نمیکند، و از push بهعنوان یک channel استفاده میکند اما availability پلتفرم را اثبات نمیکند.
سه مرز سخت:
- رضایت مشتری به دریافت سرویس یا داشتن سفارش، مجوز کپیکردن هر دادهای در هر پیام نیست.
provider acceptedمساویcustomer deliveredنیست.- retention یا consent خاص یک vendor را قانون عمومی پروژه اعلام نمیکنیم.
مدل ذهنی: Event → Purpose → Recipient → Minimal Projection → Render → Provider → Delivery Ledger → Retention
| notification_id | event_trigger | purpose_code | message_class | recipient_ref | recipient_channel | recipient_destination_masked | authorization_or_basis_ref | minimal_field_set | redaction_policy_version | template_id | template_version | locale | tracking_link_policy | provider_message_id | queued_at | provider_accepted_at | delivery_event_at | delivery_status | failure_code | retention_until_or_class | owner_ref | evidence_ref |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| N1 | SHIPMENT_IN_TRANSIT | SHIPMENT_STATUS | TRANSACTIONAL | CUST-7 | SMS | --4821 | POL-TXN-1 | order_ref_fragment;normalized_status;safe_tracking_link | redact-v3 | ship-status-sms | v5 | fa-IR | SAFE_REDIRECT_ONLY | NONE | 2026-09-14T18:00Z | NONE | NONE | QUEUED | NONE | TXN-LEDGER-30D | NOTIF-OPS | E-N1 |
| N2 | SHIPMENT_IN_TRANSIT | SHIPMENT_STATUS | TRANSACTIONAL | CUST-7 | SMS | --4821 | POL-TXN-1 | order_ref_fragment;normalized_status;safe_tracking_link | redact-v3 | ship-status-sms | v5 | fa-IR | SAFE_REDIRECT_ONLY | P-992 | 2026-09-14T18:00Z | 2026-09-14T18:00:02Z | NONE | PROVIDER_ACCEPTED | NONE | TXN-LEDGER-30D | NOTIF-OPS | E-N2 |
| N3 | SHIPMENT_IN_TRANSIT | SHIPMENT_STATUS | TRANSACTIONAL | CUST-7 | SMS | --4821 | POL-TXN-1 | order_ref_fragment;normalized_status;safe_tracking_link;full_address;internal_note | redact-v3 | ship-status-sms | v5 | fa-IR | SAFE_REDIRECT_ONLY | NONE | NONE | NONE | NONE | BLOCKED | UNNECESSARY_PII | TXN-LEDGER-30D | NOTIF-OPS | E-N3 |
| N4 | SHIPMENT_IN_TRANSIT | SHIPMENT_STATUS | TRANSACTIONAL | CUST-7 | m***@example.com | POL-TXN-1 | order_ref_fragment;normalized_status;safe_tracking_link | redact-v3 | ship-status-email | v2 | en-US | SAFE_REDIRECT_ONLY | E-42 | 2026-09-14T18:10Z | 2026-09-14T18:10:01Z | 2026-09-14T18:10:04Z | DELIVERED | NONE | TXN-LEDGER-30D | NOTIF-OPS | E-N4 |
فلو:
canonical event → purpose gate → recipient authorization/routing → minimal projection + redaction → versioned template → provider adapter → delivery-event ledger → retention/erase gate
هر مرحله evidence خودش را دارد. carrier event business truth است؛ recipient route operational routing است؛ rendered message یک projection است؛ provider response فقط evidence همان provider stage است.
FACT، INFERENCE و DESIGN را قاطی نکن
FACT — Data minimisation. راهنمای رسمی کمیسیون اروپا میگوید دادهی شخصی باید متناسب، مرتبط و محدود به مقدار لازم برای purpose باشد؛ storage limitation هم نگهداری را به نیاز واقعی محدود میکند.
FACT — Privacy by design/default. safeguardها باید از ابتدا در طراحی باشند و default processing فقط دادهی لازم را با دسترسی و retention محدود پردازش کند.
FACT — Vendor boundary. DHL برای tracking data شروط خاص استفاده/ارسال و retention خودش را دارد. این شروط فقط برای همان provider/context authority هستند.
INFERENCE. اگر notification از projection کوچک و purpose-specific ساخته شود و route، render و delivery evidence جدا باشند، audit و کاهش exposure آسانتر میشود.
DESIGN — MAKNOW. fieldهای این Contract، stateهای delivery، retry rule، redaction version و fail-closed rules طراحی محلی هستند.
قرارداد ۲۳بعدی اعلان
هر notification record این fieldها را دارد:
notification_id, event_trigger, purpose_code, message_class, recipient_ref, recipient_channel, recipient_destination_masked, authorization_or_basis_ref, minimal_field_set, redaction_policy_version, template_id, template_version, locale, tracking_link_policy, provider_message_id, queued_at, provider_accepted_at, delivery_event_at, delivery_status, failure_code, retention_until_or_class, owner_ref, evidence_ref.
Gate 1 — قبل از template، Purpose را قفل کن
«shipment update» یک purpose است؛ «هر چیزی که درباره مشتری داریم» purpose نیست. purpose_code تعیین میکند چه fieldهایی واقعاً لازماند.
Gate 2 — Business truth را به Projection تبدیل کن
template نباید full order/customer/carrier object بگیرد. یک projector باید فقط fieldهای allowlisted را بسازد: مثلاً order_ref_fragment, normalized_status, safe_tracking_link. full_address, internal_note, raw_carrier_payload در این message class مجاز نیستند مگر purpose مشخص و evidence مستقل آن را لازم کند.
Gate 3 — Recipient routing را از customer truth جدا کن
recipient_ref میتواند canonical identity reference باشد، اما destination خروجی باید masked یا tokenized evidence داشته باشد. raw email/phone را در ledger عمومی یا content artifact تکثیر نکن.
Gate 4 — Basis/authorization را explicit نگه دار
authorization_or_basis_ref باید به policy/contract/consent/context معتبر اشاره کند. این درس خودش lawful basis حقوقی تعیین نمیکند. اگر basis لازم است و evidence نداریم، HOLD.
Gate 5 — Redaction و Template باید version داشته باشند
بدون redaction_policy_version و template_version نمیتوان بازسازی کرد چه دادهای با چه متن و چه ruleی ارسال شده. template change یک تغییر audit-relevant است.
Gate 6 — Tracking link را raw payload نکن
notification میتواند safe link یا normalized status داشته باشد، اما raw provider response، internal route data یا provider-only identifiers را به content customer-facing هل نده.
Gate 7 — QUEUED، ACCEPTED و DELIVERED سه state متفاوتاند
QUEUED: ما کار را برای provider صف کردهایم. PROVIDER_ACCEPTED: provider request را پذیرفته/ID داده است. DELIVERED: delivery event معتبر داریم. نبود delivery receipt یعنی DELIVERED را حدس نمیزنیم.
Gate 8 — Failure و Retry را bounded کن
Transient failure میتواند RETRY_ALLOWED بدهد، اما فقط وقتی message قبلاً delivered نشده، idempotency evidence داریم و سقف retry مشخص است. retry کور میتواند duplicate notification بسازد.
Gate 9 — Retention را field کن، نه حافظهی تیم
retention_until_or_class باید مشخص کند ledger/projection طبق چه کلاس محلی نگهداری یا پاک میشود. retention vendor-specific را فقط در همان boundary اعمال کن.
Gate 10 — Missing decisive evidence = fail closed
مقصد نامعتبر، basis مفقود، template version نامعلوم، retention نامعلوم یا recipient mismatch را با pressure عملیاتی به green تبدیل نکن. HOLD یا BLOCKED stateهای سالماند.
مثالهای حلشده
1. Shipment SMS با projection مینیمال → QUEUED
Purpose=SHIPMENT_STATUS; field set فقط reference fragment + normalized status + safe link؛ مقصد masked؛ basis ref حاضر؛ template/redaction version مشخص. هنوز provider response نداریم، پس state QUEUED است.
2. Provider accepted ولی receipt نداریم → PROVIDER_ACCEPTED
Provider message ID و accepted timestamp داریم اما delivery_event_at خالی است. این evidence برای DELIVERED کافی نیست.
3. Projection over-complete → BLOCKED، سپس Repair
نسخهی اول full_address و internal_note را هم حمل میکند؛ برای purpose لازم نیستند، پس BLOCKED. با حذف آنها function اصلی از بین نمیرود و projection قابل ارسال میشود.
4. Failure transient و retry safe → RETRY_ALLOWED
پیام delivered نشده، failure transient است، idempotency key و retry budget داریم. retry مجاز است. اگر delivery receipt قبلاً ثبت شده بود، retry باید block شود.
5. انتقال SMS به Email و Push
Purpose و minimal business fields ثابت میمانند، اما channel-specific destination token، template، provider adapter و delivery evidence دوباره ساخته میشوند. نتیجهی SMS را کپی نمیکنیم.
Failure modeهای رایج
- Object dumping: کل order/customer object وارد template میشود.
- Provider payload leakage: raw carrier/provider payload به مشتری یا log نامناسب میرسد.
- Route-as-truth: مقصد پیام با canonical customer identity یکی فرض میشود.
- Consent shortcut: «مشتری سفارش داده» به معنی consent برای همهی message classها فرض میشود.
- Accepted=Delivered: HTTP 2xx یا provider ID به receipt تبدیل میشود.
- Versionless template: معلوم نیست چه متن/redaction rule ارسال شده.
- Infinite retry: بعد از delivery یا بدون idempotency دوباره میفرستیم.
- Vendor-rule generalization: retention یا محدودیت DHL برای همهی providerها کپی میشود.
- Copied transfer: SMS contract بدون recompute به email/push منتقل میشود.
Alternatives و trade-offها
Full object templating سریع است اما exposure و coupling زیادی دارد. Projection کمی کار design میخواهد ولی field ownership و privacy boundary را روشن میکند.
Raw destination storage debugging را ساده میکند اما exposure را بالا میبرد. token/mask + secure resolver معمولاً audit surface کوچکتری میسازد.
Optimistic delivered dashboard را سبزتر میکند اما truth را خراب میکند. جداکردن PROVIDER_ACCEPTED از DELIVERED ممکن است UNKNOWN بیشتری نشان دهد، ولی دقیقتر است.
Aggressive retry احتمال eventual delivery را بالا میبرد اما duplicate risk دارد. bounded retry + idempotency trade-off سالمتری است.
Long retention troubleshooting تاریخی را آسان میکند اما privacy/storage risk را بالا میبرد. retention class باید purpose-driven و قابل review باشد.
Experienced bridge: ده سؤال review
- message class و purpose دقیق چیست؟
- minimal field set چطور justify شده؟
- آیا full address/name/raw payload واقعاً لازم است؟
- recipient route چگونه authorization میشود؟
- destination در evidence masked/tokenized است؟
- redaction/template version چیست؟
- provider acceptance و delivery receipt جدا هستند؟
- retry چه سقف و idempotency دارد؟
- retention class از کدام authority میآید؟
- در channel جدید چه چیزهایی باید recompute شوند؟
تمرین هدایتشده و مستقل
Lab آفلاین را اجرا کن:
python -B lab/COM-035-LAB1/learner/run_checks.py
fixture baseline را ببین؛ over-complete projection را با حذف PII غیرضروری repair کن؛ provider acceptance بدون delivery receipt را تشخیص بده؛ basis یا template version را حذف کن؛ retry بعد از delivered را امتحان کن؛ سپس همان purpose را از SMS به email/push منتقل و route/template/provider evidence را recompute کن.
Verification evidence
Evaluator باید دستکم این shortcutها را بگیرد:
- field حساس/غیرضروری در projection؛
- destination خام یا recipient mismatch؛
- basis لازم ولی مفقود؛
- template/redaction version مفقود؛
DELIVEREDبدون delivery event؛- retry بعد از delivered یا بدون idempotency/budget؛
- retention مفقود؛
- transfer که channel-specific evidence را از baseline کپی میکند.
Oracle فقط fixture synthetic و ruleهای deterministic است؛ هیچ customer data، provider credential یا hidden reasoning وجود ندارد.
Assessment و transfer
تکلیف نهایی چهار حرکت دارد: مرز COM-035 را توضیح بده؛ Contract baseline را کامل کن؛ یک over-collection یا accepted-without-delivery mutation را تشخیص بده؛ سپس همان purpose را برای channel دیگر از صفر recompute کن.
پاسخ قوی فقط نمیگوید «PII کم شد». نشان میدهد کدام field برای purpose لازم بود، چه چیزی حذف شد بدون functional loss، route/basis/template چگونه ثابت شد، delivery state از چه evidence آمد و چه زمانی HOLD/BLOCKED لازم است.
منابع و freshness
EC-GDPR-PRINCIPLES— اصول GDPR در وبسایت رسمی کمیسیون اروپا؛ rechecked 2026-09-14.EC-GDPR-OBLIGATIONS— data protection by design/default؛ rechecked 2026-09-14.DHL-UTAPI-PUSH— Unified Tracking Push و terms مربوط به tracking data؛ rechecked 2026-09-14؛ vendor-specific.LOCAL_DESIGN_AUTHORITY— Bible فریزشده COM-035 برای schema/state/gateها.
این درس توصیه حقوقی نیست. sourceهای قانونی/قراردادی فقط FACT boundary میدهند؛ lawful basis، retention class و channel policy باید در context واقعی با authority مناسب تعیین شوند.
ارزیابی
پاسخنامهی این درس در بستهی آموزش وجود ندارد؛ خودت جواب بده و صادقانه علامت بزن. «نیاز به مرور» درس را به صف تکرار میفرستد.
COM-035-S1 retrieval
Explain COM-035 ownership and one adjacent non-goal.
COM-035-S2 application
Build the baseline Minimal-PII Notification Projection and Delivery Contract.
COM-035-S3 diagnosis
Repair an over-complete projection and explain why provider acceptance is not delivery.
COM-035-S4 transfer
Move the same purpose from SMS to email/push and recompute channel-specific routing/template/provider evidence.
ملاکهای ارزیابی (rubric)
Blocking dimensions: scope boundary, purpose/minimal-field evidence, recipient routing/basis, template/redaction provenance, delivery truth, retry/retention controls, negative evidence, and changed-channel transfer.
منابع و تازگی
مطالعهٔ موارد (case studies)
فایلهای آزمایشگاه
python -B run_checks.py را اجرا کنید. هشت fixture مصنوعی minimisation، routing masked، basis/template/retention، تفاوت accepted/delivered، retry محدود و transfer بین channelها را میسنجند.