پروژه ۰۱ — Digitale PSM

پایگاه داده‌ای که
در مرورگر اجرا می‌شود.

Digitale PSM یک برنامه رایگان و متن‌باز تحت وب برای مجموعه‌های باغبانی و کشاورزی است. با آن می‌توان میزان مصرف محصولات حفاظت از گیاهان، مثل آفت‌کش‌ها، را محاسبه و ثبت کرد و از سوابق خروجی گرفت. نیازی به حساب کاربری، بک‌اند یا فضای ابری نیست. تمام داده‌ها در یک فایل SQLite روی کامپیوتر کاربر می‌مانند و خود پایگاه داده با WebAssembly در مرورگر اجرا می‌شود.

نویسنده: عباس حسینی·از 04/2025·نسخه 2.0·مجوز MIT

در استفاده حرفه‌ای از محصولات حفاظت از گیاهان، هر بار مصرف باید ثبت شود: نام محصول، مقدار، مساحت، گیاه، تاریخ و دوره انتظار تا برداشت. در عمل این اطلاعات اغلب در پوشه‌های کاغذی یا سرویس‌های ابری با حساب کاربری، اشتراک و سرور دیگران نگهداری می‌شوند. Digitale PSM راه دیگری دارد: یک برنامه تحت وب که مثل نرم‌افزار روی کامپیوتر شخصی کار می‌کند، داده‌ها را به‌صورت فایل نزد کاربر نگه می‌دارد و بدون اینترنت هم قابل استفاده است.

صفحه شروع Digitale PSM روی کامپیوتر، برای ایجاد پایگاه داده یا باز کردن فایل موجود
صفحه شروع Digitale PSM روی گوشی
تصویر ۱ — صفحه شروع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 می‌تواند آن را باز کند و می‌توان آن را کپی کرد، پشتیبان گرفت یا به کامپیوتر دیگری برد.

۲. معماری سه‌لایه

پایگاه داده در رشته اصلی اجرای مرورگر کار نمی‌کند؛ داخل Web Worker جداگانه‌ای اجرا می‌شود تا حتی هنگام وارد کردن داده‌های حجیم، رابط کاربری پاسخ‌گو بماند. ارتباط این دو بخش فقط با پیام انجام می‌شود.

رابط کاربری · رشته اصلی
Astro, TypeScript, Bootstrap
  • فرم‌ها، تقویم، فهرست‌ها و خروجی PDF و CSV
  • مدیریت وضعیت و رویدادها
  • ارتباط با پایگاه داده فقط از طریق پیام
  • نگهداری دسترسی فایل و نوشتن روی آن
⇄postMessage
شناسه، مهلت پاسخ،
انتقال بافرهای بزرگ
پایگاه داده · Web Worker
SQLite 3.54 با WebAssembly
  • ساختار داده با مهاجرت نسخه‌ها، از user_version 1 تا 11
  • WAL، کلیدهای خارجی و کش صفحه ۲۰ مگابایتی
  • اجرای پرس‌وجوها، فهرست‌های صفحه‌بندی‌شده و وارد کردن داده‌های BVL
  • خروجی کامل پایگاه داده به‌صورت بایت
⇄بایت‌ها
خروجی · ورودی
ذخیره‌سازی · نزد کاربر
یک فایل .sqlite
  • File System Access API، با نگهداری دسترسی فایل در IndexedDB برای شروع خودکار
  • حالت OPFS، اگر مرورگر اجازه دهد
  • روش‌های جایگزین: فایل JSON، localStorage و حافظه

