تخطَّ إلى المحتوى

القوالب والأدوار والحقول

القالب عقد قابل لإعادة الاستخدام. له اسم، ومسودة واحدة، وأي عدد من الإصدارات المنشورة. تُنشأ المظاريف دائمًا من إصدار منشور، وهو غير قابل للتعديل: تحرير القالب يعني حفظ مسودة جديدة ونشرها بصفتها الإصدار التالي. وتحتفظ المظاريف المرسلة بالفعل بالإصدار الذي ثبّتته.

GET /v1/templates/tpl_…
{
"id": "tpl_3kQ9xV2mLp",
"organization": "org_…",
"name": "Mutual NDA",
"description": "Two-party NDA, US law",
"latestVersion": 3,
"draftVersion": 4,
"createdAt": "2026-10-01T09:12:44.120Z",
"updatedAt": "2026-10-12T16:03:10.981Z"
}

المعرّفات سلاسل نصية ذات بادئة (tpl_، tplv_، tfl_، env_، rcp_، ses_، lnk_، evt_، whk_، whd_، …)؛ والطوابع الزمنية بصيغة RFC 3339 بتوقيت UTC.

وضع التراكب (source: "pdf") يبدأ من مستند مرفوع. الحقول مستطيلات توضع على صفحاته بوحدة نقاط PDF (1/72 بوصة)، ونقطة الأصل في الزاوية العلوية اليسرى من الصفحة، وفهرس الصفحات يبدأ من 0. يُحوَّل الملف المرفوع بصيغة .docx إلى PDF مرة واحدة (باستخدام LibreOffice، مع الحفاظ على تخطيط Word؛ وقد تُستبدل الخطوط التي لا يضمّنها الملف)، ومن ثم يصبح ملف PDF كأي ملف آخر: يذكر الملف convertedFrom: "docx". ويمكن أن تحمل إصدارات التراكب أيضًا تعديلات على المحتوى (نص يُحرَّر في مكانه، وتغطية بيضاء، ومربعات نص، وصور، وعمليات على الصفحات) تُطبَّق عند نشر الإصدار.

وضع المستند (source: "document") يخزّن العقد نفسه كنص منسّق (ProseMirror JSON) مع رقاقات متغيرات مثل {{client.name}}، وكتل حقول ضمن النص، وأقسام شرطية (لا تُبقى إلا عندما يكون تعبير showIf صحيحًا) وأقسام وصفوف جداول متكررة (واحد لكل عنصر في متغير من نوع مصفوفة). يعرض كل مظروف ملف PDF الخاص به، وتُقرأ مواضع الحقول من ذلك العرض. وفي لوحة التحكم، وضع المستند هو “البدء من مستند فارغ”. وعبر الـ API، يمكن أيضًا استيراد ملف Word إلى وضع المستند باستخدام POST /v1/templates/{id}/import: تصبح {{tags}} متغيرات أو حقولًا، وتصبح أسطر التوقيع (“Signature: ____”، “By: ____”، “Date: ____”) كتل حقول.

يقدّم قالب جديد بدايتين:

  • رفع مستند: منطقة إفلات واحدة لملفات .pdf و.docx حتى 25 MB. تُحوَّل ملفات Word إلى PDF وتُفتح في المصمم مع تذكير بمراجعة التخطيط المحوَّل قبل وضع الحقول. تُجرى الإصلاحات الصغيرة في مكانها على ملف PDF (“تحرير المحتوى”)؛ أما لإعادة كتابة أكبر، فعدّل ملف Word وارفعه مرة أخرى.
  • البدء من مستند فارغ: اكتب العقد في وضع المستند.

يغيّر وضع تحرير المحتوى في المصمم ما يراه الموقِّعون دون المساس بالملف المرفوع. وأداته الافتراضية، تحرير النص، تُبرز الكتل النصية في الصفحة (أسطر وفقرات مجمّعة من طبقة النص في ملف PDF)؛ انقر إحداها، أو انتقل إليها بالمفتاح Tab واضغط Enter، لتحريرها في مكانها بالموضع والحجم واللون والمحاذاة والخط أنفسها. يحفظ Ctrl/Cmd+Enter، ويُلغي Esc، ويمكن التراجع عن كل تعديل من قائمة التعديلات. ويمكن التراجع عن التعديلات كأي تغيير آخر. أما الأدوات الأخرى فتضيف تغطية بيضاء ومربعات نص وصورًا، وتُدرج الصفحات أو تحذفها أو تعيد ترتيبها أو تدوّرها.

