렌더링 헬퍼
순수 로직은 별도의 파일로 분리해 두어 단위 테스트를 쉽게 할 수 있도록 하세요. 이는 레코드를{{dot.path}} 토큰으로 평탄화하고, 해당 토큰을 치환합니다.
핸들러
핸들러는 생성된CoreApiClient를 사용해 CRM 데이터를 읽고 씁니다. 템플릿을 불러오고, 대상 레코드를 불러온 뒤, 본문을 채우고 document를 생성합니다.
loadRecordValues는 Person과 Company에 대해 서로 다른 쿼리를 실행하고 결과를 평탄화합니다. 자세한 내용은
load-record-values.ts를 참조하세요.
도구와 워크플로 작업으로 노출하기
하나의defineLogicFunction에 여러 트리거를 실을 수 있습니다. 여기서는 toolTriggerSettings로 AI 에이전트가 호출할 수 있게 하고, workflowActionTriggerSettings로 시각적 워크플로 빌더에서 하나의 단계가 되도록 합니다. 둘 모두 JSON 스키마로 입력을 설명합니다.
templateId와 recordId를 설명하는 일반 JSON 스키마입니다. 자세한 내용은 generate-document-input.schema.ts를 참조하세요.
접근 권한 부여하기
로직 함수는 앱의 역할로 실행됩니다. 템플릿과 레코드를 읽고 문서를 생성해야 하므로,src/roles/default-role.ts에서 해당 권한을 허용하세요:
UPLOAD_FILE은 다음 섹션에서 함수가 생성된 PDF를 업로드할 수 있게 해 줍니다.
보다 세분화된 권한에 대해서는 Roles를 참조하세요.
실제 PDF 파일 첨부하기
렌더링된 텍스트 필드만으로도 유용하지만, 사용자들은 실제 문서를 원합니다. 이제 PDF를 생성하여 레코드에 다운로드 가능한 파일로 저장해 봅시다. 먼저,document 객체에 PDF를 담을 FILES 필드를 추가합니다. 앱은 자신의 파일 필드로 업로드하므로, 이 필드가 업로드 경로를 결정합니다.
generate-document-pdf.ts에 있습니다.
이 헬퍼는 marked.lexer로 Markdown을 토큰으로 파싱한 뒤, pdf-lib으로 레이아웃합니다. 실제 제목, 굵게/기울임 처리, 글머리 기호 및 번호 목록, 인용 블록과 구분선 등, 텍스트 덩어리가 아니라 템플릿 자체를 다듬어진 다중 페이지 A4 렌더링으로 만들어 줍니다.

pdf-lib의 기본 제공 폰트는 WinAnsi 인코딩을 사용하므로, 서유럽 악센트 문자는 별도 설정 없이 렌더링됩니다. 헬퍼는 스마트 따옴표와 대시를 매핑하고, 인코딩할 수 없는 문자는 제거합니다. 비라틴 문자(중국어, 아랍어, 키릴 문자 등)를 렌더링하려면 Unicode 폰트를 임베딩해야 합니다.
uploadFile은 바이트를 앱이 소유한 파일 필드로 라우팅하며, 반환된 id가 저장해야 할 값입니다.

uploadFile은 앱이 소유한 파일 필드만을 대상으로 합니다(따라서 업로드에는 항상 해당 필드를 소유한 앱과 UPLOAD_FILE 역할 플래그가 필요합니다). 그래서 PDF는 레코드의 자체 file 필드에 저장됩니다. 이는
call-recorder 앱이 녹음을 위해 사용하는 것과 동일한 패턴입니다.다음: HTTP 경로 →
HTTP를 통해 함수를 제공하고 문서를 웹 페이지로 렌더링합니다.