Add document approval workflow

Introduce a complete approval system for document publishing. Document
versions can now require approval from selected reviewers before being
published, with automatic publishing once all approvers have approved.

- Add approval quorum and decision tables with backfill migration
- Implement request approval, approve, and reject flows with electronic
  signature support for approve decisions
- Add employee approvals page with dedicated tab and pending approvals view
- Add changelog field to publish and request approval flows
- Pre-select previous version's approvers in the publish dialog
- Show quorum approvers in document list with 100 approver hard limit
- Expose approval workflow through GraphQL, MCP, and CLI
- Remove legacy default approvers feature entirely
- Add comprehensive e2e test coverage for approval workflows

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2026-03-27 17:22:54 +01:00
parent 4a2d308da0
commit 999171a626
78 changed files with 6483 additions and 1600 deletions

View File

@@ -0,0 +1,36 @@
import { Button, Section, Text } from '@react-email/components';
import * as React from 'react';
import EmailLayout, { bodyText, button, buttonContainer, footerText } from './components/EmailLayout';
export const DocumentApproval = () => {
return (
<EmailLayout subject={'Action Required – Please review and approve {{.DocumentName}}'}>
<Text style={bodyText}>
You're receiving this message because <strong>{'{{.OrganizationName}}'}</strong> has requested your approval on the document <strong>{'{{.DocumentName}}'}</strong>.
</Text>
<Text style={bodyText}>
Please take a moment to review the document and approve or reject it by clicking the button below:
</Text>
<Section style={buttonContainer}>
<Button style={button} href={'{{.ApprovalUrl}}'}>
Review and Approve
</Button>
</Section>
<Text style={bodyText}>
If you have any questions, please contact your security team.
</Text>
<Text style={footerText}>
This process is managed securely by Probo, acting as the compliance partner on behalf of <strong>{'{{.OrganizationName}}'}</strong>.
Thank you for your prompt attention to this matter.
</Text>
<Text style={footerText}>
Best regards,
</Text>
</EmailLayout>
);
};
export default DocumentApproval;

View File

@@ -8,10 +8,10 @@ import EmailLayout, {
export const ElectronicSignatureCertificate = () => {
return (
<EmailLayout
subject={`Your signed ${"{{.DocumentType}}"} — Certificate of Completion`}
subject={`Your signed ${"{{.DocumentName}}"} — Certificate of Completion`}
>
<Text style={bodyText}>
Your <strong>{"{{.DocumentType}}"}</strong> has been signed
Your <strong>{"{{.DocumentName}}"}</strong> has been signed
electronically. A Certificate of Completion is attached to this email
as a PDF document.
</Text>