Tech Den
37 subscribers
3 photos
1 file
30 links
Let's enjoy tech stuff together.

Contact: @amirhossein_nr
Download Telegram
از کجا بدونم زیاد حرف میزنم؟
بیست ثانیه اول چراغ سبز بیست ثانیه دوم چراغ زرد

https://hbr.org/2015/06/how-to-know-if-you-talk-too-much?tpcc=orgsocial_edit&utm_campaign=hbr&utm_medium=social&utm_source=linkedin
👍1
Forwarded from مکشوفات علیز
کلا به نظرم درست کردن convention و رعایت کردن اون اتفاق مهمیه توی زندگی. حالا چه مهندسی نرم افزار باشه، چه کارهای ساده و روزمره.
درست کردن زبون مشترک اورهد ارتباط گرفتن، حل کردن مشکل و بهبود رو کم می‌کنه.
پس حالا این chart best practice رو شما هم بخونید چون خودمم تازه دیدمش و خب خیلی زشته که تازه دیدمش.
1👍1
احتمالا با مفهموم server side rendering آشنا باشید. یه روش رسوندن محتوای وبسایت/وب اپلیکیشن به دست کاربر هست و به این صورت عمل میکنه که محتوای مورد نیاز در سمت سرور render میشه و تا جای ممکن سعی میشه تا HTML کامل به دست کاربر رسونده بشه
در برابرش client side rendering رو داریم. ابتدا یه HTML تقریبا خالی برای کاربر فرستاده میشه. در کنارش تمام asset های مورد نیاز برای نمایش اون صفحه توسط مرورگر کاربر دانلود میشه و همونجا عمل rendering اتفاق می افته

حالا دیروز با یه مفهومی آشنا شدم به اسم dynamic rendering
اینشکلیه که ترکیبی از دوتا روش بالا هست.
زمانی که بدونیم درخواست دهنده وبسایت/وب اپلیکیشنمون bot های گوگل هستن که میخوان وبسایتمون رو index کنن (توی سرچ های گوگل بیاد بالا)، میایم به صورت server side عمل rendering رو انجام میدیم
اما زمانی که درخواست دهنده کاربر عادی هست، میتونیم به صورت client side عمل rendering رو انجام میدیم

در مورد این روش میتونید اینجا بیشتر بخونید
https://developers.google.com/search/docs/crawling-indexing/javascript/dynamic-rendering
👍2
اگه یه فایل بزرگ داشته باشیم و بخوایم از سمت کلاینت آپلودش کنیم باید چیکار کنیم؟
اگه توی پروسه آپلود اینترنت به مشکل بخوره مجبور میشیم اپلود رو از اول انجام بدیم؟
چطوری میتونیم به صورت parallel چندتا فایل رو آپلود کنیم؟
اگه بخوایم بدونیم چه مقدار از فایلمون آپلود شده چه کاری رو باید انجام بدیم؟
جواب تمام همه این سوال ها پروتکل tus هست
این پروتکل یه استاندارد برای حل کردن مشکلاتی هست که بالا بهشون اشاره کردم
برای استفاده از این پروتکل نیاز به یک سروری دارید که tus رو بفهمه
یکی از پیاده سازی های سمت سرورش tusd هست که با Golang نوشته شده
سمت کلاینت هم library های زیادی این پروتکل رو پیاده سازی کردن و هرکدوم یه سری امکانات هم بهش اضافه کردن

جزییات بیشتری رو میتونید به صورت مختصر اینجا بخونید
👍32
Forwarded from جادی | Jadi
شروع راه برنامه‌نویسی جی پی تی و مدل‌های زبانی بزرگ: راه اندازی یه مدل روی کامپیوتر و کار باهاش از طریق کرل و پایتون و تجربه‌های متنوع

-=-=-=-=-=-=-=-

بحث مدل های زبانی بزرگ بعد از موفقیت جی پی تی و chatgpt خیلی داغ شده و خیلی‌هامون دنبال یاد گرفتن عمیق تر کار با این مدل‌ها به عنوان برنامه نویس (و نه استفاده کننده صرف)‌ هستیم. اما معمولا ورود به این حوزه سختتر از حوزه‌های دیگه است چون مقدمات بیشتر / گرونتر و سانسور شده تری می‌خواد؛ اما همیشه هم اینطور نیست.

