ثبت گام افزونهٔ سروری
شناسهٔ شِما: plugin-step@1
شِمای قابلخواندن توسط ماشین: plugin-step.schema.json
پوشش مرجعِ ثبت برای یک گام افزونهٔ سروری (بخش 6.6) — منطقی سمت سرور که هنگام ساخته، بهروزرسانی یا حذف شدن یک رکورد روی یک موجودیت اجرا میشود. این پوشش میگوید منطق کِی و چگونه اجرا شود؛ یک پیادهسازی BS Lang افزون بر آن، اسکریپت را بهصورت درونخطی حمل میکند که علاوه بر این شِما، توسط دستور زبان BS Lang هم اعتبارسنجی میشود. یک ثبت به شکل یکسان اعتبارسنجی میشود، چه از یک طراح بیاید، چه از یک فراخوانی API، چه از یک دستیار هوش مصنوعی، و چه از یک وارد کردن راهحل.
شکل
| فیلد | نوع | اجباری | یادداشتها |
|---|---|---|---|
logicalName | string | بله | پیشوند ناشر در ابتدا، با snake-case کوچک. |
displayName | string | بله | نام خوانای گام. |
publisherPrefix | string | بله | پیشوند ناشر مالک که logicalName باید با آن فضانام شود — نه پیشوند جدولی که گام آن را میپاید. جدول استاندارد مانند account عمداً بیپیشوند است و اعتبارسنجی در برابر آن، نامگذاری گامی روی چنین جدولی را ناممکن میکرد. |
entity | string | بله | موجودیتی که نوشتنهایش گام را برمیانگیزد. |
message | string | بله | Create، Update یا Delete. |
stage | string | بله | PreValidation، PreOperation یا PostOperation. |
executionMode | string | بله | Synchronous (درونخطی، داخل نوشتن) یا Asynchronous (از راه صندوق خروجی صف میشود و پس از ثبت نهایی نوشتن اجرا میگردد). گام ناهمگام باید PostOperation باشد: پس از ذخیرهٔ رکورد اجرا میشود، پس چیزی برای رد کردن ندارد. |
rank | integer | بله | ترتیب اجرا میان گامهای همموجودیت + همپیام + هممرحله؛ کمتر زودتر اجرا میشود. |
isEnabled | boolean | بله | گام غیرفعال ذخیره میشود اما هرگز اجرا نمیشود. |
implementation | object | بله | دقیقاً یک پیادهسازی (پایینتر را ببینید). |
پیادهسازی
| فیلد | نوع | اجباری | یادداشتها |
|---|---|---|---|
type | string | بله | BsLangScript یا DotNetAssembly. |
script | string | هنگام BsLangScript | متن مبدأ BS Lang. |
assemblyReference | string | هنگام DotNetAssembly | کلید ذخیرهسازی اسمبلی بارگذاریشده. |
typeName | string | هنگام 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()) { … }
هر دو گونهٔ نقلقول کار میکند. ماژول باید یک اسکریپت راهحل در همان محیط باشد؛ هر چیز دیگری هنگام ذخیرهٔ گام شکست میخورد، نه هنگام اجرا.