چگونه قرارداد پروژههای نرمافزاری نوشته میشود؟
فرض کنید یک مشتری با شما تماس میگیرد و میگوید: «برای فروشگاه اینترنتیام یک سایت حرفهای میخواهم؛ چیزی شبیه فروشگاههای بزرگ، با پنل مدیریت، درگاه پرداخت و امکان پیگیری سفارشها.»
شما هم قیمت و زمان تقریبی را اعلام میکنید و پروژه را شروع میکنید.
چند هفته بعد مشتری میگوید: «راستی، امکان اتصال به انبارداری و باشگاه مشتریان را هم اضافه کن. فکر میکردم اینها جزو پروژه است!»
شما پاسخ میدهید: «اما درباره این موارد صحبت نکرده بودیم.»
مشتری میگوید: «خب، سایت فروشگاهی بدون این امکانات که کامل نیست!»
اینجاست که یک پروژه نرمافزاری ساده میتواند به اختلاف، تأخیر و حتی ضرر مالی تبدیل شود.
راهحل چیست؟ قرارداد نرمافزاری دقیق و شفاف.
قرارداد فقط یک کاغذ برای تعیین قیمت نیست؛ بلکه مشخص میکند چه چیزی باید ساخته شود، چه کسی چه مسئولیتی دارد، پروژه چه زمانی تحویل داده میشود، هزینه چگونه پرداخت میشود و اگر مشکلی پیش آمد چه اتفاقی خواهد افتاد.
اما قرارداد پروژه نرمافزاری دقیقاً چگونه نوشته میشود و چه بخشهایی باید داشته باشد؟
قرارداد پروژه نرمافزاری چیست؟
قرارداد پروژه نرمافزاری یک توافق رسمی بین کارفرما و مجری یا تیم توسعه است که در آن جزئیات پروژه، وظایف طرفین، هزینه، زمانبندی، نحوه پرداخت، مالکیت کد و شرایط پشتیبانی مشخص میشود.
برای مثال، فرض کنید یک شرکت از شما میخواهد یک اپلیکیشن رزرو آنلاین سالن ورزشی طراحی کنید.
اگر فقط بنویسید:
«طراحی و پیادهسازی اپلیکیشن رزرو سالن ورزشی»
هنوز تقریباً هیچ چیز مشخص نشده است!
آیا اپلیکیشن برای Android است یا iOS؟
آیا پنل مدیریت دارد؟
آیا پرداخت آنلاین دارد؟
آیا کاربر میتواند رزرو خود را لغو کند؟
آیا پیامک ارسال میشود؟
آیا اتصال به درگاه پرداخت بر عهده برنامهنویس است؟
پشتیبانی چند ماه است؟
کد منبع در پایان پروژه تحویل داده میشود؟
هرچه این موارد دقیقتر مشخص شوند، احتمال اختلاف در آینده کمتر خواهد شد.
چرا قرارداد برای پروژههای برنامهنویسی مهم است؟
پروژههای نرمافزاری با بسیاری از پروژههای معمولی تفاوت دارند.
وقتی یک میز سفارش میدهید، اندازه، جنس و رنگ آن تقریباً مشخص است؛ اما در یک پروژه نرمافزاری ممکن است مشتری در طول پروژه نظرش را تغییر دهد یا قابلیتهای جدیدی بخواهد.
مثلاً ابتدا قرار بوده یک سایت شرکتی با ۵ صفحه ساخته شود، اما در میانه پروژه کارفرما درخواست میکند:
سیستم ورود کاربران اضافه شود.
پنل مدیریت ساخته شود.
وبلاگ به سایت اضافه شود.
سیستم تیکت راهاندازی شود.
اتصال به CRM انجام شود.
نسخه موبایل اپلیکیشن هم ساخته شود!
اگر قرارداد مشخصی وجود نداشته باشد، مشخص نیست این امکانات جدید جزو پروژه اولیه هستند یا باید هزینه جداگانه داشته باشند.
به همین دلیل قرارداد به نوعی مرز پروژه را مشخص میکند.
مهمترین بخشهای قرارداد نرمافزاری
یک قرارداد مناسب باید بخشهای مختلفی داشته باشد. البته متن و شرایط دقیق قرارداد به نوع پروژه، قوانین محل اجرا و توافق طرفین بستگی دارد و برای قراردادهای مهم بهتر است متن نهایی توسط فرد متخصص حقوقی بررسی شود.
اما از نظر پروژهای، چند بخش اهمیت ویژهای دارند.
۱. مشخصات طرفین قرارداد
در ابتدای قرارداد باید مشخص شود چه افرادی یا شرکتهایی با یکدیگر قرارداد میبندند.
برای مثال:
کارفرما: شرکت نمونه
مجری: شرکت یا شخص توسعهدهنده
نماینده پروژه: مدیر محصول یا نماینده معرفیشده از طرف کارفرما
اگر یکی از طرفین شرکت باشد، مشخصات ثبتی و نماینده مجاز آن نیز میتواند در قرارداد درج شود.
هدف این بخش ساده است:
دقیقاً چه کسی سفارشدهنده و چه کسی اجراکننده پروژه است؟
۲. موضوع قرارداد
موضوع قرارداد باید کاملاً مشخص و قابل اندازهگیری باشد.
مثلاً به جای اینکه بنویسیم:
طراحی یک سایت حرفهای
بهتر است مشخص کنیم:
طراحی و توسعه یک وبسایت فروشگاهی شامل صفحات اصلی، دستهبندی محصولات، جستوجو، سبد خرید، ثبت سفارش، پرداخت آنلاین و پنل مدیریت محصولات.
این تفاوت بسیار مهم است.
هرچه موضوع پروژه مبهمتر باشد، احتمال اختلاف بیشتر میشود.
۳. محدوده پروژه یا Scope
یکی از مهمترین بخشهای قرارداد نرمافزاری، Scope یا محدوده پروژه است.
محدوده پروژه مشخص میکند چه امکاناتی باید ساخته شوند و چه امکاناتی خارج از قرارداد هستند.
فرض کنید قرار است یک اپلیکیشن آموزش آنلاین ساخته شود.
در محدوده پروژه میتوان نوشت:
ثبتنام و ورود کاربران
مشاهده دورهها
پخش ویدئو
پرداخت آنلاین
پنل مدرس
پنل مدیریت
سیستم ثبت نظر
اما اگر مثلاً اپلیکیشن تلویزیون هوشمند یا سیستم پیشنهاد دوره با هوش مصنوعی جزو پروژه نیست، بهتر است این موضوع نیز مشخص شود.
این کار جلوی یکی از مشکلات رایج پروژهها یعنی Scope Creep را میگیرد.
Scope Creep چیست؟
Scope Creep زمانی اتفاق میافتد که امکانات پروژه بهمرور و بدون اصلاح رسمی قرارداد افزایش پیدا کنند.
مثلاً پروژه ابتدا قرار بوده یک فروشگاه اینترنتی ساده باشد.
بعد مشتری میگوید:
«یک سیستم تخفیف هم اضافه کنیم.»
بعد:
«باشگاه مشتریان هم داشته باشیم.»
بعد:
«اتصال به انبارداری را هم انجام بده.»
بعد:
«یک اپلیکیشن موبایل هم برایش بساز.»
اگر همه این موارد بدون تغییر زمان و هزینه اضافه شوند، پروژه کمکم از چیزی که در ابتدا توافق شده بود بسیار بزرگتر میشود.
به همین دلیل قرارداد باید فرآیند تغییرات پروژه را مشخص کند.
۴. زمانبندی و مراحل تحویل
در قرارداد بهتر است فقط ننویسیم:
پروژه در ۳ ماه تحویل داده میشود.
بلکه مراحل پروژه را نیز مشخص کنیم.
برای مثال:
مرحله اول: تحلیل نیازمندیها
مرحله دوم: طراحی رابط کاربری
مرحله سوم: توسعه Backend
مرحله چهارم: توسعه Frontend
مرحله پنجم: تست و رفع خطا
مرحله ششم: استقرار و تحویل نهایی
این تقسیمبندی باعث میشود هر دو طرف بدانند پروژه در چه مرحلهای قرار دارد.
یک نکته مهم درباره زمان تحویل
فرض کنید برنامهنویس اعلام کرده پروژه را در ۶۰ روز تحویل میدهد.
اما کارفرما اطلاعات محصولات، تصاویر، متن صفحات یا دسترسیهای موردنیاز را ۲۰ روز دیرتر ارسال میکند.
آیا باز هم باید پروژه در همان روز اولیه تحویل داده شود؟
این موارد باید در قرارداد مشخص شوند.
برای مثال میتوان تعیین کرد که تأخیر در ارائه اطلاعات یا دسترسیهای موردنیاز از طرف کارفرما، زمانبندی پروژه را به همان میزان یا طبق شرایط توافقشده تغییر دهد.
۵. مبلغ قرارداد و نحوه پرداخت
یکی از مهمترین قسمتهای قرارداد، هزینه پروژه است.
اما فقط نوشتن مبلغ نهایی کافی نیست.
بهتر است مشخص شود پرداختها در چه مراحلی انجام میشوند.
مثلاً:
۳۰٪ هنگام شروع پروژه
۳۰٪ پس از تأیید طراحی
۳۰٪ پس از تکمیل نسخه اصلی
۱۰٪ هنگام تحویل نهایی
البته درصدها کاملاً به توافق طرفین بستگی دارند.
پرداخت مرحلهای باعث میشود پروژه از نظر مالی قابل مدیریتتر باشد و هر دو طرف بدانند در هر مرحله چه تعهد مالی دارند.
۶. نحوه مدیریت درخواستهای جدید
فرض کنید مشتری در اواسط پروژه یک قابلیت جدید درخواست میکند.
مثلاً:
«امکان ورود با شماره موبایل و کد یکبارمصرف را هم اضافه کنیم.»
اگر این قابلیت در Scope اولیه نبوده باشد، قرارداد باید مشخص کند که چگونه با چنین درخواستهایی برخورد میشود.
یک فرآیند مناسب میتواند اینگونه باشد:
درخواست جدید → بررسی فنی → تخمین زمان و هزینه → تأیید کارفرما → اجرای قابلیت
به این ترتیب، هیچ قابلیت جدیدی بدون بررسی وارد پروژه نمیشود.
۷. مالکیت کد و حقوق استفاده
یکی از مهمترین موضوعاتی که گاهی فراموش میشود، مالکیت نرمافزار و کد منبع است.
فرض کنید یک برنامهنویس برای یک شرکت سامانهای اختصاصی طراحی کرده است.
پس از پایان پروژه باید مشخص باشد:
مالک کد منبع چه کسی است؟
آیا کارفرما سورسکد را دریافت میکند؟
آیا مجری اجازه استفاده مجدد از بخشهای عمومی کد را دارد؟
آیا کارفرما اجازه فروش یا واگذاری نرمافزار را دارد؟
آیا کتابخانهها و ابزارهای شخص ثالث شرایط خاصی دارند؟
این موضوع بهخصوص در پروژههای اختصاصی اهمیت زیادی دارد.
۸. محرمانگی اطلاعات
در بسیاری از پروژهها، برنامهنویس به اطلاعات مهمی دسترسی پیدا میکند.
مثلاً:
اطلاعات مشتریان
اطلاعات مالی
اطلاعات فروش
API Keyها
اطلاعات ورود به سرورها
ساختار دیتابیس
اطلاعات تجاری شرکت
بنابراین بهتر است قرارداد درباره محرمانگی اطلاعات نیز تعیین تکلیف کند.
در پروژههای حساس ممکن است یک NDA یا توافقنامه محرمانگی نیز بهصورت جداگانه استفاده شود.
۹. امنیت و مسئولیت اطلاعات
در پروژههایی که با اطلاعات کاربران، پرداخت یا دادههای حساس سروکار دارند، بهتر است مسئولیتهای امنیتی نیز مشخص شود.
برای مثال باید مشخص شود:
چه کسی مسئول تهیه سرور است؟
چه کسی دسترسیها را مدیریت میکند؟
چه کسی مسئول تهیه Backup است؟
چه کسی مسئول تنظیمات امنیتی سرور است؟
چه کسی مسئول امنیت کدی است که توسط تیم توسعه نوشته شده؟
این موارد به نوع پروژه بستگی دارند و باید دقیقاً متناسب با معماری و زیرساخت پروژه تعیین شوند.
۱۰. تست و معیار پذیرش پروژه
یکی از جالبترین مشکلات پروژههای نرمافزاری این است که گاهی کارفرما میگوید:
«من پروژه را تحویل گرفتم، اما هنوز کامل نیست.»
مجری هم میگوید:
«تمام قابلیتهایی که در قرارداد نوشته شده اجرا شده است.»
برای جلوگیری از چنین اختلافی، قرارداد باید معیار پذیرش (Acceptance Criteria) داشته باشد.
مثلاً برای قابلیت ورود کاربران:
کاربر باید بتواند با شماره موبایل ثبتشده و کد تأیید معتبر وارد حساب خود شود و در صورت وارد کردن کد اشتباه، پیام خطای مناسب دریافت کند.
این تعریف بسیار بهتر از عبارت مبهم «سیستم ورود کاربران ساخته شود» است.
۱۱. پشتیبانی و رفع خطا
تحویل پروژه لزوماً به معنی پایان تمام مسئولیتها نیست.
ممکن است توافق شود که مجری پس از تحویل پروژه، مثلاً برای مدت مشخصی رفع باگهای مرتبط با نسخه تحویلشده را انجام دهد.
اما باید تفاوت بین Bug Fix و Feature Request مشخص باشد.
مثلاً اگر دکمه پرداخت در شرایطی که طبق مشخصات پروژه باید کار کند، خطا بدهد، احتمالاً باگ محسوب میشود.
اما اگر مشتری بعد از تحویل بگوید:
«حالا یک سیستم کیف پول هم به پروژه اضافه کنیم.»
این دیگر یک قابلیت جدید است و لزوماً نباید بخشی از پشتیبانی رایگان باشد.
۱۲. شرایط فسخ قرارداد
گاهی ممکن است یکی از طرفین نتواند به تعهدات خود عمل کند.
بنابراین قرارداد باید شرایط فسخ یا خاتمه همکاری را مشخص کند.
برای مثال باید درباره مواردی مانند:
عدم پرداخت هزینهها
تأخیر طولانی در اجرای تعهدات
عدم ارائه اطلاعات موردنیاز
نقض محرمانگی
عدم تحویل پروژه طبق شرایط قرارداد
تکلیف مشخصی وجود داشته باشد.
شرایط حقوقی دقیق فسخ باید متناسب با قانون و قرارداد توسط متخصص حقوقی تنظیم شود.
یک مثال واقعیتر
فرض کنید یک استارتاپ از یک تیم برنامهنویسی میخواهد یک پلتفرم رزرو آنلاین کلاسهای آموزشی بسازد.
در قرارداد نوشته میشود:
موضوع: طراحی و توسعه پلتفرم رزرو کلاس
امکانات نسخه اول:
ثبتنام کاربران
ورود با شماره موبایل
جستوجوی کلاسها
مشاهده برنامه زمانی
رزرو کلاس
پرداخت آنلاین
پنل مدرس
پنل مدیریت
ارسال اعلان
زمان اجرای پروژه: ۴ ماه
پرداخت: مرحلهای و بر اساس نقاط تحویل
پشتیبانی: ۲ ماه رفع خطاهای مرتبط با نسخه تحویلی
قابلیتهای خارج از Scope: اپلیکیشن موبایل، سیستم پیشنهاد هوشمند و اتصال به نرمافزار حسابداری
حالا اگر کارفرما در ماه سوم بگوید:
«یک اپلیکیشن Android هم میخواهم.»
تیم توسعه میتواند به قرارداد مراجعه کند و مشخص شود که اپلیکیشن موبایل در محدوده اولیه پروژه نبوده است.
در نتیجه میتوان برای آن تخمین زمان و هزینه جداگانه ارائه کرد.
قرارداد نرمافزاری خوب چه ویژگیهایی دارد؟
یک قرارداد خوب باید:
واضح باشد.
قابل اندازهگیری باشد.
وظایف هر دو طرف را مشخص کند.
محدوده پروژه را دقیق تعریف کند.
زمانبندی مشخص داشته باشد.
نحوه پرداخت را تعیین کند.
فرآیند تغییرات را مشخص کند.
درباره مالکیت کد تصمیمگیری کند.
شرایط پشتیبانی را مشخص کند.
معیار پذیرش پروژه داشته باشد.
درباره محرمانگی و امنیت اطلاعات تعیین تکلیف کند.
شرایط خاتمه یا فسخ را مشخص کند.
چند اشتباه رایج در قراردادهای برنامهنویسی
❌ «پروژه را کامل تحویل میدهم»
کامل بودن یک مفهوم مبهم است.
بهتر است دقیقاً مشخص شود چه قابلیتهایی باید تحویل داده شوند.
❌ «هر تغییری که کارفرما بخواهد انجام میشود»
این جمله میتواند پروژه را بینهایت بزرگ کند.
در قرارداد باید فرآیند درخواست تغییر مشخص باشد.
❌ «پشتیبانی به مدت ۶ ماه»
پشتیبانی دقیقاً شامل چه چیزی است؟
رفع باگ؟
آموزش؟
توسعه قابلیت جدید؟
رفع مشکلات سرور؟
این موارد باید مشخص شوند.
❌ «تحویل پروژه پس از اتمام کار»
«اتمام کار» باید تعریف شود.
بهتر است معیارهای پذیرش پروژه مشخص باشند.
آیا قرارداد برای پروژههای کوچک هم لازم است؟
حتی اگر پروژه کوچک باشد، داشتن توافق مکتوب میتواند بسیار مفید باشد.
فرض کنید قرار است برای یک فروشگاه محلی یک سایت ساده طراحی کنید.
ممکن است پروژه فقط چند صفحه داشته باشد؛ اما باز هم بهتر است حداقل موارد زیر مشخص شوند:
چه چیزی ساخته میشود؟
چقدر هزینه دارد؟
چه زمانی تحویل داده میشود؟
چند بار امکان اصلاح وجود دارد؟
پشتیبانی چگونه است؟
دامنه و هاست را چه کسی تهیه میکند؟
سورسکد چگونه تحویل داده میشود؟
چند صفحه توافق شفاف میتواند جلوی ساعتها بحث و اختلاف را بگیرد.
قرارداد فقط برای محافظت از برنامهنویس نیست!
گاهی تصور میشود قرارداد فقط برای این است که برنامهنویس بتواند پول خود را دریافت کند.
اما قرارداد از هر دو طرف محافظت میکند.
کارفرما میداند دقیقاً چه چیزی دریافت خواهد کرد و برنامهنویس نیز میداند دقیقاً چه چیزی باید تحویل دهد.
به همین دلیل قرارداد خوب نباید یک ابزار برای فشار آوردن به طرف مقابل باشد؛ بلکه باید یک نقشه مشترک برای اجرای پروژه باشد.
جمعبندی
نوشتن قرارداد برای پروژههای نرمافزاری فقط مشخص کردن قیمت و زمان تحویل نیست.
یک قرارداد حرفهای باید مشخص کند چه چیزی ساخته میشود، چه کسی چه مسئولیتی دارد، پروژه چگونه تحویل داده میشود، تغییرات چگونه مدیریت میشوند، پرداختها چه زمانی انجام میشوند و مالکیت نرمافزار و کد متعلق به چه کسی است.
مهمترین نکته این است که هر چیزی که ممکن است در آینده باعث سوءتفاهم شود، بهتر است قبل از شروع پروژه مشخص شود.
اگر برنامهنویس هستید، یادگیری اصول قراردادهای نرمافزاری میتواند به اندازه یادگیری یک تکنولوژی جدید برایتان ارزشمند باشد؛ چون در دنیای واقعی، یک پروژه موفق فقط با کد خوب ساخته نمیشود، بلکه به توافق شفاف، مدیریت درست و ارتباط حرفهای با مشتری هم نیاز دارد.
فرایانه؛ جایی که مفاهیم پیچیده برنامهنویسی و دنیای فناوری را به زبان ساده، کاربردی و قابل فهم آموزش میدهیم. 💚