معمارية NestJS القابلة للتوسّع — من Module إلى Monorepo
بدأنا مشاريعنا الكبيرة على NestJS كـ «تطبيق واحد بمودولات». اليوم، أصبحت كلّ الأنظمة التي تتعدّى 10 مودولات تسكن داخل monorepo. هذه الوثيقة توضّح متى نعمل كلّ قفزة وما يربح الفريق منها.المرحلة 1: Single app + modular mod…

بدأنا مشاريعنا الكبيرة على NestJS كـ «تطبيق واحد بمودولات». اليوم، أصبحت كلّ الأنظمة التي تتعدّى 10 مودولات تسكن داخل monorepo. هذه الوثيقة توضّح متى نعمل كلّ قفزة وما يربح الفريق منها.
المرحلة 1: Single app + modular modules
- كل ميزة داخل module مستقلّ (Auth, Billing, Content…).
- Shared types/DTOs داخل
src/commonفقط. - اختبارات e2e داخل كل module لضمان عزله.
المرحلة 2: Monorepo + Libraries
حين يكبر النظام نستخدم أمر nest g app|lib. الـ libraries تصبح عقودًا مشتركة (types / DTOs / interfaces)، والـ apps مستقلّة قابلة للتشغيل بشكل منفصل.
الأنماط المعتمدة
- Controllers خفيفة: تستقبل DTO وتستدعي use-case / service.
- Service = Application: تنسّق بين repositories و domain.
- Repository: واجهة + تنفيذ TypeORM/Prisma — قابل للتبديل بـ fake.
- Domain: كائنات قيمة وقواعد أعمال نقيّة.
قاعدة الحدود: الـ domain لا يعرف عن DB، والـ infrastructure لا تحتوي منطق عمل. هذا هو الفرق الحقيقي بين DDD وMVC.
أدوات المراقبة
- Pino للـ logs المنظّمة.
- OpenTelemetry مع Tempo/Grafana للتتبّع الموزّع.
- Prometheus + exporters مخصّصة لمقاييس العمل.
خلاصة
معمارية قابلة للنمو ليست «framework»، بل حدود واضحة. رسم الحدود من اليوم الأول يجنّب إعادة الكتابة بعد 18 شهرًا.