يُخزَّن تعديل النص في مكانه كعنصرين يتشاركان قيمة group: تغطية بيضاء فوق الكتلة الأصلية (بلون خلفية الصفحة) وعنصر نصي مُخطَّط داخل الكتلة، بارتفاع سطر الكتلة وخط الأساس الأول لها:

edits.items (excerpt)
[
{ "id": "whiteout_k2", "kind": "whiteout", "group": "blk_k1", "page": 0, "color": "#FFFFFF",
"rect": { "x": 71, "y": 209.9, "width": 452, "height": 26.9 } },
{ "id": "text_k3", "kind": "text", "group": "blk_k1", "page": 0, "rect": { "x": 72, "y": 210.9, "width": 451, "height": 24.9 },
"text": "1. Purpose. The Parties wish to evaluate a joint venture…", "original": "1. Purpose. The Parties wish to evaluate a possible business relationship…",
"size": 10.5, "lineHeight": 15.23, "baseline": 7.54, "padding": 0, "align": "left", "color": "#0B0F1A",
"face": { "source": "pdf", "name": "ABCDEF+Calibri", "fallback": "carlito" }, "font": "helvetica" }
]

يختار face الخط: الخط المضمَّن في ملف PDF إذا كان يستطيع رسم كل حرف من النص الجديد، وإلا فخط مرفق متوافق في المقاييس (sans Arimo بدلًا من Helvetica/Arial، وserif Tinos بدلًا من Times، وmono Cousine بدلًا من Courier، وcarlito Carlito بدلًا من Calibri) بالوزن والنمط المطابقين. يلتف النص داخل الكتلة؛ وعندما يحتاج إلى أسطر أكثر من الأصل، يتمدد التعديل في المساحة الفارغة أسفله، ويرفض المصمم حفظه إذا لم توجد مساحة (“النص لا يتسع — اختصره أو أضف مساحة”). يتشارك المصمم والـ API شيفرة التخطيط والخطوط، لذا يطابق ملف PDF المنشور المعاينة سطرًا بسطر.

لا يمكن للتعديلات أن تغيّر إلا مسودة. يطبّقها النشر على ملف PDF أساسي جديد تكون تجزئة SHA-256 الخاصة به هي documentHash للإصدار (تجزئة ما يراه الموقِّعون)؛ ويُحفظ الأصل المرفوع بصفته sourceFile للإصدار، وتبدأ المسودة التالية منه مع التعديلات نفسها. تغطي التغطية البيضاء المحتوى بصريًا؛ ويبقى النص الأصلي في الملف تحتها، لذا فهي ليست تنقيحًا (redaction) آمنًا.

الأدوار هي أطراف العقد. ويُطابَق مستلمو المظروف مع الأدوار حسب key.

{ "key": "client", "label": "Client", "kind": "signer", "order": 1, "verification": "none" }
الخاصية المعنى
key معرّف بأحرف صغيرة (^[a-z][a-z0-9_]*$) تستخدمه الحقول ومستلمو المظروف
kind signer (يجب أن يكون له حقل توقيع أو أحرف أولى)، أو approver، أو form_filler، أو cc (يستلم، ولا يوقّع أبدًا)
order ترتيب التوجيه بدءًا من 1. الأدوار ذات الترتيب نفسه توقّع بالتوازي؛ ويبدأ الترتيب التالي عندما تنتهي
verification كيف يُثبت مستلم الدور هويته: none (الافتراضي: رابط التوقيع الفريد وحده) أو email_otp (الرابط مع رمز مرسل بالبريد الإلكتروني). يمكن للمستلم تجاوزه؛ راجع التحقق من الموقِّع

