المشروع 01 — Digitale PSM

قاعدة بيانات
تعمل في المتصفح.

Digitale PSM تطبيق ويب مجاني ومفتوح المصدر للشركات الزراعية والبستانية، يتيح حساب استخدام منتجات وقاية النباتات وتسجيله وتصدير السجلات. لا حساب ولا خدمات خلفية ولا سحابة. تبقى البيانات كلها في ملف SQLite واحد على جهاز المستخدم، وتعمل قاعدة البيانات نفسها عبر WebAssembly في المتصفح.

بقلم عباس حسيني·منذ 04/2025·الإصدار 2.0·ترخيص MIT

يتطلب الاستخدام المهني لمنتجات وقاية النباتات توثيق كل معالجة: المنتج والكمية والمساحة والمحصول والتاريخ وفترة الانتظار قبل الحصاد. غالبًا ما تُحفظ هذه المعلومات في ملفات ورقية أو خدمات سحابية تتطلب حسابًا واشتراكًا وتستخدم خوادم الآخرين. يقدم Digitale PSM طريقًا آخر: تطبيق ويب يعمل كبرنامج محلي، يحتفظ بالبيانات في ملف لدى المستخدم ويعمل دون اتصال.

شاشة بداية Digitale PSM على الكمبيوتر: إنشاء قاعدة جديدة أو فتح ملف موجود
شاشة بداية Digitale PSM على الهاتف
الشكل 1 — شاشة البدايةdigitale-psm.de على الكمبيوتر والهاتف

لا تسجيل دخول ولا إنشاء حساب. يسأل التطبيق فقط: هل تريد إنشاء قاعدة جديدة أم فتح ملف موجود؟ الملف قاعدة SQLite عادية على كمبيوتر المستخدم، يمكن نسخها وحفظ نسخة احتياطية منها وقراءتها بأي أداة تدعم SQLite.

وظائف التطبيق

حساب وتوثيق وإعداد سجلات.

الحساب
حساب معدل الاستخدام بحسب المساحة أو الكمية، والتحويل بين الوحدات، وحفظ تركيبات المنتجات المتكررة، مع اختيار سريع لرموز EPPO ومراحل النمو BBCH.
التوثيق
تسجيل كل معالجة، وعرض تقويم مع مرشحات، وتصدير بصيغة PDF أو CSV.
بيانات التراخيص الرسمية
بعد الاستيراد، تصبح قاعدة تراخيص BVL داخل ملفك. يمكنك البحث بحسب المحصول والآفة والمادة الفعالة، حتى دون اتصال.
تطبيق مكتبي يعمل دون اتصال
يمكن تثبيته من Chrome أو Edge، وتشغيله دون شبكة، وتذكّر آخر قاعدة بيانات وفتح ملفات .sqlite بالنقر المزدوج. يدعم أيضًا إحداثيات GPS للحقول.
التفاصيل التقنية

كيف تُحفظ البيانات

التصميم المعتاد لمثل هذا التطبيق هو خادم بقاعدة بيانات وحساب لكل مستخدم. أردت أن تبقى البيانات لدى الشركة في ملف واحد على كمبيوترها. لذلك كان لا بد أن تعمل قاعدة البيانات حيث توجد البيانات نفسها: في المتصفح.

1. ملف بدلًا من خادم

يتكون التطبيق من ملفات HTML وCSS وJavaScript ثابتة تُقدَّم عبر GitHub Pages. لا يستقبل أي خادم سجلات المستخدمين. يُحوَّل SQLite إلى وحدة WebAssembly (@sqlite.org/sqlite-wasm) وتُضمَّن محليًا مع التطبيق، مع بصمة وإصدار يُحددان وقت البناء، مثل بقية الملفات. لا يُجلب شيء من CDN لطرف ثالث أثناء التشغيل؛ ولهذا تعمل قاعدة البيانات دون اتصال أيضًا.

نقطة مهمة: الملف الموجود على قرص المستخدم هو قاعدة SQLite حقيقية، لا صيغة تصدير خاصة. يمكن فتحه بأي أداة SQLite ونسخه ونسخه احتياطيًا ونقله إلى جهاز آخر.

