79 lines
2.5 KiB
Python
79 lines
2.5 KiB
Python
"""
|
|
normalized_template.py
|
|
-----------------------
|
|
Platform-agnostic intermediate schema that decouples Adobe Sign extraction
|
|
from DocuSign composition. Both platforms' data is converted to/from this
|
|
model so neither side is tightly coupled.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from enum import Enum
|
|
from typing import Any, Optional
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class ActionType(str, Enum):
|
|
SIGN = "SIGN"
|
|
APPROVE = "APPROVE"
|
|
CC = "CC"
|
|
ACKNOWLEDGE = "ACKNOWLEDGE"
|
|
|
|
|
|
class NormalizedRole(BaseModel):
|
|
name: str
|
|
order: int
|
|
action_type: ActionType = ActionType.SIGN
|
|
|
|
|
|
class NormalizedField(BaseModel):
|
|
"""One form field in the normalized intermediate representation."""
|
|
type: str # e.g. "signature", "text", "checkbox"
|
|
label: str
|
|
page: int
|
|
x: float
|
|
y: float
|
|
width: float
|
|
height: float
|
|
required: bool = False
|
|
read_only: bool = False
|
|
role_name: str = "" # which role this field belongs to
|
|
options: list[str] = Field(default_factory=list) # for dropdown/radio
|
|
validation: str = "" # e.g. "DATE", "NUMBER"
|
|
content_type: str = "" # e.g. "SIGNATURE_DATE", "SIGNER_NAME"
|
|
conditional_parent_label: Optional[str] = None
|
|
conditional_parent_value: Optional[str] = None
|
|
raw: dict[str, Any] = Field(default_factory=dict) # original source data
|
|
|
|
|
|
class NormalizedDocument(BaseModel):
|
|
name: str
|
|
content_base64: str = "" # base64-encoded PDF bytes
|
|
checksum_sha256: str = "" # SHA-256 hex of raw bytes before encoding
|
|
source_path: str = ""
|
|
|
|
|
|
class NormalizedTemplate(BaseModel):
|
|
"""
|
|
Platform-agnostic representation of an eSignature template.
|
|
Used as the bridge between Adobe Sign and DocuSign.
|
|
"""
|
|
name: str
|
|
description: str = ""
|
|
email_subject: str = ""
|
|
email_message: str = ""
|
|
roles: list[NormalizedRole] = Field(default_factory=list)
|
|
documents: list[NormalizedDocument] = Field(default_factory=list)
|
|
fields: list[NormalizedField] = Field(default_factory=list)
|
|
reminder_enabled: bool = False
|
|
expiration_days: Optional[int] = None
|
|
source_id: str = "" # original Adobe Sign template ID
|
|
unsupported_features: list[str] = Field(default_factory=list)
|
|
|
|
def role_names(self) -> list[str]:
|
|
return [r.name for r in self.roles]
|
|
|
|
def fields_for_role(self, role_name: str) -> list[NormalizedField]:
|
|
return [f for f in self.fields if f.role_name == role_name]
|