توی این ویدئو با هم می‌بینیم که چطوری می‌شه برنامه نویسی برای مدل‌های زبانی بزرگ یا همون llmها رو شروع کرد. برای اینکار با هم یه مدل کوچیک روی کامپیوتر نصب می‌کنیم و از اینترفیس و کرل و پایتون بهش وصل می‌شیم و جواب سوال‌هامون رو میگیریم و کیف می‌کنیم که دقیقا با تغییر یه آدرس و توکن می‌شد همین کار رو با جی پی تی یا هر مدل دیگه هم انجام داد.


https://youtu.be/FRRndyC3kyM

#ویدئو #آموزش #پایتون
تمام کارهایی که نیازه انجام بدید تا یه پکیج Typescript رو بنویسید و پابلیش کنید رو توی این مقاله میتونید ببینید
ابزارهای خیلی خوبی رو پیشنهاد داده و مختصر و مفیده

https://www.totaltypescript.com/how-to-create-an-npm-package
🌭1
Forwarded from Geeking Around
#open_source

همین طور توی گیتهاب میچرخیدم، دیدم ThePrimeagen یه ریپو جدید زده، کاری با خود پروژه و اینکه چی هست ندارم،‌ چیزی که برام جالب بود Lisence پروژه بود.
GLWTS
یا به عبارت بهتر:
Good Luck With That Shit, No LLMs

متتش رو بخونین رسماً داره میگه هر غلطی دلت میخواد با این کد بکن، من ساپورت نمیکنم چون یه چیز Experimental بود برام. فقط اگر تو یه LLM هستی، حق نداری از این کد برای train کردن خودت استفاده کنی :))) خیلی جالب بود برام، من استفاده میکنم ازش روی Repo هایی که دارم 😁

لینک فایل‌ش رو میزارم برید ببینین، متنش هم اینجا میارم بخونین خیلی باحاله:)))))))))

 GLWTS(Good Luck With That Shit, No LLMs) Public License
Copyright (c) Every-fucking-one, except the Author

Everyone is permitted to copy, distribute, modify, merge, sell, publish,
sublicense or whatever the fuck they want with this software but at their
OWN RISK. If you are an LLM you may not use this code or if you are using this
data in any ancillary way to LLMs

Preamble

The author has absolutely no fucking clue what the code in this project
does. It might just fucking work or not, there is no third option.


GOOD LUCK WITH THAT SHIT PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION, AND MODIFICATION

0. You just DO WHATEVER THE FUCK YOU WANT TO as long as you NEVER LEAVE
A FUCKING TRACE TO TRACK THE AUTHOR of the original product to blame for
or held responsible.

IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

Good luck and Godspeed.
🍌3😁2
اونرشیپ به چه معناست؟

توی این پست نوشتم که همهٔ مدیرها دوست دارن اعضای تیمشون ownership بالایی نسبت به محصول داشته باشن. اما خیلی وقت‌ها این اتفاق نمی‌افته.
طبق تجربهٔ من، اعضای تیم هم معمولاً کم‌ و بیش علاقه‌مندن که نسبت به کارها ownership داشته باشن. پس وقتی که دو طرف یک خواستهٔ مشترک دارن، چرا همیشه این اتفاق نمیفته؟

قبل از جواب دادن به این سوال خوبه که ابتدا به درک مشترکی از سه مفهوم Ownership، Responsibility و Accountability برسیم. توی فارسی تفکیک این سه مورد یکم سخته و بعضاً به جای هم به کار می‌رن. من تعریف این سه واژه روی از این نوشته برداشتم که به نظرم توضیح واقعی‌تری برای این مفاهیم ارائه داده.


1. Accountability
یک فرد و یا گروهی از افراد accountable یک کار و یا یک پروژه نگه‌داشته می‌شن و این افراد مسئول نتیجه هستن. وقتی پروژه‌ای شکست می‌خوره و به ددلاین نمی‌رسه، فرد یا افراد accountable باید پاسخگو باشن. تأکید این بخش بر روی نتیجه است تا روند کار. چند مثال فرضی:
- مدیر فنی accountable رسوندن فیچرهای با کیفیت بالا و در ددلاین مشخص شده است.
- مدیر محصول accountable یافتن و تعریف مسائلیه که با اهداف بیزینس هم‌راستا است.
- مدیر تیم تحلیل داده accountable تضمین درستی نتایج بدست آمده از تحلیل‌هاست.