2. ثلاث طبقات

لا تعمل قاعدة البيانات في مسار التنفيذ الرئيسي للمتصفح، بل داخل Web Worker مستقل، لتبقى الواجهة مستجيبة أثناء استيراد البيانات الكبيرة. يتم التواصل بينهما بالرسائل فقط.

الواجهة · مسار التنفيذ الرئيسي
Astro, TypeScript, Bootstrap
  • النماذج والتقويم والقوائم وتصدير PDF وCSV
  • إدارة الحالة وناقل الأحداث
  • التواصل مع قاعدة البيانات بالرسائل فقط
  • الاحتفاظ بمرجع الوصول إلى الملف والكتابة فيه
⇄postMessage
معرّف ومهلة،
نقل مخازن بيانات كبيرة
قاعدة البيانات · Web Worker
SQLite 3.54 عبر WebAssembly
  • مخطط بيانات مع ترحيلات، من user_version 1 إلى 11
  • WAL ومفاتيح خارجية وذاكرة صفحات مؤقتة بحجم 20 MB
  • الاستعلامات والقوائم المقسّمة إلى صفحات واستيراد BVL
  • تصدير قاعدة البيانات كاملةً كبايتات
⇄بايتات
تصدير · استيراد
التخزين · لدى المستخدم
ملف .sqlite واحد
  • File System Access API، مع حفظ مرجع الملف في IndexedDB لإعادة فتحه عند التشغيل
  • وضع OPFS عندما يسمح المتصفح
  • البدائل: ملف JSON وlocalStorage والذاكرة

3. الحفظ خطوة بخطوة

  1. يُرسل الإدخال، مثل معالجة جديدة، إلى worker كرسالة. تحمل كل رسالة معرّفًا ومهلة انتظار، وتصل الإجابة بصورة غير متزامنة.
  2. يكتب worker في قاعدة SQLite الخاصة به. تكون القاعدة في ذاكرته، أو في Origin Private File System (OPFS) إذا سمح المتصفح بذلك.
  3. ثم يصدّر القاعدة كاملةً كسلسلة بايتات (sqlite3_js_db_export) وينقل مخزن البيانات إلى مسار التنفيذ الرئيسي دون نسخه، باستخدام Transferable.
  4. يكتب المسار الرئيسي البايتات في ملف .sqlite للمستخدم عبر مرجع الملف: createWritable ثم write ثم close. بذلك يحتوي الملف على القرص على قاعدة كاملة ومتسقة.
  5. تُجمع التغييرات المتلاحقة. إذا كانت كتابة جارية، يسجل التطبيق فقط ضرورة الكتابة مرة أخرى بعد انتهائها. فتحدث كتابة لكل مجموعة تغييرات، لا لكل ضغطة مفتاح.

4. التعرّف على الملف من محتواه

عند الفتح، يقرأ التطبيق بايتات الملف ويتحقق من توقيعه الأول: SQLite format 3. المحتوى هو الذي يحدد النوع، لا الامتداد. قد ينتهي اسم الملف بـ.json مع أنه قاعدة ثنائية. كانت الإصدارات القديمة تحفظ JSON، وقد جعل هذا التداخل قاعدة سليمة تبدو «فارغة» ذات مرة. منذ ذلك الحين أصبح التوقيع هو المرجع.

إذا كان الملف SQLite، يحوّله worker إلى القاعدة النشطة عبر sqlite3_deserialize. وفي وضع OPFS تستورده OpfsDb.importDb إلى الملف الدائم. وإذا كان JSON، تُستورد البيانات كلقطة كاملة للحالة. ينتهي المساران إلى القاعدة نفسها وتُنفَّذ الترحيلات في الحالتين.

5. مسار إعداد بيانات BVL

