پرش به مطلب اصلی

ثبت گام افزونهٔ سروری

شناسهٔ شِما: plugin-step@1 شِمای قابل‌خواندن توسط ماشین: plugin-step.schema.json

پوشش مرجعِ ثبت برای یک گام افزونهٔ سروری (بخش 6.6) — منطقی سمت سرور که هنگام ساخته، به‌روزرسانی یا حذف شدن یک رکورد روی یک موجودیت اجرا می‌شود. این پوشش می‌گوید منطق کِی و چگونه اجرا شود؛ یک پیاده‌سازی BS Lang افزون بر آن، اسکریپت را به‌صورت درون‌خطی حمل می‌کند که علاوه بر این شِما، توسط دستور زبان BS Lang هم اعتبارسنجی می‌شود. یک ثبت به شکل یکسان اعتبارسنجی می‌شود، چه از یک طراح بیاید، چه از یک فراخوانی API، چه از یک دستیار هوش مصنوعی، و چه از یک وارد کردن راه‌حل.

شکل​

فیلدنوعاجبارییادداشت‌ها
logicalNamestringبلهپیشوند ناشر در ابتدا، با snake-case کوچک.
displayNamestringبلهنام خوانای گام.
publisherPrefixstringبلهپیشوند ناشر مالک که logicalName باید با آن فضانام شود — نه پیشوند جدولی که گام آن را می‌پاید. جدول استاندارد مانند account عمداً بی‌پیشوند است و اعتبارسنجی در برابر آن، نام‌گذاری گامی روی چنین جدولی را ناممکن می‌کرد.
entitystringبلهموجودیتی که نوشتن‌هایش گام را برمی‌انگیزد.
messagestringبلهCreate، Update یا Delete.
stagestringبلهPreValidation، PreOperation یا PostOperation.
executionModestringبلهSynchronous (درون‌خطی، داخل نوشتن) یا Asynchronous (از راه صندوق خروجی صف می‌شود و پس از ثبت نهایی نوشتن اجرا می‌گردد). گام ناهمگام باید PostOperation باشد: پس از ذخیرهٔ رکورد اجرا می‌شود، پس چیزی برای رد کردن ندارد.
rankintegerبلهترتیب اجرا میان گام‌های هم‌موجودیت + هم‌پیام + هم‌مرحله؛ کمتر زودتر اجرا می‌شود.
isEnabledbooleanبلهگام غیرفعال ذخیره می‌شود اما هرگز اجرا نمی‌شود.
implementationobjectبلهدقیقاً یک پیاده‌سازی (پایین‌تر را ببینید).

پیاده‌سازی​

فیلدنوعاجبارییادداشت‌ها
typestringبلهBsLangScript یا DotNetAssembly.
scriptstringهنگام BsLangScriptمتن مبدأ BS Lang.
assemblyReferencestringهنگام DotNetAssemblyکلید ذخیره‌سازی اسمبلی بارگذاری‌شده.
typeNamestringهنگام DotNetAssemblyنوع افزونه‌ای که نمونه‌سازی می‌شود.

مرحله‌ها​

  • PreValidation — پیش از عملیات اجرا می‌شود؛ وارسی‌های درشت‌دانهٔ شکل و امنیت.
  • PreOperation — درست پیش از نوشتن اجرا می‌شود؛ می‌تواند مقدار فیلدها را روی رکورد تغییر دهد یا کل عملیات را رد کند.
  • PostOperation — درست پس از نوشتن اجرا می‌شود؛ برای تغییرهای آبشاری یا وابسته.

یک گام با فراخوانی throwValidationError("reason") عملیات را رد می‌کند، که نوشتن را متوقف می‌کند و دلیل را به فراخواننده بازمی‌گرداند.

نمونه​

{
"logicalName": "par_invoice_reject_negative",
"displayName": "Reject negative invoice total",
"entity": "par_invoice",
"message": "Create",
"stage": "PreOperation",
"executionMode": "Synchronous",
"rank": 1,
"isEnabled": true,
"implementation": {
"type": "BsLangScript",
"script": "if (getValue(\"par_total\") < 0) { throwValidationError(\"Total cannot be negative.\"); }"
}
}

توابع میزبان اسکریپت BS Lang​

