Settings Schema (v1)
Your listing declares a settings form that Dentolize renders natively in the clinic UI (web now, mobile later), Arabic and English included. Your service reads the saved values from GET /api/v1/installation and receives plugin.settings.updated webhooks on change.
With the settings:write scope your service can also update its own settings via PATCH /api/v1/installation/settings (SDK: client.installation.updateSettings(values)) — useful for sync cursors or connection state. The body is the full settings object, validated against the same schema as UI saves; submit the "__SET__" sentinel to keep a stored secret. The PATCH response returns secrets masked and the change fires plugin.settings.updated. (GET /installation still returns real secret values — your service needs them to function; only clinic-UI reads are masked.)
The contract is defined (types + validators) in @dentolize/plugin-sdk — build your schema with defineSettingsSchema() to validate locally before submission.
{
"version": 1,
"sections": [
{
"key": "reminders",
"title": { "en": "Reminder settings", "ar": "إعدادات التذكير" },
"fields": [
{
"key": "hoursBefore", // ^[a-zA-Z][a-zA-Z0-9_]{0,63}$, unique across schema
"type": "number", // text | secret | number | boolean | select | multiselect | url
"label": { "en": "Hours before", "ar": "ساعات قبل الموعد" },
"help": { "en": "…", "ar": "…" }, // optional
"required": true,
"default": 24,
"validation": { "min": 1, "max": 168 }, // minLength/maxLength/pattern for strings
"visibleIf": { "field": "enabled", "equals": true } // one flat condition, no chaining
}
]
}
]
}
Rules
- Labels/help are inline
{en, ar}objects — English required, Arabic strongly recommended (review checks it). select/multiselectrequire non-emptyoptions; values are validated server-side against them.urlvalues must behttps://.secretfields are write-only: clients see the sentinel"__SET__"instead of stored values, and submitting the sentinel keeps the stored value. Secrets cannot declare defaults. Your service receives the real value viaGET /api/v1/installation.- Limits: ≤10 sections, ≤50 fields total. Unknown properties or field types are rejected at publish.
- Hidden fields (failing
visibleIf) skip validation, includingrequired. - Client-side validation is UX only — the server re-validates every save with the same validators.