تتوفر قاعدة التراخيص الرسمية لدى BVL، المكتب الاتحادي الألماني لحماية المستهلك وسلامة الغذاء، عبر API عامة. لكنها ليست مهيأة للاستخدام المباشر في المتصفح: نقاط وصول كثيرة وطلبات عديدة، دون تشغيل بلا اتصال. لذلك تُجهَّز البيانات مسبقًا في مسار مستقل داخل المستودع العام pflanzenschutz-db:

  1. كل يومين، يجلب GitHub Actions البيانات من جميع نقاط BVL ويتحقق منها ويضيف معلومات، منها مؤشرات الاستخدام في الزراعة العضوية وأسماء المواد الفعالة وعبارات الخطر.
  2. الناتج ملف SQLite يُضغط بصيغتي Brotli وZIP ويُنشر عبر GitHub Pages، مع ملف manifest يحدد حجم كل ملف وبصمة SHA-256 الخاصة به.
  3. يحمّل التطبيق manifest ويختار أصغر صيغة يستطيع المتصفح فك ضغطها، ويعرض تقدم التنزيل، ثم يسلّم البايتات إلى worker.
  4. يفتح worker الملف كقاعدة مؤقتة في الذاكرة، وينسخ جداولها إلى قاعدة المستخدم ضمن معاملة واحدة، بترتيب التبعيات للحفاظ على صحة المفاتيح الخارجية.
  5. بعدها يصبح الفهرس كاملًا داخل ملف .sqlite الخاص بالمستخدم، ويمكن البحث فيه دون اتصال. يسجّل سجل داخل القاعدة الإصدار الذي استُورد.
البيانات بتاريخ 25 أكتوبر 2026القيمة
المنتجات في الفهرس2,165
الاستخدامات، بحسب المنتج والمحصول والآفة30,836
المواد الفعالة482
حجم التنزيل، Brotli / ZIP6.8 MB / 12.5 MB
بعد فك الضغط، SQLite113 MB

6. العمل دون اتصال وتثبيت التطبيق

عند التثبيت، يخزن service worker مسبقًا جميع ملفات البناء ذات البصمات، بما فيها وحدة WebAssembly. بعدها يعمل التطبيق دون شبكة. يضع كل بناء إصدارًا جديدًا للذاكرة المؤقتة داخل service worker؛ وإلا لبقي المستخدمون الذين ثبّتوا التطبيق على الشيفرة القديمة، لأن المتصفح لا يعيد تثبيت service worker مطابق بايتًا ببايت.

بعد تثبيته كتطبيق مكتبي، يسجل Digitale PSM نفسه عبر File Handling API للامتدادات .sqlite و.db و.json. يفتح النقر المزدوج على الملف قاعدة البيانات مباشرةً في التطبيق. يُحفظ مرجع آخر ملف في IndexedDB؛ وعند التشغيل التالي يطلب التطبيق الإذن فقط ويعيد فتحه.

7. الأداء والاستقرار

8. القيود الحالية

9. بطاقة المشروع

التطبيقdigitale-psm.de — مجاني، دون إعلانات أو حساب
اللغةالألمانية؛ يتبع التطبيق قواعد التراخيص الألمانية وقاعدة BVL
بداية المشروعأبريل 2025، الإصدار الحالي 2.0
الترخيص والشيفرةMIT، والشيفرة المصدرية على GitHub
التقنياتAstro 5 وTypeScript وBootstrap 5 مضمّن محليًا، وSQLite 3.54 عبر WebAssembly، وWeb Worker وservice worker وملف manifest لتطبيق الويب
التخزينملف SQLite لدى المستخدم عبر File System Access API؛ وOPFS عند توفره؛ وبدائل بملف JSON وlocalStorage
بيانات التراخيصAPI الخاصة بـBVL، مع إعداد في pflanzenschutz-db عبر GitHub Actions كل يومين، ونشر بصيغة Brotli/ZIP مع manifest وSHA-256
الاستضافةملفات ثابتة عبر GitHub Pages، والبناء والنشر باستخدام GitHub Actions
مشروع مرتبطst.digitale-psm.de: لوحة إحصاءات لقاعدة BVL، مع استعلامات SQL مباشرةً في المتصفح