كل منتج أطلقته تجاوز قرارًا واحدًا على الأقل بشأن إطار العمل. أما قاعدة البيانات فتجاوزتها جميعًا. تتغير إصدارات Next.js، ويُستبدل ORM، ويتغير الفريق؛ لكن الصفوف تبقى، ومعها الافتراضات المضمّنة في المخطط. لذلك أتعامل مع SQL بوصفه العقد الحقيقي للمنتج، لا تفصيلًا تنفيذيًا مخفيًا خلف صنف repository.
يغطي Prisma جزءًا كبيرًا من عملي اليومي: CRUD محدد الأنواع، وترحيلات محفوظة في المستودع، ومخطط يستطيع الموظف الجديد قراءته. لكنني أقرأ SQL الذي يولّده أيضًا. إذا نفّذت صفحة قائمة استعلامًا لكل صف، أو احتاج تقرير إلى دالة نافذة، أو تطلبت لوحة معلومات GROUP BY على ثلاثة joins، أكتب الاستعلام يدويًا عبر $queryRaw أو أضعه في view. قبل أن يضيف أحد Redis، أفتح EXPLAIN ANALYZE. وراء معظم طلبات «نحتاج إلى cache» فهرس مفقود.
القيود أرخص ضمان جودة ستحصل عليه. تعمل NOT NULL وUNIQUE وFOREIGN KEY وCHECK عند كل كتابة ومن كل خدمة، حتى من سكربت يشغّله شخص يدويًا يوم الجمعة. يحمي Zod واجهة API، وتحمي قاعدة البيانات الحقيقة. تُحفظ الأموال بوحدات فرعية صحيحة أو باستخدام NUMERIC، وليس float أبدًا. تصل webhooks الدفع مرتين، لذا يحتاج مفتاح idempotency إلى فهرس فريد، لا إلى تعليق في handler.
تعيش أخطاء FinTech في التزامن. يقرأ طلبان الرصيد، ويقرران معًا أنه كافٍ، ثم يكتبان معًا؛ هذا تحديث مفقود لا يصلحه أي تحقق في الواجهة الأمامية. أفضل عبارة ذرية واحدة —UPDATE ... SET balance = balance - $1 WHERE id = $2 AND balance >= $1— ثم أتحقق من تغيّر صف واحد بالضبط. أو أستخدم معاملة فيها SELECT ... FOR UPDATE، مع جدول ledger إضافي فقط كي يمكن تفسير كل حركة لاحقًا. في الأنظمة التي عالجت أكثر من 1.5 مليون دولار، «القدرة على التفسير لاحقًا» هي جوهر العمل.
تُبنى الفهارس وفق الاستعلامات التي تنفذها فعلًا، لا الأعمدة التي تبدو مهمة. في الفهرس المركب تأتي أعمدة المساواة أولًا، ثم عمود النطاق أو الترتيب؛ وتناسب الفهارس الجزئية الصفوف «النشطة»، كما أن pagination بالمفتاح أفضل من OFFSET 50000. تُنفّذ الترحيلات على الجداول الحية على مراحل: إضافة العمود nullable، وملؤه على دفعات، ثم إضافة القيد؛ وإنشاء الفهرس باستخدام CONCURRENTLY. الترحيل الذي يقفل جدول الطلبات ظهرًا انقطاع خدمة مرفق بطلب دمج.
أرفض جدول entity-attribute-value «مرنًا» بدل المخطط، واستخدام JSONB لإخفاء الحقول الأساسية التي لا يريد أحد نمذجتها، وsoft delete في كل مكان دون مراعاة قيود التفرد، وإضافة cache أمام استعلام لم يفحصه أحد باستخدام EXPLAIN. إذا أرسلت صفحة بطيئة أو مخططًا غير مؤكد، فأرسل الاستعلام وأعداد الصفوف. سأرد بخطة التنفيذ والفهرس والقيد الأول الذي سأضيفه.
امنح المنتج القادم شخصاً يبقى معه.
هل أنت مستعد للبدء؟ أرسل لي رسالة؛ أنا متاح للبدء الآن والبقاء. عقود طويلة الأمد، لا تسليم خلال أسبوعين. لنتحدث عن مشروعك ومتطلباته وأفضل طريقة للمضي قدماً.