عنوان:

‫تدوین نقشه مهاجرت و بازآفرینی کلان (Migration Plan) پیش از دستکاری سورس‌کد با GitHub Copilot


نویسنده: وحید نصیری
تاریخ: ۱۴۰۵/۰۵/۲۹ ۱۲:۵۷
آدرس: www.dntips.ir
در پروژه‌ها و Solutionهای بزرگ دات‌نت، درخواست‌های ناگهانی و کلی مانند «کل این پروژه را ریفکتور کن» یا «الگوی ریپازیتوری را حذف کن» معمولاً به کدهای شکسته، خطاهای متعدد زمان کامپایل و از بین رفتن یکپارچگی معماری ختم می‌شود. قابلیت‌های حالت عامل (Agent Mode) در GitHub Copilot برای تسک‌های چندمرحله‌ای و پیچیده طراحی شده‌اند، اما سپردن تغییرات ساختاری بدون نظارت به هوش مصنوعی یک ریسک عملیاتی بزرگ است. الگوی حرفه‌ای و امن در بازآفرینی‌های کلان، تفکیک مرحله «برنامه‌ریزی و سنجش ریسک» از مرحله «اجرای تغییرات» است:
Plan -> Review -> Execute -> Test -> Review Again
به جای استراتژی پرخطر «پرامپت بزن، دعا کن و کامیت کن!» (Prompt -> Pray -> Commit)، ابتدا باید از مدل یک نقشه راه مهندسی، گام‌به‌گام و قابل‌سنجش مطالبه کرد.

ساختار پرامپت مهندسی برای تدوین استراتژی مهاجرت معماری

هنگام جابه‌جایی میان الگوهای معماری (مانند حذف لایه‌های زائد Repository/Service، حرکت به سمت Vertical Slice Architecture، یا یکپارچه‌سازی Minimal APIs):
مخزن کدهای این پروژه را تحلیل کن. ما قصد داریم از الگوی سرویس‌های سنگین و لایه‌بندی مفرط (Repository-heavy pattern) به سمت یک معماری مدرن‌تر و ساده‌تر مهاجرت کنیم.
الزام مهم: فعلاً هیچ فایلی را تغییر نده یا حذف نکن.
ابتدا یک سند برنامه مهاجرت (Migration Plan) با بخش‌های زیر ارائه بده:
۱. وضعیت معماری فعلی (Current Architecture): تشریح نحوه تعامل لایه‌ها و شناسایی نقاط تجمع پیچیدگی.
۲. گراف وابستگی‌ها (Dependency Graph): وابستگی‌های متقابل میان اینترفیس‌ها، ریپازیتوری‌ها و سرویس‌های دامنه.
۳. فهرست فایل‌های کاندید (Candidate Files): دسته‌بندی فایل‌هایی که باید حذف، ادغام، یا بازنویسی شوند.
۴. ریسک‌های بحرانی (Risks & Breaking Changes): تغییر قراردادهای داده، رفتارهای پیش‌بینی‌نشده در تراکنش‌های دیتابیس یا خطاهای زمان اجرا.
۵. توالی گام‌به‌گام مهاجرت (Migration Sequence): مراحل خرد و افزایشی (Incremental Steps) به گونه‌ای که پس از هر مرحله پروژه قابلیت dotnet build و اجرای موفق تست‌ها را حفظ کند.
۶. سپر آزمون (Safety Harness / Test Strategy): چه تست‌های واحد یا یکپارچگی (Integration Tests) باید قبل از شروع نوشته شوند تا از رفتار قبلی محافظت کنند؟
۷. استراتژی بازگشت (Rollback Plan): در صورت بروز شکست در هر مرحله، مسیر بازگشت ایمن به وضعیت پایدار چگونه خواهد بود؟

چرا رویکرد افزایشی و مبتنی بر نقشه راه ضروری است؟
  • حفظ قابلیت بیلد و تست در هر گام: با تعریف فازهای کوچک (مثلاً مهاجرت یک ماژول مجزا مانند Orders به عنوان پایلوت)، می‌توان از شکسته‌شدن هم‌زمان صدها کلاس جلوگیری کرد.
  • کشف وابستگی‌های حلقوی و پنهان: تحلیل پیشینی گراف وابستگی‌ها مشخص می‌کند که آیا سرویسی به ظاهر ساده به ده‌ها اینترفیس دیگر گره خورده است یا خیر.
  • استفاده کنترل‌شده از Copilot Agent Mode: پس از تأیید نقشه راه، می‌توان به حالت Agent اجازه داد تا فقط یک گام مشخص از نقشه (مثلاً گام ۳: بازنویسی ماژول سفارشات با MediatR / FastEndpoints) را اجرا کند، دستورات dotnet test را در ترمینال اجرا کند، نتایج را ارزیابی کرده و خطاهای احتمالی را قبل از رفتن به گام بعدی اصلاح نماید.

نمونه فازبندی استخراج‌شده در یک مهاجرت فرضی دات‌نت

  • فاز ۰ (ایمن‌سازی): افزودن تست‌های یکپارچگی با WebApplicationFactory روی سناریوهای کلیدی Endpointها برای ثبت وضعیت پایدار فعلی.
  • فاز ۱ (حذف لایه انتزاع زائد): جایگزینی ریپازیتوری‌های عمومی (Generic Repositories) با تزریق مستقیم DbContext یا ساخت Handlers در یک زیرسیستم ایزوله.
  • فاز ۲ (پاک‌سازی Dependency Injection): اصلاح متدهای اکستنشن ثبت سرویس‌ها در Program.cs و حذف اینترفیس‌های منسوخ‌شده.
  • فاز ۳ (سنجش و تثبیت): اجرای بنچ‌مارک و تست‌های بارگذاری برای اطمینان از عدم افت کارایی.

نکات تکمیلی برای مدیریت تغییرات بزرگ

  • تعریف شاخه‌های موقت (Feature Branches) با مرزهای کوچک: هر مرحله از نقشه مهاجرت را در قالب یک Pull Request جداگانه و قابل بازبینی توسط تیم مدیریت کنید.
  • استفاده از متغیر @workspace در VS Code یا Solution Scope در Visual Studio: هنگام تدوین نقشه مهاجرت، به Copilot اجازه دسترسی کامل به کل فضای کاری را بدهید تا هیچ ماژول وابسته‌ای از چشم تحلیل پنهان نماند.
  • پرچم‌گذاری با صفت [Obsolete] پیش از حذف قطعی: به مدل تأکید کنید در فازهای میانی، متدها یا کلاس‌های قدیمی را با اتریبیوت [Obsolete("Use NewHandler instead", false)] پرچم‌گذاری کند تا سایر بخش‌های سیستم فرصت تطبیق داشته باشند.

قاعده کلیدی: ابزارهای هوش مصنوعی در اجرای کارهای چندمرحله‌ای توانمند هستند، اما مالکیت استراتژی و مرزبندی ریسک‌ها بر عهده مهندس نرم‌افزار است؛ ابتدا نقشه را بررسی و تصویب کنید، سپس فرمان اجرا را به هوش مصنوعی بسپارید.