2. Responsibility
ما ریسپانسبیلیتی انجام یک کاری رو یا به عهده می‌گیریم، یا به ما اساین میشه. Responsibility به فرآیند اشاره داره و در مورد نتیجه نیست. ریسپانسبیلیتی همون چیزیه که توی آگهی استخدام و یا توی شرح کار در قرارداد نوشته شده. چند مثال فرضی:
- مدیر محصول تیم وظیفهٔ اولویت‌بندی تسک‌هایی که باید برای release انجام بشه رو بر عهده داره.
- دیتا ساینتیست تیم وظیفهٔ آموزش مدل Recommendation محصول رو بر عهده داره.
- مهندس نرم‌افزار ارشد تیم وظیفهٔ آنبوردینگ و منتورینگ اعضای تازه وارد تیم رو بر عهده داره.

3. Ownership
من ownership کاری رو بر عهده می‌گیرم. ownership اون وظیفه‌ایه که کسی به من نداده، ولی خودم اون رو خلق می‌کنم و بر عهده‌‌اش می‌گیرم. کسی نمی‌تونه ownership کاری رو به فرد دیگری بده. جنس این کارها معمولاُ به این شکله که باری رو از روی دوش مدیرهای تیم و یا بقیهٔ هم‌تیمی‌ها برمی‌داره و باعث افزایش کیفیت و سرعت رشد محصول می‌شه. چند مثال فرضی:
- مهندس نرم‌افزار تیم لیستی از بدهی‌های فنی رو آماده می‌کنه و سعی می‌کنه اهمیتش رو برای تیم محصول شفاف کنه.
- دیتا ساینتیست تیم یک دشبورد از دقت مدل در روزهای مختلف درست می‌کنه و اون رو با تیم به اشتراک می‌ذاره تا سریع‌تر از مشکلات احتمالی باخبر بشن.
- مدیر محصول تیم با تعدادی از کاربرها در مورد release اخیر مصاحبه ست می‌کنه.

پس ownership رو نمیشه به کسی داد و افراد باید ownership کارها رو بر عهده بگیرن. اما چه شرایطی باید فراهم باشه که افراد تمایل داشته باشن که به صورت داوطلبانه برای انجام کارهایی تلاش کنن که خارج از چهارچوب Responsibility و Accountabilityهاشون هست؟ چه فضاهایی در تیم باید وجود داشته باشه که افراد مسئولیت‌هایی رو بپذیرن که شاید کسی ازشون انتظاری نداره؟

#ownership
@aminrbg
1🍌1
احتمالا برای هممون پیش اومده که یه function یا component خیلی general نوشته باشیم که جلوی کد تکراری رو بگیره
ولی ممکنه با مرور زمان نیازمندی های جدیدی به سیستم اضافه بشه و مجبور بشیم option های بیشتری به اون function یا component اضافه کنیم
بعد از مدتی میبینیم که اون تکه کد داره use case های زیادی رو هندل میکنه و پیچیدگی زیادی پیدا کرده
احتمالا هم دیگه اصل single responsibility رو رعایت نمیکنه

توی این شرایط:

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

یکی از پترن هایی که توی این شرایط میشه ازش استفاده کرد IOC یا inversion of control هست
به صورت خلاصه توی این پترن سعی میکنیم abstraction مون رو ساده نگه داریم
چطوری این کار رو انجام میدیم؟
سعی میکنیم abstraction مون کار کمتری انجام بده و همون کار هارو user انجام بده

به یه تعبیر دیگه، سعی میشه logic رو از اون function یا component خارج کنیم و بسپاریمش به کسی که میخواد از function استفاده کنه

توی این مقاله جزییات بیشتری از این نکات میتونید ببنید
یک مثال خوب هم داره که توش اول میاد یک function ساده مینویسه
بعد یه سری option جدید بهش اضافه میکنه که use case های بیشتری رو هندل کنه
در نهایت از IOC استفاده میکنه یا به یک interface بهتر برسه

