{
  "title": "استاندارد نهایی نام‌گذاری رویدادها",
  "slug": "team/platform/ADR/ADR-EVENT-001",
  "url": "/docs/team/platform/ADR/ADR-EVENT-001",
  "frontmatter": {
    "layout": "doc",
    "title": "استاندارد نهایی نام‌گذاری رویدادها",
    "description": "تصمیم معماری برای تعیین الگوی رسمی نام‌گذاری، دامنه‌ها، فرمت افعال، نسخه‌بندی و منبع حقیقت رویدادهای پلتفرم",
    "version": "1.0.0",
    "status": "DRAFT",
    "author": "Antigravity",
    "owner": "Platform Team",
    "created_at": "2026-06-15",
    "updated_at": "2026-06-15",
    "tags": "",
    "reviewers": ""
  },
  "sections": [
    {
      "level": 1,
      "heading": "استاندارد نهایی نام‌گذاری رویدادها",
      "content": "**Event Naming & Versioning Final Standard**\n\n> **ADR-EVENT-001**\n\n---"
    },
    {
      "level": 2,
      "heading": "وضعیت",
      "content": "**Status**\n\n⏳ **پیش‌نویس (DRAFT)**\n\n---"
    },
    {
      "level": 2,
      "heading": "تاریخ",
      "content": "**Date**\n\n2026-06-15\n\n---"
    },
    {
      "level": 2,
      "heading": "زمینه",
      "content": "**Context**\n\nپلتفرم NONS بر پایه معماری رویدادمحور (Event-Driven Architecture) طراحی شده است. تمام ارتباطات بین سرویس‌ها از طریق NATS JetStream و در قالب رویداد انجام می‌شود.一致性 و یکپارچگی در نام‌گذاری رویدادها برای درکپذیری، اشکال‌زدایی و نگهداری بلندمدت حیاتی است.\n\nدر مستندات فعلی پروژه سه استاندارد نام‌گذاری با تضادهای مشخص وجود دارد:\n\n| سند | الگو | مثال |\n| --- | --- | --- |\n| `standards/event-standard.md` (خط ۱۶۰) | `nons.<domain>.<entity>.<action>` | `nons.order.completed` |\n| `standards/naming-conventions.md` (خط ۱۳۸) | `nons.{resource}.{past_tense_verb}` | `nons.payment.escrow.held` |\n| `standards/event-contract.md` (خط ۱۶۹) | `nons.<domain>.<entity>.<action>` | `nons.payment.escrow.released` |\n\nهمچنین در `packages/events/src/events.ts` دو دسته نام وجود دارد — دسته‌ای با پیشوند `nons.` و دسته‌ای بدون آن (`user.registered`, `platform.service.status_changed`). این تضادها توسعه‌دهنده را در نام‌گذاری رویدادهای جدید سردرگم می‌کند و مانع یکپارچگی پلتفرم می‌شود.\n\n---"
    },
    {
      "level": 2,
      "heading": "مسئله",
      "content": "**Problem Statement**\n\nالگوی نام‌گذاری رویدادها باید:\n- یکتا و قابل پیش‌بینی باشد — توسعه‌دهنده بتواند نام رویداد جدید را بدون مراجعه به سند حدس بزند.\n- از collision با رویدادهای خارج از پلتفرم جلوگیری کند.\n- قابلیت مسیریابی با wildcard در NATS را حفظ کند (`nons.>.created`).\n- از بسط‌پذیری برای sub-entityها پشتیبانی کند (`nons.payment.escrow.held`).\n- با ابزارهای Cross-Cutting مانند Telemetry, Audit Log و Alerting سازگار باشد.\n\n---"
    },
    {
      "level": 2,
      "heading": "گزینه‌های بررسی‌شده",
      "content": "**Alternatives Considered**"
    },
    {
      "level": 3,
      "heading": "گزینه ۱ — الگوی ساده `{verb}.{resource}` (بدون پیشوند)",
      "content": "مانند `user.registered`, `order.created`.\n\n**مزایا:**\n- بسیار کوتاه و خواناتر.\n\n**معایب:**\n- خطر collision با کتابخانه‌ها یا ابزارهای خارجی.\n- عدم تفکیک domain — `user.registered` مشخص نمی‌کند کدام سرویس صادر کرده است.\n- مشکل در Wildcard — `*.registered` همه رویدادهای ثبت‌نام را یکسان می‌گیرد.\n\n**نتیجه:** رد شد.\n\n---"
    },
    {
      "level": 3,
      "heading": "گزینه ۲ — الگوی `nons.{domain}.{entity}.{action}` با فعل حال",
      "content": "مانند `nons.order.complete`, `nons.user.register`.\n\n**مزایا:**\n- خوانایی بالا برای انگلیسی‌زبانان.\n\n**معایب:**\n- فعل حال (`register`) مفهوم Command را منتقل می‌کند نه Event.\n- در معماری Event-Driven، رویداد باید حقیقتی از گذشته باشد (`registered` نه `register`).\n- مصرف‌کننده ممکن است تصور کند باید اقدامی انجام دهد.\n\n**نتیجه:** رد شد.\n\n---"
    },
    {
      "level": 3,
      "heading": "گزینه ۳ — الگوی `nons.{domain}.{entity}.{past_action}` ✅",
      "content": "مانند `nons.auth.user.registered`, `nons.order.fulfillment.completed`.\n\n**مزایا:**\n- پیشوند `nons.` از collision جلوگیری می‌کند.\n- domain اولین بخش معنی‌دار — امکان wildcard روی domain.\n- entity اختیاری — برای domainهای ساده حذف می‌شود.\n- فعل گذشته مفهوم Event را به درستی منتقل می‌کند.\n- sub-entity با dot قابل افزودن است (`nons.payment.escrow.held`).\n- حداکثر عمق ۴ بخش بعد از `nons.` از پیچیدگی جلوگیری می‌کند.\n\n**نتیجه:** ✅ پذیرفته شد.\n\n---"
    },
    {
      "level": 2,
      "heading": "تصمیم",
      "content": "**Decision**"
    },
    {
      "level": 3,
      "heading": "الگوی رسمی نام‌گذاری رویدادها",
      "content": "```text\nnons.<domain>.<entity>.<past_action>\n```\n\n- `nons.` — پیشوند ثابت (اجباری برای همه رویدادهای پلتفرم)\n- `<domain>` — bounded context یا نام سرویس مالک (مفرد، kebab-case)\n- `<entity>` — موجودیت اصلی رویداد (مفرد، اختیاری)\n- `<past_action>` — فعل گذشته ساده (lowercase، جداکننده کلمات: `_`)"
    },
    {
      "level": 3,
      "heading": "دامنه‌های مصوب (Domains)",
      "content": "| Domain | سرویس مالک | توضیح |\n| ------ | ---------- | ----- |\n| `auth` | auth-service | احراز هویت — ثبت‌نام، ورود، خروج، تغییر رمز |\n| `iam` | iam-service | مدیریت نقش‌ها، مجوزها و سیاست‌های دسترسی |\n| `user` | user-service | پروفایل، شناسه عمومی، Username، تنظیمات شخصی |\n| `marketplace` | marketplace-service | محصولات، فروشگاه‌ها، موجودی |\n| `order` | order-service | سفارشات، وضعیت‌ها |\n| `payment` | payment-service | پرداخت، اسکرو |\n| `wallet` | wallet-service | کیف پول، تراکنش‌ها |\n| `settlement` | settlement-service | تسویه، کمیسیون |\n| `currency` | currency-service | نرخ ارز |\n| `chat` | chat-service | پیام‌ها |\n| `dispute` | dispute-service | اختلافات، داوری |\n| `review` | review-service | بازخوردها |\n| `moderation` | moderation-service | نظارت |\n| `zone` | zone-service | حوزه تخصصی |\n| `boost` | boost-service | تبلیغات |\n| `search` | search-service | جستجو |\n| `notification` | notification-service | اعلانات |\n| `storage` | storage-service | ذخیره‌سازی فایل |\n| `analytics` | analytics-service | تحلیل |\n| `kyc` | kyc-service | احراز هویت مشتریان |\n| `platform` | core-service | رویدادهای سطح زیرساخت |\n\n> **قانون:** domain جدید فقط با ADR جدید قابل اضافه شدن است.\n\n> **تغییر نسخه 1.1 — 2026-06-22:** دامنه `user` به لیست دامنه‌های مصوب اضافه شد. مالک: `user-service`. این تصمیم به دلیل جداسازی مسئولیت پروفایل و هویت نمایشی کاربر از IAM Service اتخاذ شد — IAM فقط مالک Authorization (Role, Permission, Policy) است.\n\n> **تغییر نسخه 1.2 — 2026-06-22:** دامنه `iam` مطابق Blueprint v1.1 بازنگری شد. رویدادهای IAM از الگوی `nons.iam.<entity>.<past_action>` پیروی می‌کنند که در `<past_action>` از underscore (`_`) برای کلمات چندبخشی استفاده می‌شود (مثلاً `nons.iam.user.status_changed`). مستندات کامل رویدادها در [ایونت کاتالوگ IAM](../../../../nons-api/catalog/events/iam/events.yaml)."
    },
    {
      "level": 3,
      "heading": "نسخه‌بندی",
      "content": "نسخه **فقط در Envelope** قرار می‌گیرد، هرگز در NATS Subject:\n\n```\n❌ nons.order.completed.v1\n✅ nons.order.completed   (version داخل Envelope)\n```\n\nفرمت: `major.minor` — minor برای افزودن فیلد اختیاری، major برای تغییرات ناسازگار."
    },
    {
      "level": 3,
      "heading": "منبع حقیقت (Source of Truth)",
      "content": "```text\nProto (envelope.proto)    → ساختار EventEnvelope\n        ↓\nEvent Catalog (catalog/)  → ثبت نام، domain، owner، consumers، schema\n        ↓\nCode Bindings (events.ts) → ثابت‌های TypeScript\n```\n\n---"
    },
    {
      "level": 2,
      "heading": "پیامدها",
      "content": "**Consequences**"
    },
    {
      "level": 3,
      "heading": "پیامدهای مثبت",
      "content": "- **یکپارچگی:** همه رویدادها از یک الگو پیروی می‌کنند — دیگر تضاد نام وجود ندارد.\n- **Wildcard-friendly:** `nons.auth.>.registered` تمام رویدادهای ثبت‌نام در Auth را می‌گیرد.\n- **Self-documenting:** نام رویداد domain، entity و ماهیت تغییر را مشخص می‌کند.\n- **بازدارنده از collision:** `nons.` یک namespace انحصاری پلتفرم است."
    },
    {
      "level": 3,
      "heading": "پیامدهای منفی",
      "content": "- **تغییر نام رویدادهای موجود:** ۴ رویداد Auth (بدون `nons.`) و ۱ رویداد Platform باید تغییر نام دهند.\n- **نیاز به بروزرسانی استانداردهای موجود:** `standards/event-standard.md` و `standards/naming-conventions.md` باید با این ADR هماهنگ شوند.\n- **هزینه مهاجرت:** سرویس‌هایی که رویدادهای قدیمی را مصرف می‌کنند باید همزمان هر دو نام را پشتیبانی کنند.\n\n---"
    },
    {
      "level": 2,
      "heading": "نتیجه",
      "content": "**Conclusion**\n\nالگوی `nons.<domain>.<entity>.<past_action>` به عنوان استاندارد رسمی نام‌گذاری رویدادهای پلتفرم NONS تصویب می‌شود. این الگو جایگزین تمام استانداردهای قبلی می‌شود و تمام رویدادهای جدید باید از آن پیروی کنند.\n\nلایه‌های Source of Truth به ترتیب Proto → Event Catalog → Code Bindings هستند و هیچ رویداد جدیدی بدون ثبت در هر سه لایه مجاز نیست."
    }
  ]
}