feat(documenso-phase-7): Project Director RBAC binding

Admin UI binding for the developer + approver user-id fields that
Phase 1 schema'd but left unwired. Surfaces four new fields in the
Documenso settings card so admins can:

  - Set per-port display labels for the developer/approver slots
    (documenso_developer_label / approver_label) — drives email
    subjects + signer-progress UI copy. Defaults to "Developer" /
    "Approver" when blank.
  - Link each slot to a CRM user (documenso_developer_user_id /
    approver_user_id) — UUID from /admin/users.

Webhook side-effect:
- handleRecipientSigned's cascade now fires an in-CRM notification
  for the next pending signer when their signerRole matches a
  configured developer_user_id / approver_user_id. The branded
  email is the primary channel; the notification is a defense-in-
  depth nudge for users who live in the CRM all day.
- New notification type `document_signing_your_turn` with dedupeKey
  `document:<id>:your-turn:<signerId>` so duplicate webhook
  deliveries don't re-notify.
- Falls back silently when the binding isn't set or the signer
  isn't a developer/approver — preserves the existing flow.

Out of scope (build plan flags as out-of-scope for v1):
- Auto-fill name/email when a user is selected: needs a typeahead
  field type the SettingsFormCard doesn't have yet. Admin reads the
  user's UUID from /admin/users and pastes; minor friction for a
  one-time per-port config.
- Webhook handler reading the linked user's email and matching
  against the inbound recipient: today the developer/approver email
  settings already drive the matching; the user-id is purely a
  notification target.

Tests: 1340/1340 ; tsc clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-13 14:08:52 +02:00
parent 7bf587de90
commit b1dfec09a0
2 changed files with 70 additions and 0 deletions

View File

@@ -57,6 +57,24 @@ const SIGNER_FIELDS: SettingFieldDef[] = [
placeholder: 'dm@portnimara.com',
defaultValue: '',
},
{
key: 'documenso_developer_label',
label: 'Developer signer — display label',
description:
'How the developer slot is referenced in email subjects + signer-progress UI copy. Defaults to "Developer" when blank.',
type: 'string',
placeholder: 'Developer',
defaultValue: '',
},
{
key: 'documenso_developer_user_id',
label: 'Developer signer — linked CRM user (optional)',
description:
"Project Director RBAC binding. When set, the webhook handler fires an in-CRM notification for this user when it's their turn to sign — alongside the branded email. Leave blank if the developer slot doesn't map to a CRM user (e.g. external developer). Use the user's UUID from /admin/users.",
type: 'string',
placeholder: '00000000-0000-0000-0000-000000000000',
defaultValue: '',
},
{
key: 'documenso_approver_name',
label: 'Approver — name',
@@ -74,6 +92,24 @@ const SIGNER_FIELDS: SettingFieldDef[] = [
placeholder: 'sales@portnimara.com',
defaultValue: '',
},
{
key: 'documenso_approver_label',
label: 'Approver — display label',
description:
'How the approver slot is referenced in email subjects + signer-progress UI copy. Defaults to "Approver" when blank.',
type: 'string',
placeholder: 'Approver',
defaultValue: '',
},
{
key: 'documenso_approver_user_id',
label: 'Approver — linked CRM user (optional)',
description:
"Same as developer's linked user — when set, fires an in-CRM notification when it's the approver's turn. Use the user's UUID from /admin/users.",
type: 'string',
placeholder: '00000000-0000-0000-0000-000000000000',
defaultValue: '',
},
];
const EOI_FIELDS: SettingFieldDef[] = [