Document Signing
File Starter also provides a lightweight signing flow built on top of SigningRequest and SigningDocument.
Signing Model
SigningRequest: signing transaction header, recipient, status, expiration time, and relatedSigningDocumentlist.SigningDocument: one signable document under a signing request.
Current implementation stores a compact set of top-level fields on SigningDocument:
- business fields:
signingRequestId,templateId,signSlotCode,status - generated file fields:
signedImageId,signedPdfId - signer fields:
signerUserId,signerName,signedAt - audit correlation:
evidenceId - full evidence payload:
signatureEvidence(JsonNode)
signatureEvidence contains:
evidenceIdsignSlotCodeclientPayloadresolvedPlacementresolvedRenderOptionsserverEvidencesignatureMethodsignerUserId,signerNameserverSignedAtclientIp,userAgentsignatureImageFileId,generatedSignedFileId,originalTemplateFileIdoriginalPdfSha256,signatureImageSha256,signedPdfSha256
Status
SigningRequestStatus:
DraftSentInProgressCompletedCancelledExpired
SigningDocumentStatus:
PendingInProgressCompleted
Sign Endpoint
Endpoint:
POST /SigningDocument/sign?id={id}
Content type:
multipart/form-data
Parts:
signatureFile: handwritten signature image file, usually PNGpayload: JSON payload ofSigningDocumentSignRequest
Request DTO:
{
"signSlotCode": "EMPLOYEE_SIGN",
"placement": {
"page": 1,
"x": 120,
"y": 90,
"width": 180,
"height": 64,
"unit": "PT"
},
"evidence": {
"signatureMethod": "DRAW",
"clientSignedAt": "2026-03-24T10:15:30+08:00",
"clientTimeZone": "Asia/Shanghai",
"consentAccepted": true,
"consentTextVersion": "v1",
"signerDisplayName": "Alice",
"userAgent": "Mozilla/5.0",
"canvasWidth": 800,
"canvasHeight": 240
},
"renderOptions": {
"flattenToPdf": true,
"keepSignatureImage": true,
"imageScaleMode": "FIT"
}
}Response DTO:
{
"signingDocumentId": 9001,
"status": "Completed",
"signedFile": {
"fileId": 701,
"fileName": "contract_signed_20260324.pdf",
"fileType": "PDF",
"url": "https://...",
"size": 256,
"checksum": "..."
},
"signatureImageFile": {
"fileId": 700,
"fileName": "signature.png",
"fileType": "PNG",
"url": "https://...",
"size": 12,
"checksum": "..."
},
"signedAt": "2026-03-24T10:15:32+08:00",
"evidenceId": "abc123"
}Signing Rules
The current sign flow completes the following steps in one request:
- Validate current user, recipient, signing request status, and expiration time.
- Upload the signature image file and persist
signedImageId. - Build the original PDF from
DocumentTemplate. - Resolve signature placement:
- Prefer
signSlotCodeby locating a PDF form field in the source PDF. - Fallback to
placementif the slot does not exist or the source PDF has no matching field.
- Prefer
- Stamp the signature image onto the PDF.
- Upload the signed PDF and persist
signedPdfId. - Persist
signatureEvidence,evidenceId, signer info, and sign timestamp. - Update
SigningDocument.statusand refreshSigningRequest.status.
DocumentTemplateSignSlot
DocumentTemplateSignSlot stores predefined sign slot configurations for a document template.
Each slot defines a named region where a signature can be placed.
| Field | Type | Description |
|---|---|---|
templateId | Long | Parent DocumentTemplate ID |
slotName | String | Display name for the slot |
slotCode | String | Code used in signSlotCode during signing |
sequence | Integer | Order of the slot |
placement | JsonNode | Default placement coordinates (page, x, y, width, height, unit) |
description | String | Description text |
CRUD is available via POST/GET/PUT/DELETE /DocumentTemplateSignSlot.
Placement Resolution
signSlotCodeis the recommended mode for template-defined sign slots. The system first tries to locate a matching PDF form field in the source PDF; if not found, it looks up theDocumentTemplateSignSlotby code.placementis the fallback for free positioning.- Supported placement units:
PTPXMMCMIN
Current Limitation
The current signing implementation builds the original PDF only from DocumentTemplate:
DocumentTemplate.fileIdwithPDFis used directlyDocumentTemplate.fileIdwithDOCXis rendered with empty data and then converted to PDFDocumentTemplate.htmlTemplateis rendered with empty data and converted to PDF
This means the current implementation is suitable for:
- signing fixed PDF templates
- signing static DOCX or HTML templates without business-row rendering
It does not yet support:
- signing a document that must first be rendered with business row data and then assigned to a
SigningDocument