نظام شامل لإدارة مخزون الفنيين مبني بتقنيات حديثة، يوفر تتبع مزدوج للمخزون (الثابت والمتحرك) مع واجهة باللغة العربية وتصميم متجاوب بالكامل.
- نظام مخزون مزدوج: تتبع منفصل للمخزون الثابت (Fixed) والمخزون المتحرك (Moving)
- إدارة المستخدمين: نظام صلاحيات متقدم (Admin/Employee)
- تتبع الفنيين: إدارة مفصلة لمخزون كل فني على حدة
- تنبيهات ذكية: إشعارات تلقائية عند انخفاض المخزون بألوان مميزة
- سجل المعاملات: تتبع كامل لجميع العمليات مع الأسباب
- تصدير Excel: إمكانية تصدير التقارير بصيغة Excel احترافية
- تصميم متجاوب: يعمل بكفاءة على جميع الأجهزة (جوال، تابلت، كمبيوتر)
- واجهة عربية: دعم كامل للغة العربية مع تخطيط RTL
- Node.js 20 أو أحدث
- PostgreSQL Database
- npm أو yarn
# تثبيت المكتبات
npm install
# إعداد قاعدة البيانات
npm run db:push
# تشغيل المشروع في بيئة التطوير
npm run devDATABASE_URL=postgresql://user:password@host:port/database
SESSION_SECRET=your-secret-key
PORT=5000
NODE_ENV=development- افتح التطبيق على المتصفح
- أدخل اسم المستخدم وكلمة المرور
- اضغط على "تسجيل الدخول"
ملاحظة: يجب على المسؤول إنشاء حساب المستخدم الأول من قاعدة البيانات
- نظرة عامة على المخزون: عرض مخزون جميع الفنيين
- تنبيهات ملونة:
- 🟢 أخضر: المخزون جيد (أكثر من 70%)
- 🟡 أصفر: تحذير (30-70%)
- 🔴 أحمر: حرج (أقل من 30%)
- إحصائيات مباشرة: عدد الفنيين، إجمالي المخزون، التنبيهات
- عرض المخزون الخاص به فقط
- إمكانية تحديث المخزون المتحرك
- عرض سجل المعاملات الخاصة به
الوصول: القائمة الجانبية > المخزون الثابت
- اختر الفني من القائمة
- أدخل الكميات بالصناديق والوحدات:
- أجهزة N950: صناديق ووحدات
- أجهزة I900: صناديق ووحدات
- أوراق رول: صناديق ووحدات
- ملصقات: صناديق ووحدات
- شرائح موبايلي: صناديق ووحدات
- شرائح STC: صناديق ووحدات
- حدد نسب التنبيه (اختياري)
- اضغط "حفظ"
ملاحظة هامة: المخزون الثابت يُدخل يدوياً ولا يتأثر إلا بالتحديثات المباشرة
الوصول: القائمة الجانبية > المخزون المتحرك
- افتح صفحة المخزون المتحرك
- اختر "تحديث المخزون"
- أدخل الكميات المراد نقلها
- أدخل السبب (إجباري)
- اضغط "تحويل إلى المخزون المتحرك"
ملاحظة: عند النقل من الثابت للمتحرك:
- ✅ يتم الخصم تلقائياً من المخزون الثابت
- ✅ يتم الإضافة للمخزون المتحرك
- ✅ يتم تسجيل العملية في السجل
- اختر "تحديث المخزون"
- اختر نوع العملية: "إضافة" أو "خصم"
- أدخل الكميات
- أدخل السبب
- اضغط "حفظ"
ملاحظة: التحديثات المباشرة على المخزون المتحرك لا تؤثر على المخزون الثابت
الوصول: القائمة الجانبية > المستخدمين (Admin فقط)
- اضغط "إضافة مستخدم"
- املأ البيانات:
- الاسم الكامل (إجباري)
- اسم المستخدم (إجباري، فريد)
- البريد الإلكتروني (إجباري، فريد)
- كلمة المرور (إجباري)
- المدينة (اختياري)
- الصلاحية: Admin أو Employee
- المنطقة (اختياري)
- اضغط "حفظ"
- اضغط على أيقونة التعديل بجانب المستخدم
- عدّل البيانات المطلوبة
- اضغط "حفظ"
- اضغط على أيقونة الحذف
- أكد عملية الحذف
الوصول: القائمة الجانبية > المناطق (Admin فقط)
- اضغط "إضافة منطقة"
- أدخل اسم المنطقة والوصف
- اضغط "حفظ"
ملاحظة: لا يمكن حذف منطقة تحتوي على مستخدمين أو مخزون
الوصول: القائمة الجانبية > الأجهزة المسحوبة
- اضغط "إضافة جهاز مسحوب"
- املأ التفاصيل:
- المدينة واسم الفني
- رقم الجهاز والسيريال
- حالة البطارية (جيدة/متوسطة/سيئة)
- كابل وراس الشاحن (موجود/غير موجود)
- وجود شريحة (نعم/لا)
- نوع الشريحة (Mobily/STC/غير محدد)
- وصف العطل
- ملاحظات
- اضغط "حفظ"
الوصول: القائمة الجانبية > المعاملات
- حسب النوع: إضافة/سحب/الكل
- حسب المستخدم: اختر مستخدم محدد
- حسب المنطقة: اختر منطقة محددة
- حسب التاريخ: نطاق زمني محدد
- البحث: ابحث بالكلمات المفتاحية
- اسم الصنف
- نوع العملية (إضافة/سحب)
- الكمية
- المستخدم
- المنطقة
- السبب
- التاريخ والوقت
- اذهب إلى صفحة المخزون المتحرك
- اضغط "تصدير إلى Excel"
- سيتم تحميل ملف Excel يحتوي على:
- اسم الفني
- المدينة
- جميع الأصناف والكميات
- حالة التنبيه
- التاريخ
- اذهب إلى صفحة المعاملات
- اختر الفلاتر المطلوبة
- اضغط "تصدير إلى Excel"
- سيتم تحميل ملف يحتوي على:
- جميع المعاملات المفلترة
- التفاصيل الكاملة
- الإحصائيات
- React 18: مكتبة بناء واجهات المستخدم
- TypeScript: لغة البرمجة مع دعم الأنواع
- Tailwind CSS: إطار عمل CSS
- shadcn/ui + Radix UI: مكتبة مكونات UI
- TanStack React Query: إدارة حالة الخادم
- Wouter: نظام التوجيه
- React Hook Form + Zod: إدارة النماذج والتحقق
- ExcelJS: تصدير ملفات Excel
- Lucide React: الأيقونات
- Node.js: بيئة تشغيل JavaScript
- Express.js: إطار عمل الخادم
- PostgreSQL: قاعدة البيانات
- Drizzle ORM: أداة ORM للتعامل مع قاعدة البيانات
- Passport.js: نظام المصادقة
- Express Session: إدارة الجلسات
- Vite: أداة بناء سريعة
- ESBuild: مترجم JavaScript سريع
- TypeScript Compiler: فحص الأنواع
├── client/ # Frontend Application
│ ├── src/
│ │ ├── components/ # React Components
│ │ │ └── ui/ # shadcn UI Components
│ │ ├── pages/ # Page Components
│ │ ├── lib/ # Utilities & Config
│ │ ├── hooks/ # Custom React Hooks
│ │ └── App.tsx # Main App Component
│ └── index.html
│
├── server/ # Backend Application
│ ├── index.ts # Server Entry Point
│ ├── routes.ts # API Routes
│ ├── storage.ts # Storage Interface
│ ├── database-storage.ts # Database Implementation
│ ├── auth.ts # Authentication Logic
│ └── vite.ts # Vite Integration
│
├── shared/ # Shared Code
│ └── schema.ts # Database Schema & Types
│
└── package.json # Dependencies
- id: UUID (Primary Key)
- username: TEXT (Unique)
- email: TEXT (Unique)
- password: TEXT (Hashed)
- fullName: TEXT
- city: TEXT
- role: TEXT (admin/employee)
- regionId: UUID (Foreign Key)
- isActive: BOOLEAN
- createdAt: TIMESTAMP
- updatedAt: TIMESTAMP- id: UUID (Primary Key)
- name: TEXT
- description: TEXT
- isActive: BOOLEAN
- createdAt: TIMESTAMP
- updatedAt: TIMESTAMP- id: UUID (Primary Key)
- technicianId: UUID (Foreign Key → users)
- n950Boxes: INTEGER
- n950Units: INTEGER
- i900Boxes: INTEGER
- i900Units: INTEGER
- rollPaperBoxes: INTEGER
- rollPaperUnits: INTEGER
- stickersBoxes: INTEGER
- stickersUnits: INTEGER
- mobilySimBoxes: INTEGER
- mobilySimUnits: INTEGER
- stcSimBoxes: INTEGER
- stcSimUnits: INTEGER
- lowStockThreshold: INTEGER (%)
- criticalStockThreshold: INTEGER (%)
- createdAt: TIMESTAMP
- updatedAt: TIMESTAMP- id: UUID (Primary Key)
- technicianName: TEXT
- city: TEXT
- n950Devices: INTEGER
- i900Devices: INTEGER
- rollPaper: INTEGER
- stickers: INTEGER
- mobilySim: INTEGER
- stcSim: INTEGER
- notes: TEXT
- createdBy: UUID (Foreign Key)
- regionId: UUID (Foreign Key)
- createdAt: TIMESTAMP
- updatedAt: TIMESTAMP- id: UUID (Primary Key)
- technicianId: UUID (Foreign Key)
- movementType: TEXT (transfer/direct_update)
- itemType: TEXT (n950/i900/...)
- quantityChanged: INTEGER
- fromInventory: TEXT (fixed/moving)
- toInventory: TEXT (fixed/moving)
- reason: TEXT
- createdBy: UUID (Foreign Key)
- createdAt: TIMESTAMP- id: UUID (Primary Key)
- city: TEXT
- technicianName: TEXT
- terminalId: TEXT
- serialNumber: TEXT
- battery: TEXT
- chargerCable: TEXT
- chargerHead: TEXT
- hasSim: TEXT
- simCardType: TEXT
- damagePart: TEXT
- notes: TEXT
- createdBy: UUID (Foreign Key)
- regionId: UUID (Foreign Key)
- createdAt: TIMESTAMP
- updatedAt: TIMESTAMP- id: UUID (Primary Key)
- name: TEXT
- type: TEXT (devices/sim/papers)
- unit: TEXT
- quantity: INTEGER
- minThreshold: INTEGER
- technicianName: TEXT
- city: TEXT
- regionId: UUID (Foreign Key)
- createdAt: TIMESTAMP
- updatedAt: TIMESTAMP- id: UUID (Primary Key)
- itemId: UUID (Foreign Key)
- userId: UUID (Foreign Key)
- type: TEXT (add/withdraw)
- quantity: INTEGER
- reason: TEXT
- createdAt: TIMESTAMPusers ←→ regions (Many to One)
users ←→ technician_fixed_inventories (One to One)
users ←→ stock_movements (One to Many)
users ←→ withdrawn_devices (One to Many)
users ←→ transactions (One to Many)
regions ←→ inventory_items (One to Many)
inventory_items ←→ transactions (One to Many)
Development: http://localhost:5000/api
Production: https://your-domain/api
تسجيل الدخول
Request:
{
"username": "admin",
"password": "password123"
}
Response:
{
"success": true,
"user": {
"id": "uuid",
"username": "admin",
"role": "admin",
...
}
}تسجيل الخروج
الحصول على بيانات المستخدم الحالي
الحصول على جميع المستخدمين (Admin فقط)
إنشاء مستخدم جديد (Admin فقط)
{
"username": "john_doe",
"email": "john@example.com",
"password": "password123",
"fullName": "John Doe",
"role": "employee",
"city": "Riyadh",
"regionId": "uuid"
}تحديث مستخدم
حذف مستخدم
الحصول على المخزون الثابت لفني
إنشاء/تحديث المخزون الثابت
الحصول على جميع المخزون المتحرك
الحصول على مخزون فني محدد
إنشاء مخزون متحرك
تحديث المخزون المتحرك
نقل من الثابت للمتحرك
{
"technicianId": "uuid",
"quantities": {
"n950": 5,
"i900": 3,
...
},
"reason": "نقل مخزون للعمل الميداني"
}تحديث مباشر للمخزون المتحرك
الحصول على جميع المناطق
إنشاء منطقة جديدة
تحديث منطقة
حذف منطقة
الحصول على جميع الأجهزة المسحوبة
تسجيل جهاز مسحوب
تحديث جهاز مسحوب
حذف جهاز مسحوب
الحصول على المعاملات (مع فلاتر)
Query Parameters:
type: نوع المعاملة (add/withdraw)userId: معرف المستخدمregionId: معرف المنطقةstartDate: تاريخ البدايةendDate: تاريخ النهايةsearch: كلمة البحث
✅ الوصول الكامل لجميع الصفحات ✅ إدارة المستخدمين ✅ إدارة المناطق ✅ عرض مخزون جميع الفنيين ✅ عرض جميع المعاملات ✅ تصدير التقارير
✅ عرض المخزون الخاص به فقط ✅ تحديث المخزون المتحرك الخاص به ✅ عرض المعاملات الخاصة به ❌ لا يمكنه إدارة المستخدمين ❌ لا يمكنه رؤية مخزون الآخرين
- كلمات المرور: يتم تشفيرها باستخدام bcrypt
- الجلسات: محمية بـ express-session
- CSRF Protection: محمي من هجمات CSRF
- SQL Injection: محمي باستخدام Prepared Statements
- XSS Protection: React يحمي تلقائياً من XSS
# تشغيل بيئة التطوير
npm run dev
# بناء المشروع للإنتاج
npm run build
# تشغيل النسخة الإنتاجية
npm start
# فحص الأخطاء البرمجية
npm run check
# تحديث قاعدة البيانات
npm run db:push- تحديث Schema: عدّل
shared/schema.ts - تحديث Storage Interface: عدّل
server/storage.ts - تحديث Database Storage: عدّل
server/database-storage.ts - إضافة API Routes: عدّل
server/routes.ts - إنشاء Components: أضف في
client/src/components/ - إنشاء Pages: أضف في
client/src/pages/ - تحديث Router: عدّل
client/src/App.tsx
- استخدم TypeScript للأنواع القوية
- استخدم React Query للـ caching
- استخدم shadcn/ui components
- تجنب التكرار - أنشئ مكونات قابلة لإعادة الاستخدام
- استخدم
data-testidلسهولة الاختبار
- استخدم Zod للتحقق من البيانات
- أبقِ Routes بسيطة - المنطق في Storage
- استخدم TypeScript Types من Schema
- سجّل الأخطاء بشكل واضح
- استخدم Transactions للعمليات المعقدة
- استخدم Indexes للأعمدة المستخدمة في البحث
- استخدم Foreign Keys للحفاظ على سلامة البيانات
- لا تغير نوع ID columns
- استخدم
npm run db:pushلتحديث Schema
الحل:
- تأكد من وجود مستخدم في قاعدة البيانات
- تحقق من صحة كلمة المرور
- تأكد من أن
SESSION_SECRETموجود
الحل:
- تأكد أن username و email فريدان
- تأكد من ملء جميع الحقول الإجبارية
- افحص الـ logs للأخطاء التفصيلية
الحل:
- استخدم endpoint
/api/stock-movements/transfer - لا تستخدم التحديث المباشر للنقل
- تأكد من وجود مخزون كافٍ
الحل:
- تأكد من تحديث قاعدة البيانات
- تحقق من متغيرات البيئة
- راجع سجلات الأخطاء
الحل:
pkill -f "tsx server/index.ts"
npm run dev-
تقرير المخزون الشامل
- جميع الفنيين ومخزونهم
- حالة التنبيهات
- الإجماليات
-
تقرير المعاملات
- جميع العمليات المسجلة
- مفلتر حسب التاريخ/المستخدم/النوع
- الإحصائيات التفصيلية
-
تقرير الأجهزة المسحوبة
- جميع الأجهزة المسحوبة
- تفاصيل الحالة والعطل
- مصنفة حسب الفني/المدينة
-
تقرير المناطق
- إحصائيات كل منطقة
- عدد الأصناف والكميات
- عدد التنبيهات
- ✅ قاعدة بيانات PostgreSQL
- ✅ متغيرات البيئة مضبوطة بشكل صحيح
- ✅ جميع الـ dependencies مثبتة
- ✅ Schema محدث في قاعدة البيانات
- بناء المشروع:
npm run build- تشغيل النسخة الإنتاجية:
npm start- التحقق من النشر:
- تأكد من عمل قاعدة البيانات
- تحقق من الاتصال بالخادم
- اختبر الوظائف الأساسية
Development:
- للتطوير والاختبار
- Hot reload مفعّل
npm run dev
Production:
- للاستخدام الفعلي
- مُحسّن للأداء
npm start
المخزون الثابت (Fixed):
- يُدخل يدوياً من قبل المسؤول
- لا يتأثر إلا بالتحديثات المباشرة أو النقل
- يمثل القاعدة الأساسية للمخزون
المخزون المتحرك (Moving):
- يستقبل التحويلات من الثابت
- يمكن تحديثه مباشرة
- يمثل المخزون الفعلي للعمل
عمليات النقل:
- ✅ النقل من الثابت → المتحرك: يخصم من الثابت
- ❌ التحديث المباشر للمتحرك: لا يؤثر على الثابت
- صندوق: عبوة كاملة من الصنف
- وحدة: قطعة واحدة من الصنف
- يتم تتبع كليهما بشكل منفصل
تم تطبيق بنية معمارية احترافية على المشروع بناءً على أفضل الممارسات:
للحصول على توثيق شامل للبنية المعمارية، راجع:
- دليل البنية المعمارية - نظرة عامة على جميع الملفات التوثيقية
- التوثيق المعماري الشامل - البنية الكاملة والمبادئ
- توثيق الطبقات - تفصيل كل طبقة
- أمثلة الكود - أمثلة عملية
- المخططات البصرية - مخططات توضيحية
للحصول على دليل شامل للاختبار والتحليل والتطوير:
- دليل الاختبار والتحليل والتطوير - دليل شامل
- دليل اختبار API - اختبار API endpoints
- سير العمل للتطوير - Workflow للتطوير
- دليل التطوير السريع - بدء سريع
للحصول على الخطة الاستراتيجية الشاملة لتطوير التطبيق وجعله منافس قوي:
- الخطة الاستراتيجية الشاملة - خطة كاملة (سوق، تطوير، تسويق، نمو)
- خطة تطبيق الجوال - خطة تفصيلية لتطبيق الجوال
- خارطة الطريق - Timeline مفصل (12 شهر)
- ملخص الخطة الاستراتيجية - ملخص سريع
للحصول على دليل شامل لرفع التطبيق على Hostinger:
- دليل رفع Hostinger - دليل شامل ومفصل
- البدء السريع - خطوات سريعة
- Checklist الرفع - قائمة التحقق
- ✅ Clean Architecture: فصل الاهتمامات
- ✅ SOLID Principles: قابلية الصيانة
- ✅ Security First: الأمان أولاً
- ✅ Type Safety: TypeScript في كل مكان
Presentation Layer → Application Layer → Domain Layer → Infrastructure Layer
(Routes) (Services) (Models) (Repositories)
للحصول على المساعدة:
- راجع هذا الملف أولاً
- تحقق من الـ logs للأخطاء
- تأكد من تحديث قاعدة البيانات
- تحقق من صلاحيات المستخدم
MIT License - يمكن استخدامه بحرية للأغراض التجارية والشخصية
النسخة الحالية: 1.0.0
- ✅ البنية المعمارية الاحترافية: تطبيق Clean Architecture + SOLID Principles
- ✅ الأمان: تشفير كلمات المرور (bcrypt) + Security Middleware
- ✅ Error Handling: معالجة أخطاء مركزية ومنظمة
- ✅ التوثيق: توثيق شامل للبنية المعمارية (5 ملفات توثيقية)
- ✅ إصلاح مشكلة إنشاء المستخدمين
- ✅ تحسين نظام التنبيهات
- ✅ إضافة تصدير Excel
- ✅ تحسين واجهة المستخدم العربية
تم بناء هذا النظام بـ ❤️ باستخدام أحدث التقنيات