تظهر passkey وid_check وsms_otp في المخطط لكنها غير متاحة للتوقيع بعد: القالب الذي يستخدم passkey أو id_check لا يمكن نشره، ولا تُسلَّم رموز SMS بعد.

{
"id": "client_signature",
"type": "signature",
"role": "client",
"label": "Signature",
"required": true,
"rect": { "page": 1, "x": 72, "y": 610, "width": 220, "height": 48 }
}

أنواع الحقول: signature، وinitials، وname، وemail، وdate_signed، وtext، وnumber، وdate، وcheckbox، وradio، وdropdown، وattachment، وformula، وstamp، وvariable_text (يملؤه المرسل من متغير، لا الموقِّع). ويمكن أن تحتوي الحقول أيضًا على:

  • variable: مؤشر JSON Pointer داخل المتغيرات (/client/name) لربط الحقل أو تعبئته مسبقًا؛
  • options لحقول radio وdropdown؛
  • validation: pattern أو min أو max أو maxLength أو format (email، phone، date، number، currency)؛
  • showIf: شرط على المتغيرات والحقول الأخرى، مثل plan != "free"؛
  • formula: قيمة محسوبة للقراءة فقط؛
  • overflow: ما يجب فعله عندما لا تتسع القيمة للمربع: shrink (الافتراضي) أو wrap أو reject.

قيمة variables في الإصدار هي JSON Schema (المسودة 2020-12) للبيانات التي ترسلها مع كل مظروف؛ وsampleVariables في الإصدار مثال عليها. يتحقق POST /v1/envelopes من variables الخاصة بك وفقها ويبلّغ عن كل مشكلة مع JSON Pointer:

{
"type": "https://bonafidesign.com/problems/validation-error",
"title": "Validation failed",
"status": 422,
"detail": "The request is invalid.",
"errors": [
{ "pointer": "/variables/client/name", "message": "is required", "hint": "Provide a value for 'name'." }
]
}

لرؤية النتيجة قبل الإرسال، اعرض معاينة تحمل علامة مائية لأي إصدار باستخدام POST /v1/templates/{id}/versions/{version}/render ({ "variables": { … } } → PDF)، أو أنشئ المظروف مع ?dry_run=true.

بناء قالب باستخدام الـ API

Section titled “بناء قالب باستخدام الـ API”

تصمّم معظم الفرق القوالب في مصمم لوحة التحكم. وكل ما يفعله متاح عبر الـ API:

  1. POST /v1/templates مع { "name": "Mutual NDA" }.
  2. POST /v1/templates/{id}/files مع ملف PDF (أو .docx) بصفته الجسم (Content-Type: application/pdf) أو بصفته الحقل متعدد الأجزاء file. حتى 25 MB. تتضمن الاستجابة معرّف الملف (tfl_…) وعدد الصفحات وأحجامها.
  3. PUT /v1/templates/{id}/draft مع roles وfields وvariables (وfile، أو source: "document" مع content). تُحفظ المسودات كما هي؛ ولا يُفحص شيء بعد.
  4. POST /v1/templates/{id}/publish. يفحص النشر المسودة: وجود دور كل حقل، ووجود حقل توقيع لكل دور موقِّع، وملاءمة الحقول لصفحاتها، ووجود خيارات لحقول radio وdropdown، وقابلية التعبيرات للتحليل. وتعود المشكلات بصفتها 422 مع مؤشرات مثل /fields/3/rect.
نافذة طرفيّة
curl https://api.bonafidesign.com/v1/templates/tpl_3kQ9xV2mLp/files \
-H "Authorization: Bearer $BONA_FIDE_API_KEY" \
-H "Content-Type: application/pdf" \
--data-binary @nda.pdf

تقبل نقاط نهاية الإصدارات رقمًا، أو latest، أو draft: GET /v1/templates/{id}/versions/latest، وGET /v1/templates/{id}/versions/2/document (ملف PDF الأساسي). يمكن حذف القالب الذي لم يستخدمه أي مظروف أو رابط توقيع قط؛ وإلا فإن DELETE يجيب بـ 409 in-use.