۳. ذخیره‌سازی، مرحله به مرحله

  1. یک ورودی، مثلاً ثبت مصرف جدید، به‌صورت پیام به worker فرستاده می‌شود. هر پیام شناسه و مهلت پاسخ دارد و نتیجه به‌صورت غیرهم‌زمان برمی‌گردد.
  2. worker داده را در SQLite می‌نویسد. پایگاه داده در حافظه worker قرار دارد یا، اگر مرورگر اجازه دهد، در فضای فایل خصوصی مبدأ، یعنی Origin Private File System (OPFS).
  3. سپس worker کل پایگاه داده را به مجموعه‌ای از بایت‌ها تبدیل می‌کند (sqlite3_js_db_export) و بافر را بدون کپی کردن، با روش Transferable، به رشته اصلی تحویل می‌دهد.
  4. رشته اصلی از طریق دسترسی فایل، بایت‌ها را در فایل .sqlite کاربر می‌نویسد: createWritable، write، close. در نتیجه فایل روی دیسک یک پایگاه داده کامل و سازگار است.
  5. تغییرهای پشت سر هم تجمیع می‌شوند. اگر نوشتن در حال انجام باشد، برنامه فقط ثبت می‌کند که بعد از پایان باید یک بار دیگر ذخیره کند. بنابراین برای هر دسته تغییر یک نوشتن انجام می‌شود، نه برای هر کلید فشرده‌شده.

۴. تشخیص فایل از روی محتوا

هنگام باز کردن، برنامه فایل را به‌صورت بایت می‌خواند و امضای ابتدای آن، یعنی SQLite format 3، را بررسی می‌کند. ملاک محتواست، نه پسوند. ممکن است نام فایل به .json ختم شود اما محتوایش پایگاه داده باینری باشد. نسخه‌های قدیمی داده را به‌صورت JSON ذخیره می‌کردند و همین ترکیب یک بار باعث شد پایگاه داده سالم «خالی» به نظر برسد. از آن زمان، امضای فایل معیار تشخیص است.

اگر فایل SQLite باشد، worker با sqlite3_deserialize آن را به پایگاه داده فعال تبدیل می‌کند. در حالت OPFS، تابع OpfsDb.importDb آن را به فایل پایدار وارد می‌کند. اگر JSON باشد، داده‌ها به‌صورت یک نسخه کامل از وضعیت وارد می‌شوند. هر دو مسیر به همان پایگاه داده می‌رسند و در هر دو، مهاجرت نسخه‌ها اجرا می‌شود.

۵. مسیر پردازش داده‌های 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 خود کاربر قرار دارد و آفلاین قابل جستجوست. در لاگ داخل پایگاه داده ثبت می‌شود که کدام انتشار وارد شده است.
وضعیت در ۲۵ اکتبر ۲۰۲۶مقدار
محصولات موجود در فهرست2,165
موارد مصرف، به تفکیک محصول، گیاه و آفت30,836
مواد مؤثره482
حجم دانلود، Brotli / ZIP6.8 MB / 12.5 MB
حجم پس از باز کردن فشرده‌سازی، SQLite113 MB

۶. اجرای آفلاین و نصب برنامه

service worker هنگام نصب همه فایل‌های ساخت را که نامشان هش دارد، از جمله ماژول WebAssembly، از قبل در کش ذخیره می‌کند. پس از آن برنامه بدون اینترنت باز می‌شود. در هر ساخت، نسخه کش جدیدی در service worker قرار می‌گیرد؛ وگرنه کاربران نصب‌شده روی کد قدیمی می‌مانند، چون مرورگر service worker با بایت‌های یکسان را دوباره نصب نمی‌کند.

نسخه نصب‌شده دسکتاپ از طریق File Handling API برای فایل‌های .sqlite، .db و .json ثبت می‌شود. با دوبار کلیک روی فایل، پایگاه داده مستقیم در برنامه باز می‌شود. دسترسی آخرین فایل در IndexedDB نگهداری می‌شود؛ بار بعد، برنامه فقط اجازه دسترسی می‌خواهد و همان فایل را باز می‌کند.

۷. سرعت و پایداری

۸. محدودیت‌های فعلی

۹. مشخصات پروژه

برنامهdigitale-psm.de — رایگان، بدون تبلیغات و حساب کاربری
زبان برنامهآلمانی؛ برنامه بر اساس مقررات مجوزهای آلمان و پایگاه داده BVL طراحی شده است
شروع پروژهآوریل ۲۰۲۵، نسخه فعلی 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 در مرورگر