شما نمیتوانید توسعه را متوقف کنید. این اولین چیزی است که باید بپذیرید. تیکتها مدام میرسند، مشتریان منتظر ارسال کالا هستند و کد موجود شما فقط به این دلیل که تصمیم گرفتهاید آن را مستند کنید، از کار نمیافتد. هیچ مدیر مهندسی اجازه توقف یکماهه فعالیت تیم را نمیدهد تا آنها بتوانند مشخصاتی را بنویسند که باید از روز اول وجود میداشت. OpenSpec برای واقعیت ساخته شده است، نه برای فانتزیهای پروژههای نوپا (greenfield). این ابزار زمانی بهترین عملکرد را دارد که آن را به آنچه از قبل دارید، همراه با مشتریان و همه چیز، متصل کنید.
هدف در اینجا بازنویسی نیست؛ بلکه یک «باستانشناسی صادقانه» است. شما آنچه را که واقعاً در محیط عملیاتی (production) در حال اجراست بیرون میکشید، آن را با دقت توصیف میکنید و اجازه میدهید این توصیف همگام با کد شما تکامل یابد. وقتی مشخصات شما با سیستمتان مطابقت داشته باشد، کار مهندسانی که در فصل آینده به تیم میپیوندند و همچنین ابزارهای هوش مصنوعی که اکنون در IDE شما هستند، آسانتر میشود. در اینجا روش انجام این کار بدون از دست دادن حتی یک نسخه از انتشار (release) آمده است.
با آنچه واقعاً انجام میدهید شروع کنید
مخزن (repository) خود را باز کنید؛ پوشههایی با نامهای controllers ،models ،services و utils را خواهید دید. اینها لایههای فنی هستند و به شما دروغ میگویند. آنها توصیف نمیکنند که سیستم شما برای کسبوکار چه کاری انجام میدهد. پوشهای پر از فایلهای JavaScript توضیح نمیدهد که چگونه یک سفارش به یک محموله تبدیل میشود. برای تطبیق دادن OpenSpec، باید به «قابلیتها» فکر کنید.
به دنبال عملیاتهای تجاری پایداری باشید که حتی اگر کل استک را به زبان دیگری بازنویسی کنید، همچنان باقی میمانند. در اکثر شرکتهای محصولمحور، این موارد بارها و بارها تکرار میشوند: سفارشها (Orders)، صورتحساب (Billing)، موجودی (Inventory)، مشتریان (Customers) و اعلانها (Notifications). پنج تا هشت مورد از این قابلیتهای اصلی را نام ببرید.
برای هر کدام، خود را مجبور کنید به پنج سوال مشخص پاسخ دهید: این قابلیت چه مشکل دنیای واقعی را حل میکند؟ کد واقعاً کجا قرار دارد—در یک سرویس، سه میکروسرویس، یا یک ماژول قدیمی (legacy) که هیچکس نمیخواهد به آن دست بزند؟ چه چیزی آن را فعال میکند: کلیک کاربر، یک کرونجاب (cron job) زمانبندی شده، یا یک وبهوک ورودی؟ چه دادهای وارد میشود و چه دادهای خارج میشود؟ و در نهایت، کدام سیستمهای دیگر به آن وابسته هستند، یعنی اگر این بخش از کار بیفتد، چه چیزی خراب میشود؟
بیرحمانه صادق باشید. اگر قابلیت «مشتریان» شما در یک مونولیت Rails، یک Node API و یک CRM خارجی پخش شده است، دقیقاً همان را بنویسید. نقشه شما باید شبیه به قلمرو واقعی باشد، نه رویای یک معمار.
حقیقت را بنویسید، نه لیست آرزوها را
خطرناکترین جمله در هر تلاش برای مستندسازی این است: «حالا که داریم این را مینویسیم، بهتر است آن را اصلاح هم بکنیم.» متوقف شوید. شما در حال بازطراحی فرآیند پرداخت (checkout) نیستید. شما در حال توصیف فرآیند پرداختی هستید که همین حالا در حال شارژ کردن کارتهای اعتباری واقعی است.
اگر ثبت یک سفارش باعث ثبت فوری پرداخت و سپس ارسال ایمیل از طریق یک کارگر پسزمینه (background worker) میشود، دقیقاً همان توالی را مستند کنید. صف رویدادی (event queue) را که قصد دارید در فصل آینده اضافه کنید، وارد نکنید. تظاهر نکنید که اعتبارسنجی در لبهی API انجام میشود، در حالی که در واقع در اعماق یک کلاس سرویس قرار دارد. دقت بسیار مهمتر از آرزوهاست.
مستندات نادرست بدتر از نبود مستندات است. مستندات غلط، نیروهای جدید را آموزش میدهند تا انتظار رفتاری را داشته باشند که وجود ندارد. آنها دستیارهای کدنویسی هوش مصنوعی را بر اساس تصورات و آرزوها به مسیرهای خیالی میبرند. وقتی مشخصات شما با محیط عملیاتی مطابقت داشته باشد، یک خط مبنای قابل اعتماد ایجاد میکنید. عیبیابی (debugging) سریعتر میشود زیرا دیگر درباره جریان «مقصود» حدس نمیزنید. بازآرایی (refactoring) ایمنتر میشود زیرا میدانید نقطه شروع واقعی است.
قراردادها را از APIهای خود استخراج کنید
نقاط پایانی (endpoints) API شما از قبل قوانین را اعمال میکنند؛ آنها فقط این قوانین را ضمنی نگه داشتهاند. تطبیق دادن OpenSpec به معنای آشکار کردن این قوانین است.
با ورودیها و اعتبارسنجی شروع کنید. یک endpoint واقعاً چه چیزی را میپذیرد؟ انواع داده (types)، فیلدهای مورد نیاز، حداکثر طول و وابستگیهای بین فیلدها را مستند کنید. سپس رفتار تجاری را توصیف کنید. آیا این فراخوانی یک رکورد ایجاد میکند، یک اثر جانبی (side effect) را فعال میکند، یا صرفاً وضعیت را در برابر سرویس دیگری اعتبارسنجی میکند؟ دقیق باشید.
در نهایت، پاسخها را فهرست کنید. موفقیت چه چیزی را برمیگرداند؟ کدهای خطای دقیق چیست و تحت چه شرایطی ظاهر میشوند؟ ننویسید «یک خطا برمیگرداند». بنویسید «زمانی که آدرس صورتحساب موجود نیست کد 422 و زمانی که موجودی قبلاً توسط فرآیند دیگری رزرو شده است، کد 409 را برمیگرداند». این سطح از دقت، یک مسیر مبهم را به قراردادی تبدیل میکند که تیمهای فرانتاند، مهندسان QA و ابزارهای خودکار میتوانند به آن اعتماد کنند.
به دنبال قوانین پنهان بگردید
Some of the most expensive knowledge in your system lives in the gaps. It is buried in conditional blocks inside service classes, tucked into database triggers, or written into stored procedures that no one has touched in two years. These are your business rules, and they are usually rediscovered during outages or by cornering the one engineer who has been there since the beginning.
Pull them into daylight. Start with the ones you already know. Orders above a certain value need manager approval before they proceed. Inactive user accounts cannot create new orders. Refunds are only permitted before settlement completes. Write each rule next to the capability it governs, in language clear enough that a product manager could read it without a translator.
When you centralize these rules, you do more than document them. You expose duplication. You reveal conflicts. And you give the entire team a single place to debate policy before someone commits a one-line change that accidentally violates a constraint you forgot existed.
Map the Plumbing
Modern systems run on events. An action in one service ripples through half a dozen others before anything visible reaches the user. You need to chart those ripples. Map the flow from one event to the next for your core workflows. Order created leads to inventory reserved, which waits for payment confirmed. Draw the full chain, even if some links feel fragile or use different protocols.
Do not stop at internal traffic. External services are part of your system whether you treat them that way or not. For each integration, record its purpose, how your application authenticates, and how it fails. Does the payment gateway timeout after thirty seconds and return a generic 500? Does the shipping API return malformed JSON on weekends? Does the identity provider revoke refresh tokens earlier than its own documentation claims? These details look trivial
