FinyxWatt
منصة تشغيل لمحطات الكهرباء والمياه: أربعة تطبيقات وخلفية واحدة
منصة متعددة المستأجرين تدير العمل اليومي لمحطات الكهرباء والمياه: العملاء والعدادات، القراءات، الفواتير، السندات، الصناديق، التقارير، والرسائل، ومبنية لتستمر في العمل حين ينقطع الاتصال.
زيارة الموقعfinyxwatt.com

- تطبيقات مترابطة
- 4
- سطر برمجي
- ~270k
- اختبار آلي
- 1,580+
- ترحيل لقاعدة البيانات
- 107
الشاشات
لوحة تحكم تطبيق المحطة مع المناطق والعملاء والأرصدة والفواتير والمهام التي تحتاج متابعة
شاشة تغطية الفوترة مع العملاء المفوترين وغير المفوترين والاستهلاك وقيمة الفواتير
القائمة الجانبية مع المستخدمين والعدادات الرئيسية وتغطية الفوترة واعتماد الأجهزة وسجل العمليات
لوحة المطور لإدارة الشركات مع حالتها وخطة الخدمة وإجراءات الإدارة
التقرير الإداري للشركة مع المستخدمين والعملاء والفواتير والسندات وصافي المتحصل
تطبيق مزود الرسائل متصلاً بطابور الشركة مع عدد الرسائل اليومية وشريحة الإرسال
واجهة الموقع التسويقي لمحطات الكهرباء والمياه
الواجهة الرئيسية على الجوال مع زر إنشاء محطة
المشكلة / الحل
المشكلة
تعمل محطة التوليد عبر سلسلة خطوات مترابطة: قراءة العداد، احتساب الفاتورة، إشعار العميل، تحصيل المبلغ، تسجيل السند، ثم رفع التقرير للإدارة. وحين تعيش كل خطوة في دفتر أو جدول أو هاتف منفصل، تنكسر السلسلة بصمت ولا أحد يعرف أين انكسرت.
- القراءات تُجمع ورقيًا ثم تُدخل يدويًا، ومن هنا كانت تبدأ معظم نزاعات الفواتير.
- الفوترة والتحصيل في مكانين مختلفين، فلم يكن لسؤال «هل دفع هذا العميل؟» إجابة واحدة موثوقة.
- رسائل العملاء تُرسل يدويًا من هواتف شخصية: بلا سجل إرسال، بلا إعادة محاولة، ومع تكرار متكرر.
- المحطات تفقد الاتصال كثيرًا، فالنظام السحابي البحت سيوقف الشباك.
- مالك عدة محطات لا يملك رؤية موحدة للنقد والديون.
الحل
قسّمت المنتج حسب من يستخدمه، ووضعت خلفه خلفية مملوكة تكون المرجع الوحيد للحقيقة.
- تطبيق المحطة للموظفين: القراءات، الفوترة، السندات، الصناديق، المناطق، والتقارير، ويعمل دون اتصال.
- تطبيق مزود الرسائل يحوّل هاتف أندرويد إلى بوابة إرسال موثوقة.
- لوحة المطور لتهيئة المحطات والاشتراكات وفوترة المنصة.
- تطبيق المشترك ليرى العميل فواتيره ومدفوعاته بنفسه.
- NestJS API وقاعدة PostgreSQL كمرجع للحقيقة، مع عزل المستأجرين داخل قاعدة البيانات نفسها.
- موقع عام، ونسخة للمياه من المنصة نفسها.
الهيكلة
الهيكلة
أربعة تطبيقات Flutter تتحدث مع API واحد. الخادم يفوّض كل عملية كتابة، والتطبيقات تحتفظ بنسخة محلية فيستمر العمل دون اتصال ثم يتزامن بأمان.
التطبيقات
- تطبيق المحطة
- تطبيق مزود الرسائل
- لوحة المطور
- تطبيق المشترك
الـ API
- NestJS 11 على Fastify
- تحديثات لحظية Socket.IO
- 4 عقود OpenAPI
البيانات والهوية
- PostgreSQL مع RLS
- Keycloak
- تخزين MinIO
التشغيل
- Docker Compose
- Caddy
- نسخ احتياطي لحظي WAL-G
الهندسة
قرارات هندسية
النسخة الأولى كانت على Firebase. نقلها إلى خلفية مملوكة دون إيقاف محطات تعمل فعليًا هو ما شكّل معظم القرارات التالية.
- الخادم هو صاحب القرار
- التطبيق يقترح والخادم يقرر. كل عملية مالية يتحقق منها الـ API ويفوّضها، ولا يُوثق بها كما وصلت من الهاتف.
- تزامن يبدأ من العمل دون اتصال
- تطبيق المحطة يعمل على نسخة SQLite محلية، ومفاتيح التفرد والإصدارات المتفائلة تجعل إعادة إرسال العمليات المؤجلة آمنة.
- المال يُضاف ولا يُعدَّل
- السجل المالي لا يُحدَّث في مكانه أبدًا. التصحيح قيد جديد، فيمكن تفسير كل رصيد.
- عزل المستأجرين في قاعدة البيانات
- سياسات RLS في PostgreSQL تفصل بيانات كل محطة حتى لو أخطأ كود التطبيق.
- هواتف البوابة بهوية حقيقية
- هواتف الرسائل تُسجَّل عبر TLS متبادل بمفاتيح لا تغادر Android Keystore أبدًا.
- رسالة واحدة بالضبط لكل فاتورة
- طابور آمن بالقفل، مهام غير قابلة للتكرار، تصنيف للأعطال، تباعد زمني، ومعالج احتياطي WorkManager.
- من Firebase إلى خلفية مملوكة
- الانتقال من Firestore إلى PostgreSQL تم عبر 107 ترحيلات مرتبة ومتحقق منها وطابور صادر (outbox)، والمحطات تعمل طوال الوقت.
- الاختبارات شبكة الأمان
- 1,150 اختبار Flutter و433 اختبارًا للخلفية تعمل في CI قبل أي نشر.
البنية
وحدات الخلفية
الـ API مقسّم إلى وحدة NestJS لكل مجال. هذه أهمها.
- financial
- الفواتير والسندات والسجل المالي غير القابل للتعديل
- cashboxes
- الصناديق والتحويلات وإقفال الورديات
- sync
- إعادة تنفيذ عمليات العمل دون اتصال مع التفرد والإصدارات
- outbox
- نشر الأحداث بموثوقية بعد كل حفظ
- realtime
- تحديثات Socket.IO للتطبيقات المتصلة
- sms_gateway
- طابور الرسائل الصادرة لهواتف المزوّد
- sms_enrollment
- تسجيل أجهزة البوابة عبر TLS متبادل
- client_portal
- فواتير ومدفوعات المشتركين
- platform_billing
- اشتراكات المحطات وفوترتها
- audit
- سجل الأمان والتغييرات
التقنيات
الجوال
- Flutter
- Dart
- تخزين SQLite محلي
- WorkManager
- إضافات Kotlin
الخلفية
- NestJS 11
- Fastify 5
- Kysely
- Socket.IO
- zod
البيانات والهوية
- PostgreSQL + RLS
- Keycloak
- MinIO
الويب
- Next.js 16
- React 19
- TypeScript
البنية التحتية
- Docker Compose
- Caddy
- WAL-G
- GitHub Actions
الجودة
- اختبارات Flutter
- Vitest
- عقود OpenAPI
النتيجة
أين وصل
تعمل FinyxWatt في محطات العملاء، وموقعها العام finyxwatt.com.
- تطبيق المحطة (الإصدار 1.6) قيد الاستخدام في محطات العملاء.
- صار إشعار العميل مسؤولية النظام وله سجل إرسال، بدل أن يكون شخصًا يحمل هاتفًا.
- القراءات والفواتير والسندات مترابطة، فأي سؤال عن فاتورة يُحل بسلسلة قابلة للتتبع.
- المنصة نفسها تخدم الآن محطات المياه إلى جانب الكهرباء.
الخطوات القادمة
- توسيع إطلاق تطبيق المشترك.
- تحويل الرسائل تلقائيًا بين عدة هواتف بوابة عند الفشل.
- تقارير مجدولة تصل لمالكي المحطات.
- دفع الفواتير أونلاين.
تحتاج شيئًا مثل هذا؟
أخبرني عن العملية التي تريد تنظيمها، وسأحوّلها إلى نظام واضح قبل كتابة أي سطر برمجي.
لنتحدث