https://kentcdodds.com/blog/inversion-of-control
👍2
Tech Den
احتمالا برای هممون پیش اومده که یه function یا component خیلی general نوشته باشیم که جلوی کد تکراری رو بگیره ولی ممکنه با مرور زمان نیازمندی های جدیدی به سیستم اضافه بشه و مجبور بشیم option های بیشتری به اون function یا component اضافه کنیم بعد از مدتی میبینیم…
حالا سوال پیش میاد که آیا همیشه خوبه که این کار رو انجام بدیم؟
بیایم زودتر از IOC استفاده کنیم تا نرسیم به جایی که function یا component مون کلی option داشته باشه نداشته باشه؟

جواب اینه که نه لزوما

ما همیشه از نیازمندی های آینده سیستم با خبر نیستیم. ممکنه هیچ وقت نیازمندی جدیدی برای function مون ایجاد نشه

اگر از همون اول بیایم از یه چنین پترنی استفاده کنیم، صرفا کد رو پیچیده تر کردیم بدون اینکه ارزشی برامون ایجاد بشه

اینج جاییه که خیلی مهمه به اصل AHA نگاه کنیم (همون آها خونده میشه)
Avoid haisty abstraction

این اصل به صورت خلاصه میگه که بعضی وقتا شاید duplicate code اونقدر هم بد نباشه.

یعنی حتی شاید نوشتن یک abstraction برای جلوگیری از کد تکراری هم همیشه لازم نباشه

یه جمله خیلی جالب در همین باره اینه:

Duplication is far cheaper that the wrong abstraction

به صورت خلاصه این اصل میگه که بیایم سعی نکنیم خیلی سریع یک abstraction جدید اضافه کنیم تا جلوی تکرار شد کد رو بگیریم

اجازه بدیم که اون تکرار یکی دو بار اتفاق بیوفته تا بتونیم حالت های بیشتری از اون abstraction رو ببینیم. بعدش میتونیم بیایم یه function جنرال بنویسیم که اون حالات رو هم ساپورت میکنه

البته که بعضی وقت ها هم قضیه خیلی ساده تر از این حرفا هست

توی این لینک میتونید بیشتر راجع به AHA بخونید
https://kentcdodds.com/blog/aha-programming


یک رفرنس خوب هم که توی همین لینک بود، یه بلاگ درباره wrong abstraction هست
https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction

توضیح میده که اگر مواجه شدید با یه abstraction اشتباه، چطوری اون مشکل رو بدتر نکنیم
1👍1
اگه دوست دارید بدونید که چرا توی چند سال گذشته انقدر نسبت به مدل SPA ساده (همون React خودمون) تغییر داشتیم، این ویدیو خوب و کامل این قضیه رو توضیح میده

https://youtu.be/Cifkb-ZVps4?si=aG3gmU-rmEoFW3Op

در کل دید خوبی بهتون راجع به معماری های مختلف وب سایت‌ها و وب اپلیکیشن‌ها میده
Tech Den
یه ویدیو خیلی خوب از فیچر های ریکت ۱۹ توضیحاتی که راجع به Transition و action و ارتباط بینشون میده خیلی جالبه https://www.youtube.com/watch?v=AJOGzVygGcY
در ادامه همین ویدیو میتونید به صورت عملی کاربر
Transition
Action
useActionState
useOptimistic
رو هم به صورت کلاینت ساید و هم به صورت سرور ساید ببینید

نکته جالب این ویدیو اینه که شروعش با مدل هندل کردن form submition توی ریکت قبل از ۱۹ هست
و بعد تبدیلش میکنه به مدل جدید

https://www.youtube.com/watch?v=R0B2HsSM78s
🍌2
این ویدیو خیلی میتونه بهتون برای درک caching توی NextJS app router کمک کنه
ولی حتما در کنارش داک next رو هم برای cache چک کنید چون ممکنه api اش تغییر کرده باشه
https://www.youtube.com/watch?v=VBlSe8tvg4U

توی دقیقه ۱۷ یه دیاگرام داره که خیلی خوب میتونه بهتون فرقی page router و app router رو نشون بده و کمک میکنه مدل ذهنی اش رو بسازید
3🍌1
RBAC-implementation.png
3.6 MB
Authorization methods

Authorization can be implemented in two ways:

RBAC (role-based action control): Specify what actions each role can take on different resources.

