{
  "title": "قراردادها",
  "slug": "team/platform/ADR/ADR-Platform-001",
  "url": "/docs/team/platform/ADR/ADR-Platform-001",
  "frontmatter": {
    "layout": "doc",
    "title": "قراردادها",
    "description": "تصمیم معماری برای تعریف و توزیع قراردادهای مشترک بین سرویس‌ها",
    "version": "0.1.0",
    "status": "APPROVED",
    "author": "xoxxel",
    "owner": "xoxxel",
    "created_at": "2026-06-12",
    "updated_at": "2026-06-12",
    "tags": "",
    "reviewers": ""
  },
  "sections": [
    {
      "level": 1,
      "heading": "قراردادها",
      "content": "> ADR-Platform-001 — Language-Neutral Contract Layer"
    },
    {
      "level": 2,
      "heading": "وضعیت",
      "content": "Approved"
    },
    {
      "level": 2,
      "heading": "تاریخ",
      "content": "2026-06-12\n\n---"
    },
    {
      "level": 1,
      "heading": "زمینه",
      "content": "پروژه NONS بر پایه مجموعه‌ای از سرویس‌های مستقل و رویدادمحور طراحی شده است.\n\nاین سرویس‌ها الزاماً از یک زبان برنامه‌نویسی مشترک استفاده نمی‌کنند.\n\nنمونه:\n\n- Core → Go\n- Business Services → TypeScript / NestJS\n- Moderation Services → Python\n- Automation Workflows → n8n\n- سرویس‌های آینده → Rust ،Java ،Go ،Python یا سایر فناوری‌ها\n\nدر نسخه‌های اولیه معماری، قراردادهای مشترک پروژه در قالب Packageهای TypeScript تعریف شده بودند و به عنوان منبع حقیقت (Source of Truth) در نظر گرفته می‌شدند.\n\nاین رویکرد برای سرویس‌های TypeScript مناسب است اما برای سرویس‌های غیر TypeScript مشکلات زیر را ایجاد می‌کند:\n\n- وابستگی معماری به TypeScript\n- نیاز به Parser یا Adapter اختصاصی برای هر زبان\n- احتمال Drift بین پیاده‌سازی زبان‌ها\n- دشواری استفاده از قراردادها در ابزارهای غیرکدنویسی مانند n8n\n- محدود شدن قابلیت توسعه چندزبانه پلتفرم\n\n---"
    },
    {
      "level": 1,
      "heading": "مسئله",
      "content": "قراردادهای پلتفرم باید:\n\n- مستقل از زبان باشند\n- قابل استفاده در تمامی سرویس‌ها باشند\n- توسط ابزارهای مختلف قابل مصرف باشند\n- از ایجاد چندین منبع حقیقت جلوگیری کنند\n- امکان تولید خودکار Binding برای زبان‌های مختلف را فراهم کنند\n\n---"
    },
    {
      "level": 1,
      "heading": "گزینه‌های بررسی‌شده",
      "content": ""
    },
    {
      "level": 2,
      "heading": "گزینه ۱ — TypeScript Packages به عنوان Source of Truth",
      "content": "ساختار:\n\n```text\nnons-api/packages/\n ├─ events\n ├─ errors\n ├─ permissions\n └─ types\n```"
    },
    {
      "level": 3,
      "heading": "مزایا",
      "content": "- ساده برای سرویس‌های NestJS\n- توسعه سریع"
    },
    {
      "level": 3,
      "heading": "معایب",
      "content": "- وابستگی کل اکوسیستم به TypeScript\n- نیاز به Parser برای Go\n- نیاز به Adapter برای Python\n- افزایش احتمال ناسازگاری قراردادها"
    },
    {
      "level": 3,
      "heading": "نتیجه",
      "content": "رد شد\n\n---"
    },
    {
      "level": 2,
      "heading": "گزینه ۲ — Contract Artifact Distribution",
      "content": "ساخت قراردادها در TypeScript و تولید Artifactهای JSON/YAML."
    },
    {
      "level": 3,
      "heading": "مزایا",
      "content": "- مستقل از Runtime"
    },
    {
      "level": 3,
      "heading": "معایب",
      "content": "- همچنان TypeScript مالک قراردادها است\n- نیاز به Pipeline توزیع Artifact\n- نسخه‌بندی پیچیده‌تر"
    },
    {
      "level": 3,
      "heading": "نتیجه",
      "content": "رد شد\n\n---"
    },
    {
      "level": 2,
      "heading": "گزینه ۳ — Protocol Buffers (Protobuf) ✅",
      "content": "قراردادها در قالب Protobuf تعریف می‌شوند و برای هر زبان Binding اختصاصی تولید می‌شود."
    },
    {
      "level": 3,
      "heading": "ساختار",
      "content": "```text\ncontracts/\n\n├── envelope.proto\n├── events.proto\n├── errors.proto\n├── permissions.proto\n└── registry.proto\n```\n\n---"
    },
    {
      "level": 1,
      "heading": "تصمیم",
      "content": "Protocol Buffers به عنوان Canonical Contract Definition Format انتخاب می‌شود.\n\nتمام قراردادهای مشترک پلتفرم باید ابتدا در لایه Contracts تعریف شوند.\n\nهیچ زبان برنامه‌نویسی مالک قراردادها نیست.\n\nTypeScript، Go، Python و سایر زبان‌ها مصرف‌کننده قراردادها هستند، نه مالک آن‌ها.\n\n---"
    },
    {
      "level": 1,
      "heading": "مدل معماری",
      "content": "```text\nContracts Layer (Proto)\n\n        ↓\n\nCode Generation\n\n ┌──────┼──────┬──────┐\n │      │      │      │\n\nTS     Go    Python  Future\n```\n\n---"
    },
    {
      "level": 1,
      "heading": "محدوده قراردادها",
      "content": "موارد زیر در لایه Contracts تعریف می‌شوند:\n\n- Event Envelope\n- Platform Events\n- Error Codes\n- Permissions\n- Service Metadata\n- Registry Contracts\n\n---"
    },
    {
      "level": 1,
      "heading": "موارد خارج از محدوده",
      "content": "قراردادهای دامنه‌ای هر سرویس می‌توانند در همان سرویس نگهداری شوند.\n\nاین ADR فقط درباره قراردادهای مشترک پلتفرم است.\n\n---"
    },
    {
      "level": 1,
      "heading": "ارتباط با NATS",
      "content": "استفاده از Protobuf به معنای استفاده از gRPC نیست.\n\nپروژه همچنان از NATS به عنوان Event Bus استفاده می‌کند.\n\nقراردادها توسط Protobuf تعریف می‌شوند اما نحوه انتقال پیام‌ها مستقل از این تصمیم است.\n\nبنابراین:\n\n- NATS حفظ می‌شود\n- معماری Event-Driven حفظ می‌شود\n- Core بدون تغییر باقی می‌ماند\n\n---"
    },
    {
      "level": 1,
      "heading": "مزایا",
      "content": "- استقلال کامل از زبان\n- حذف نیاز به Parserهای اختصاصی\n- کاهش Drift بین سرویس‌ها\n- پشتیبانی طبیعی از Go ،TypeScript ،Python و سایر زبان‌ها\n- سازگاری با ابزارهای Automation\n- امکان توسعه اکوسیستم بدون تغییر قراردادها\n- یک منبع حقیقت واحد برای کل پلتفرم\n\n---"
    },
    {
      "level": 1,
      "heading": "معایب",
      "content": "- نیاز به ابزار تولید کد (Code Generation)\n- افزایش پیچیدگی Build نسبت به TypeScript Packages\n- نیاز به آشنایی تیم با Protobuf\n\n---"
    },
    {
      "level": 1,
      "heading": "پیامدها",
      "content": "تمام سرویس‌ها باید Contract Bindingهای تولیدشده برای زبان خود را مصرف کنند.\n\nهیچ سرویسی مجاز به تعریف نسخه مستقل از قراردادهای مشترک پلتفرم نیست.\n\nتمام تغییرات قراردادها باید ابتدا در لایه Contracts اعمال شوند و سپس Bindingهای جدید تولید شوند.\n\nدر همین راستا، فایل‌های استقرار، اسکریپت‌ها و چارت‌های Helm مرتبط با استقرار سرویس‌ها بر اساس قراردادها در شاخه `deploy/` نگهداری و سازمان‌دهی می‌شوند (D14).\n\n---"
    },
    {
      "level": 1,
      "heading": "نتیجه",
      "content": "به منظور پشتیبانی بلندمدت از معماری چندزبانه، جلوگیری از وابستگی به یک فناوری خاص و ایجاد یک منبع حقیقت مستقل از زبان، Protocol Buffers به عنوان لایه رسمی قراردادهای مشترک پلتفرم NONS انتخاب می‌شود."
    }
  ]
}