composer require mostafax/dynamic-hybrid-reporting-engine
افتح صفحة الـ Package ↗
DSL واحد بـ JSON — MySQL + MongoDB — أي تقرير، أي تصدير، صفر كود مخصص
كل مشروع بيحتاج تقارير في النهاية — لكن كتابة Queries منفصلة لكل مصدر، لكل Format، لكل Tenant، مش قابل للتوسع.
كل تقرير — بغض النظر عن المصدر — بيمر على نفس الـ Pipeline المحصّن قبل أي استدعاء للـ Database.
JSON object (أو PHP array) بيوصف التقرير: المصدر، الجدول، الحقول، الـ Filters، الـ Aggregations، الترتيب، الـ Pagination.
DslParser بيحوّل الـ Input الخام لـ QueryDefinition مكتوبة بالنوع (Immutable) مع Hash MD5 ثابت.
بيطبّق الـ Limits: أقصى Rows، أقصى Joins، أقصى Conditions، أقصى Aggregations. بيرفض أي Operator غير مسموح.
QuerySanitizer بيتحقق من كل Identifier بـ Regex. FieldAccessControl بيشيل الـ Fields المحظورة.
QueryCacheManager بيشوف Redis بالـ Hash. مفاتيح الـ Cache مقسّمة بالـ Tenant — بيانات Tenant ميتسرّبش لتاني.
بيجيب الـ Adapter الصح من الـ Registry: MySQLDataSource أو MongoDataSource. ممكن تضيف Custom Adapters وقت الـ Runtime.
MySQL بيستخدم Laravel Query Builder. MongoDB بيبني Pipeline $facet — Data + totalCount في رحلة واحدة للـ Database.
بيرجع ExecutionResult بالـ Data والعدد الكلي. بيحفظ في Redis وبيطلق Event ReportExecuted.
Schema واحدة لـ MySQL وMongoDB — Fields، Filters (AND/OR متداخل)، Aggregations، Joins، Group-By، ترتيب، Pagination.
سجّل Custom Data Sources وقت الـ Runtime. ضيف PostgreSQL، Elasticsearch، أو أي HTTP API.
النتائج محفوظة بالـ Hash. مفاتيح الـ Cache مقسّمة بالـ Tenant وبتتبطل تلقائياً عند التحديث.
Regex Whitelist على كل اسم Column أو Table. القيم دايماً PDO Binding — محتش في SQL أو MongoDB أبداً.
Global Deny List + Role-Based Deny List مع Wildcard Patterns. الـ Fields المحظورة بتتشال تلقائياً.
CSV (UTF-8 BOM Streaming)، XLSX (PhpSpreadsheet)، وJSON — كلهم Streamed للـ Client مباشرة بدون Temp Files.
Tenant ID بيتحط في كل Query تلقائياً. MySQL بياخد WHERE Clause، وMongoDB بياخد $match Stage — صفر كود إضافي.
ضمّن KPIs وCharts وTables وFilters في أي Blade Template بـ Tag واحد. Bootstrap وTailwind. RTL جاهز.
اختياري — livewire:report-widget بيضيف Real-time Filtering وSorting وPagination بدون أي JavaScript.
Domain Entities لـ Dashboards وWidgets (Table، Bar Chart، Line Chart، KPI Card، Heatmap). كل Widget مربوط بـ Report محفوظ.
dhr_report_executions بتسجّل كل Run: Execution Time، Rows، Memory، Cache Hit، Status.
variant="flat|gradient|dark|glass|minimal|bold" — ثيمات CSS قابلة للتبديل اللحظي مع Color Picker وTransitions سلسة.
بيبني $match → $group → $project → $sort → $facet تلقائياً — Data + totalCount في رحلة واحدة. BSONArray وObjectId بتتحوّل تلقائياً.
الـ Facade، وHTTP API، وExport Endpoint — كلهم شغّالين من أول لحظة.
نفس الـ Aggregation Query — فرق كبير في زمن الاستجابة بين Redis ساخن وبارد.
ستة Security Controls مستقلة بتشتغل قبل أول استدعاء للـ Database.
| الطبقة | الـ Class | بيحمي من إيه |
|---|---|---|
| Identifier Injection | QuerySanitizer | Regex Whitelist على كل اسم Column وTable — أي Injection Query بتترفض قبل الـ Builder |
| Value Injection | Laravel Query Builder | كل القيم PDO Bindings — مش بتتحط في النص أبداً |
| Field Exposure | FieldAccessControl | الـ Fields المحظورة عالمياً (password, api_key) بتتشال؛ الـ Fields المحظورة في الـ Filters بترمي 422 |
| Query Limits | QueryValidator | أقصى Rows، Joins، Conditions، Aggregations — بيمنع Resource Exhaustion |
| Rate Limiting | QueryLimitMiddleware | Budget لكل User عبر Laravel RateLimiter — المتبقي في الـ Response Headers |
| Tenant Isolation | ReportEngine + Builders | Tenant ID بيتضاف تلقائياً — Tenant مش ممكن يقرأ بيانات التاني |
ثبّت، انشر الـ Config، شغّل الـ Migration — بعدها REST API جاهز والـ Facade شغّالة.