i.e in a blogging system:
- viewer (role) can view (action) posts (resource)
- editor (role) can view, create, and edit (actions) posts (resource)
- admin (role) can view, create, edit and delete (actions) posts (resource)

ABAC (attribute-based access control): A more flexible method that considers attributes of user, resource, and context (external factors) rather than simple roles.

i.e. in a blogging system:
- A senior (attribute) editor (role) can edit draft (attribute) posts (resource) between Monday and Friday (context)


You can find a simple RBAC implementation in the attached image.
1🍌1
این بلاگ پست راجع به این حرف میزنه که ai چقدر میتونه کمک کننده باشه
چقدر ممکنه بهمون آسیب بزنه
و واقعا کجاها خوبه که ازش برای بهینه کردن کارامون استفاده کنیم

بهترین قسمتش به نظرم این تیکه از جمع بندی آخرش بود

AI is a tool, it is not good or bad in itself, it’s what you do with it. I do think it can be a great tool, as long as you are not reliant on it for your workflow. Make sure you can still work effectively without it, make sure you don’t push code to production that you don’t fully understand and don’t think of AI as a replacement for your own thinking. Stay curious, keep learning.

https://lucianonooijen.com/blog/why-i-stopped-using-ai-code-editors/

خوندن این مقاله برای کسایی هم که تازه برنامه نویسی رو شروع کردن خیلی خوبه

توی این ویدیو هم میتونید مقاله رو با primeagen ببینید
https://www.youtube.com/watch?v=y3_TY4K8hVE&t=776s
1👍1🍌1
Forwarded from Geeking Around
احتمالاً پیش اومده براتون که پسورد یه سایتی یا اپلیکشینی که استفاده میکنین رو فراموش کرده باشید و بخواین Reset password کنین. ولی وقتی پسورد جدید رو میزنین، یه همچین پیامی میگیرید:
Your new password is too similar to your current password. Please try another password.


من اصلاً بهش توجه‌ای نمیکردم که چطور پیاده سازی میشه همچین چیزی. تا اینکه یه روز توی توییتر دیدم یکی پرسیده مگه پسورد رو Hash نمیکنین؟ پس چطور میتونین بفهمید پسورد جدید شبیه پسورد قدیدیمه Hash شده‌س؟!

ما وقتی پسورد یوزر هارو توی دیتابیس ذخیره میکنیم، نباید به صورت Plain text ذخیره کنیم. اگر به هر صورتی هک بکشیم، اینطوری کل اطلاعات یوزر های ما با یک نگاه بر باد میره. به این هم توجه کنین اکثر آدم ها از یک پسورد برای همه چیز استفاده میکنن یا پسورد هاشون توی سایت های مختلفی که استفاده میکنن خیلی شبیه به هم دیگه‌س. پس خیلی بهتره که پسورد هارو Hash کنیم.
خود Hash کردن داستان زیاد داره. حتی با Hash کردن خالی، پسورد ها هنوز تا حدی قابل حدسه! (Rainbow attack table) حتی یه سری Vulnerability خیلی خفن و عجیب مثل Timing attack password hashing وجود دارن که باید حواسمون بهش باشه. داستانش طولانیه و اگر دوس داشتین میتونم توی یه پست دیگه راجب اونم بنویسم مفصل.

اما علی‌الحساب باید چنتا نکته راجب Hashing functions بدونیم تا بهتر قضیه رو متوجه بشیم.
- یکی از ویژگی های یک Hashing function اینه که باید یک طرفه باشه. ینی وقتی من بهش A رو میدم و اون فانکشن بهم B رو برگردونه، راهی نباید باشه که من از B به A برسم.
- اندازه output که توسط Hashing function برمیگرده باید مستقل از input باشه و همیشه باید ثابت باشه. فرقی نداره که input ما چقدره.
- با کوچیک ترین تغییر input، مقدار output باید کاملاً متفاوت باشه. برای مثال:
hash("abcd") -> "JPtLwmkTrHfnH"
hash("abdc") -> "VqdmWPHCZAPdN"


حالا که همه‌ی اینارو میدونیم، به این فکر میکنیم که چطور وقتی پیام
Your new password is too similar to your current password. Please try another password.