یک گام BsLangScript رکورد را از راه این توابع میزبان می‌خواند و تغییر می‌دهد:

تابعهدف
getValue("field")مقدار کنونی یک فیلد روی رکوردی که در حال نوشته‌شدن است.
setValue("field", value)تغییر مقدار یک فیلد (تنها در PreOperation رعایت می‌شود).
getPreValue("field")مقدار پیشین فیلد (در به‌روزرسانی‌ها و حذف‌ها).
throwValidationError("message")رد کردن عملیات و بازگرداندن آن.
message() / stage() / entityName()عملیات، مرحله و موجودیت کنونی.
userId() / depth()کاربر برانگیزاننده و ژرفای بازگشت.

رسیدن به جدول‌های دیگر​

توابع بالا فقط رکورد در حال نوشته‌شدن را می‌بینند. این‌ها به بقیهٔ محیط می‌رسند و هر کدام به‌عنوان کاربری که گام را برانگیخته اجرا می‌شوند — اسکریپت راهی برای دور زدن مجوز نیست، و گامی که فراخوانش نمی‌تواند جدولی را بخواند، از آن چیزی نمی‌گیرد.

تابعکارکرد
getRecord("table", id)یک رکورد به‌صورت شیء، یا خالی اگر نباشد. .id روی آن هست.
queryRecords("table", "field", value)سطرهایی که یک فیلدشان با یک مقدار برابر است، به‌صورت فهرستی از شیءها. سقف ۲۰۰.
runQuery({ … })یک سند کامل parsware-query@1 را اجرا می‌کند — پالایه‌های تودرتوی and/or با ده عملگر، پیوندها، مرتب‌سازی، صفحه‌بندی، یا یک aggregate که گروه پاسخ می‌دهد. همان زبان پرس‌وجویی که «جست‌وجوی پیشرفته» تولید می‌کند و پرس‌وجوی ذخیره‌شده نگه می‌دارد. سقف سطرها ۲۰۰؛ گروه‌بندی سقف ندارد. ستون پیوندخورده زیر نام مستعارش خوانده می‌شود (row.acct.par_industry)، و 'from' یک پیوند باید در گیومه باشد، چون from واژهٔ کلیدی BS Lang است.
runSavedQuery("name")یک پرس‌وجوی ذخیره‌شده را با نام منطقی‌اش اجرا می‌کند. پیچیدگی در یک طراح می‌ماند و در راه‌حل سفر می‌کند، پس اسکریپت فقط پرسش را نام می‌برد.
countRecords("table", "field", value)چند تا هستند، بی‌آنکه واکشی شوند — یک COUNT واقعی، پس فراتر از سقف ۲۰۰ سطری که queryRecords را کران می‌زند هم درست است.
createRecord("table", { field: value, … })رکوردی می‌سازد و شناسه‌اش را برمی‌گرداند.
updateRecord("table", id, { field: value, … })فقط همان فیلدهایی را که نام برده شده تغییر می‌دهد.
deleteRecord("table", id)رکوردی را حذف می‌کند.

نوشتنی که از این راه انجام شود قاعده‌های عادی را اجرا می‌کند، پس گامی که روی جدول نوشته‌شده ثبت شده باشد به نوبت اجرا می‌شود. این تودرتویی در ژرفای هشت کران دارد و depth() به اسکریپت می‌گوید کجاست — اما این حد یک پشتوانه است نه یک طراحی. گامی که جدولی را که می‌پاید بنویسد خودش را برمی‌انگیزد، و چارهٔ آن یک شرط است یا جدولی دیگر.

وارد کردن منطق مشترک​

اسکریپت یک گام می‌تواند یک اسکریپت راه‌حل را با نام import کند، دقیقاً مانند یک قاعدهٔ کسب‌وکار سمت کارخواه، تا قاعده‌ای که چند گام آن را اعمال می‌کنند یک بار نوشته شود:

import 'par_approval_rules';

if (getValue('par_total') > par_approval_rules.limit()) { … }

هر دو گونهٔ نقل‌قول کار می‌کند. ماژول باید یک اسکریپت راه‌حل در همان محیط باشد؛ هر چیز دیگری هنگام ذخیرهٔ گام شکست می‌خورد، نه هنگام اجرا.