Digitale PSM تطبيق ويب مجاني ومفتوح المصدر للشركات الزراعية والبستانية، يتيح حساب استخدام منتجات وقاية النباتات وتسجيله وتصدير السجلات. لا حساب ولا خدمات خلفية ولا سحابة. تبقى البيانات كلها في ملف SQLite واحد على جهاز المستخدم، وتعمل قاعدة البيانات نفسها عبر WebAssembly في المتصفح.
يتطلب الاستخدام المهني لمنتجات وقاية النباتات توثيق كل معالجة: المنتج والكمية والمساحة والمحصول والتاريخ وفترة الانتظار قبل الحصاد. غالبًا ما تُحفظ هذه المعلومات في ملفات ورقية أو خدمات سحابية تتطلب حسابًا واشتراكًا وتستخدم خوادم الآخرين. يقدم Digitale PSM طريقًا آخر: تطبيق ويب يعمل كبرنامج محلي، يحتفظ بالبيانات في ملف لدى المستخدم ويعمل دون اتصال.
الشكل 1 — شاشة البدايةdigitale-psm.de على الكمبيوتر والهاتف
لا تسجيل دخول ولا إنشاء حساب. يسأل التطبيق فقط: هل تريد إنشاء قاعدة جديدة أم فتح ملف موجود؟ الملف قاعدة SQLite عادية على كمبيوتر المستخدم، يمكن نسخها وحفظ نسخة احتياطية منها وقراءتها بأي أداة تدعم SQLite.
وظائف التطبيق
حساب وتوثيق وإعداد سجلات.
الحساب
حساب معدل الاستخدام بحسب المساحة أو الكمية، والتحويل بين الوحدات، وحفظ تركيبات المنتجات المتكررة، مع اختيار سريع لرموز EPPO ومراحل النمو BBCH.
التوثيق
تسجيل كل معالجة، وعرض تقويم مع مرشحات، وتصدير بصيغة PDF أو CSV.
بيانات التراخيص الرسمية
بعد الاستيراد، تصبح قاعدة تراخيص BVL داخل ملفك. يمكنك البحث بحسب المحصول والآفة والمادة الفعالة، حتى دون اتصال.
تطبيق مكتبي يعمل دون اتصال
يمكن تثبيته من Chrome أو Edge، وتشغيله دون شبكة، وتذكّر آخر قاعدة بيانات وفتح ملفات .sqlite بالنقر المزدوج. يدعم أيضًا إحداثيات GPS للحقول.
التفاصيل التقنية
كيف تُحفظ البيانات
التصميم المعتاد لمثل هذا التطبيق هو خادم بقاعدة بيانات وحساب لكل مستخدم. أردت أن تبقى البيانات لدى الشركة في ملف واحد على كمبيوترها. لذلك كان لا بد أن تعمل قاعدة البيانات حيث توجد البيانات نفسها: في المتصفح.
يتكون التطبيق من ملفات 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. الحفظ خطوة بخطوة
يُرسل الإدخال، مثل معالجة جديدة، إلى worker كرسالة. تحمل كل رسالة معرّفًا ومهلة انتظار، وتصل الإجابة بصورة غير متزامنة.
يكتب worker في قاعدة SQLite الخاصة به. تكون القاعدة في ذاكرته، أو في Origin Private File System (OPFS) إذا سمح المتصفح بذلك.
ثم يصدّر القاعدة كاملةً كسلسلة بايتات (sqlite3_js_db_export) وينقل مخزن البيانات إلى مسار التنفيذ الرئيسي دون نسخه، باستخدام Transferable.
يكتب المسار الرئيسي البايتات في ملف .sqlite للمستخدم عبر مرجع الملف: createWritable ثم write ثم close. بذلك يحتوي الملف على القرص على قاعدة كاملة ومتسقة.
تُجمع التغييرات المتلاحقة. إذا كانت كتابة جارية، يسجل التطبيق فقط ضرورة الكتابة مرة أخرى بعد انتهائها. فتحدث كتابة لكل مجموعة تغييرات، لا لكل ضغطة مفتاح.
4. التعرّف على الملف من محتواه
عند الفتح، يقرأ التطبيق بايتات الملف ويتحقق من توقيعه الأول: SQLite format 3. المحتوى هو الذي يحدد النوع، لا الامتداد. قد ينتهي اسم الملف بـ.json مع أنه قاعدة ثنائية. كانت الإصدارات القديمة تحفظ JSON، وقد جعل هذا التداخل قاعدة سليمة تبدو «فارغة» ذات مرة. منذ ذلك الحين أصبح التوقيع هو المرجع.
إذا كان الملف SQLite، يحوّله worker إلى القاعدة النشطة عبر sqlite3_deserialize. وفي وضع OPFS تستورده OpfsDb.importDb إلى الملف الدائم. وإذا كان JSON، تُستورد البيانات كلقطة كاملة للحالة. ينتهي المساران إلى القاعدة نفسها وتُنفَّذ الترحيلات في الحالتين.
5. مسار إعداد بيانات BVL
تتوفر قاعدة التراخيص الرسمية لدى BVL، المكتب الاتحادي الألماني لحماية المستهلك وسلامة الغذاء، عبر API عامة. لكنها ليست مهيأة للاستخدام المباشر في المتصفح: نقاط وصول كثيرة وطلبات عديدة، دون تشغيل بلا اتصال. لذلك تُجهَّز البيانات مسبقًا في مسار مستقل داخل المستودع العام pflanzenschutz-db:
كل يومين، يجلب GitHub Actions البيانات من جميع نقاط BVL ويتحقق منها ويضيف معلومات، منها مؤشرات الاستخدام في الزراعة العضوية وأسماء المواد الفعالة وعبارات الخطر.
الناتج ملف SQLite يُضغط بصيغتي Brotli وZIP ويُنشر عبر GitHub Pages، مع ملف manifest يحدد حجم كل ملف وبصمة SHA-256 الخاصة به.
يحمّل التطبيق manifest ويختار أصغر صيغة يستطيع المتصفح فك ضغطها، ويعرض تقدم التنزيل، ثم يسلّم البايتات إلى worker.
يفتح worker الملف كقاعدة مؤقتة في الذاكرة، وينسخ جداولها إلى قاعدة المستخدم ضمن معاملة واحدة، بترتيب التبعيات للحفاظ على صحة المفاتيح الخارجية.
بعدها يصبح الفهرس كاملًا داخل ملف .sqlite الخاص بالمستخدم، ويمكن البحث فيه دون اتصال. يسجّل سجل داخل القاعدة الإصدار الذي استُورد.
البيانات بتاريخ 25 أكتوبر 2026
القيمة
المنتجات في الفهرس
2,165
الاستخدامات، بحسب المنتج والمحصول والآفة
30,836
المواد الفعالة
482
حجم التنزيل، Brotli / ZIP
6.8 MB / 12.5 MB
بعد فك الضغط، SQLite
113 MB
6. العمل دون اتصال وتثبيت التطبيق
عند التثبيت، يخزن service worker مسبقًا جميع ملفات البناء ذات البصمات، بما فيها وحدة WebAssembly. بعدها يعمل التطبيق دون شبكة. يضع كل بناء إصدارًا جديدًا للذاكرة المؤقتة داخل service worker؛ وإلا لبقي المستخدمون الذين ثبّتوا التطبيق على الشيفرة القديمة، لأن المتصفح لا يعيد تثبيت service worker مطابق بايتًا ببايت.
بعد تثبيته كتطبيق مكتبي، يسجل Digitale PSM نفسه عبر File Handling API للامتدادات .sqlite و.db و.json. يفتح النقر المزدوج على الملف قاعدة البيانات مباشرةً في التطبيق. يُحفظ مرجع آخر ملف في IndexedDB؛ وعند التشغيل التالي يطلب التطبيق الإذن فقط ويعيد فتحه.
7. الأداء والاستقرار
دون نسخ مخازن البيانات الكبيرة. تنتقل صادرات القاعدة وبيانات BVL بين مسارات التنفيذ بالنقل بدل الاستنساخ البنيوي. عند حجم 100 MB، قد يكون هذا الفارق بين واجهة سلسة وأخرى متجمدة.
مهلة مناسبة لكل عملية. للاستدعاءات العادية 30 ثانية، ولاستيراد BVL حتى ثماني دقائق، لأن المتصفحات تبطئ المؤقتات في علامات التبويب الخلفية. إذا تعطل worker، تُرفض جميع الاستدعاءات المعلقة فورًا بدل انتظارها إلى ما لا نهاية.
تحميل على صفحات. تُحمَّل السجلات والمنتجات ونقاط GPS صفحةً صفحة باستخدام مؤشر cursor، وتعرض الواجهة الصفوف المرئية فقط.
معالجة سبب لفقدان البيانات. في وضع SQLite، يدير worker السجل مباشرةً ولم يعد يرسله ضمن لقطة الحالة. وإلا فقد يعيد حفظ أحد الإعدادات كتابة قائمة قديمة، ويحذف كل السجلات المضافة منذ فتح الملف.
8. القيود الحالية
الأولوية للكمبيوتر. يتوفر الوصول عبر File System Access API في متصفحات Chromium المكتبية مثل Chrome وEdge فقط. لا يتوفر على الهواتف، سواء Safari على iPhone أو Chrome على Android. لذلك لا يمكن لهذه النسخة فتح ملف هناك، وتبقى القاعدة الجديدة فقط حتى إعادة تحميل الصفحة. يحتاج إصدار الهاتف إلى مسار تخزين آخر، مثل OPFS أو IndexedDB، ولم يُطوَّر بعد.
OPFS يحتاج إلى العزل. التخزين الدائم داخل worker عبر OPFS يتطلب عزلًا بين المصادر مع ترويسات COOP/COEP، لا يمكن ضبطها في GitHub Pages. لذلك تعمل القاعدة في النسخة المنشورة داخل ذاكرة worker، وتبقى النسخة المرجعية في الملف على القرص.
إعادة كتابة الملف كاملًا. كل حفظ يعيد كتابة جميع البيانات. لا يمثل ذلك مشكلة لسجلات الشركة وحدها، لكن الملف يتجاوز 100 MB بعد استيراد فهرس BVL ويصبح زمن الحفظ ملحوظًا. أُبقي هذا التصميم بسيطًا عمدًا؛ والخطوة التالية قد تكون كتابة الصفحات المتغيرة فقط.