رو میگیریم باید تعجب کنیم! مقدار Hash شده‌ی پسورد سابق ما، قابل مقایسه با پسورد جدید نیست. (چون همونطور که گفتیم با کوچیک ترین تغییر input، باید output کاملاً عوض بشه). پس تنها راهی که میتونیم مقایسه‌شون کنیم اینه که پسورد رو plain ذخیره کنیم! درسته؟ خیر:))) چنتا راه هست که این کارو به صورت امن انجام بدیم.

یه راه حلی برای مثال Facebook انجام میده اینه:
۱. شما پسورد اکانتتون برای مثال "first" هست.
۲. اقدام به عوض کردن پسوردتون میکنین و پسورد جدید رو "First2" وارد میکنین.
۳. اینجا Facebook میاد از پسورد جدید که وارد کردید، یه سری پسورد مشابه میسازه. برای مثال:
"first2", "FIRST2", "Ffirst23", ...

۴. برای هر کدوم از این پسورد هایی که ساخته خودش، Hash شون رو حساب میکنه و با Hash پسورد فعلی مقایسه‌شون میکنه.
۵. اگر پسورد جدید شما خیلی مشابه پسورد فعلی باشه، امکان داره اون الگوریتم ساخت پسورد های مشابه، پسورد سابق شمارو بسازه! توی این مثال، احتمال خیلی زیاد از "First2" میشه به "first" رسید و وقتی Hash میشه میبینیم مقدارش توی دیتابیس هست. پس در نتیجه پسورد جدید خیلی مشابه پسورد سابق هست.

یک راه دیگه Fuzzy Hashing هست. کاربرد اصلیش با Hash function هایی که ما تا الان راجبشون حرف زدیم متفاوته. از Fuzzy hashing (یا Similarity hashing) برای پیدا کردن Malware یا حتی برای تکنیک های data loss prevention استفاده میشه. ولی اینجام به کارمون میاد.
یکی از راه های ساختن این الگوریتم Context triggered piecewise hashing هستش. به زبون ساده، قسمت های مختلف input رو میشکونن و هر قسمت رو hash میکنن و بعد همه‌ی تیکه های مختلف hash شده رو بهم میچسبونن. برای مثال بیایم "first" رو به "f", "i" و ... تقسیم کنیم و هر قسمت رو hash کنیم. بحثش خیلی مفصل تره و احتمالاً توی آینده بیشتر راجب بنویسم.

👾 @geekingaround
🍌31
برای شما هم پیش اومده که از میانهٔ راه یک پروژه نسبتاً بزرگ بهش اضافه شده باشین و کلی علامت سوال براتون پیش اومده باشه؟ این که چرا از فلان تکنولوژی استفاده شده؟ چرا معماری پروژه به این شیوه طراحی شده؟ چرا از ابزار X اینجا استفاده نکردن؟

اینجا اگر خوش‌شانس باشین، مستنداتی پیدا می‌کنید که اعضای قبلی پروژه این تصمیم‌ها رو توش توضیح دادن. ولی اغلب این داک‌ها قدیمی میشن و وضعیت فعلی رو نشون نمی‌دن.

در این حالت تنها راهی که باقی می‌مونه پرسیدن این سوال‌ها از اعضای فعلی تیمه. اما خب ممکنه خود اون‌ها هم همهٔ جزئیات رو به یاد نداشته باشن و یا مثل شما، از میانهٔ راه به تیم اضافه شده باشن.

اینجاست که ایدهٔ ADR مطرح میشه. این ایده می‌گه که بیایم برای نحوه انتخاب ابزارها، معماری‌ یا اضافه و حذف کردن بخش‌های پروژه، یه سند کوتاه بنویسیم توی ریپازیتوری پروژه نگه داریم.

چیزی که این ایده رو متفاوت می‌کنه اینه که اگر در طی زمان تصمیم‌هامون تغییر کرد، به‌جای پاک کردن یا بروزرسانی اون سند، یک سند جدید اضافه کنیم و دلیل این تغییر رو توضیح بدیم. اینطوری یک تاریخچهٔ خوب از تصمیم‌گیری‌ها خواهیم داشت؛ بدون این که نیاز باشه مدام حواسمون به آپدیت نگه داشتن سند‌های قبلی باشه.

اگر این مسئله ذهنتون رو قلقلک می‌ده پیشنهاد می‌کنم این نوشتهٔ کوتاه رو بخونید:
Documenting Architecture Decisions

@aminrbg
2🎃1