@cemiar/document-analysis
v1.0.20
Published
Cemiar package for document analysis API
Keywords
Readme
@cemiar/document-analysis
SDK for Cemiar Document Analysis API. Provides document comparison, coverage validation, and data extraction capabilities for insurance documents.
Installation
npm install @cemiar/document-analysisQuick Start
import { DocumentAnalysisApi } from "@cemiar/document-analysis";
const api = new DocumentAnalysisApi(
process.env.DOCUMENT_ANALYSIS_URL,
process.env.ACCOUNT_ID
);
// Use the different services
const excelBuffer = await api.comparator.compareRenewalExcel(payload);
const validationResult = await api.coverageValidator.validateFile("intact", file);
const extractedData = await api.extractor.extractDocument(payload);Modules
The SDK provides three main modules accessible via DocumentAnalysisApi:
| Module | Description | Import Path |
|--------|-------------|-------------|
| Comparator | Compare insurance renewal documents | @cemiar/document-analysis/comparator |
| CoverageValidator | Validate coverage against templates | @cemiar/document-analysis/coverage-validation |
| Extractor | Extract structured data from documents | (main export) |
| Common | Shared utilities and types | @cemiar/document-analysis/common |
Comparator
Compare insurance renewal documents and generate comparison reports.
Methods
compareRenewalExcel(payload): Promise<Buffer>
Generate an Excel comparison report between two policy versions.
import { DocumentAnalysisApi } from "@cemiar/document-analysis";
import { RenewalComparisonPayload } from "@cemiar/document-analysis/comparator";
import fs from "fs";
const api = new DocumentAnalysisApi(endpoint, accountId);
const payload: RenewalComparisonPayload = {
before: {
base64: fs.readFileSync("old-policy.pdf").toString("base64"),
year: "2024",
premium: 1200.00
},
after: {
base64: fs.readFileSync("new-policy.pdf").toString("base64"),
year: "2025",
premium: 1350.00
},
client: {
name: "John Doe",
address: ["123 Main St", "Montreal, QC H1A 1A1"],
language: "fr"
},
policyNumber: "POL-123456",
type: "habitation",
coverageValidations: [], // Optional: include validation results
operationId: "op-123" // Optional: for tracking
};
const excelBuffer = await api.comparator.compareRenewalExcel(payload);
fs.writeFileSync("comparison.xlsx", excelBuffer);compareRenewalHtml(payload): Promise<Buffer>
Generate an HTML comparison report between two policy versions.
const htmlBuffer = await api.comparator.compareRenewalHtml(payload);
fs.writeFileSync("comparison.html", htmlBuffer);Types
interface RenewalComparisonPayload {
before: RenewalComparisonStatePayload;
after: RenewalComparisonStatePayload;
client: RenewalComparisonClientPayload;
policyNumber: string;
type?: string;
insurer?: string;
coverageValidations?: CoverageValidationTableResponse[];
operationId?: string;
}
interface RenewalComparisonStatePayload {
base64: string; // Base64-encoded PDF
year: string;
premium: number;
}
interface RenewalComparisonClientPayload {
name: string;
address: string[];
language: Language; // "en" | "fr"
}Coverage Validator
Validate insurance documents against coverage templates to detect missing or insufficient coverage.
Methods
validateFile(insurer, file): Promise<CoverageValidationTemplateResponse>
Validate a PDF document against an insurer's coverage template.
import { DocumentAnalysisApi } from "@cemiar/document-analysis";
import fs from "fs";
const api = new DocumentAnalysisApi(endpoint, accountId);
const file = {
name: "policy.pdf",
buffer: fs.readFileSync("policy.pdf")
};
const result = await api.coverageValidator.validateFile("intact", file);
// Process results
for (const table of result.results) {
console.log(`Table: ${table.tableName}`);
for (const group of table.results) {
console.log(` Group: ${group.groupName || "Default"}`);
for (const coverage of group.results) {
console.log(` Coverage: ${coverage.coverageName}`);
for (const check of coverage.checks) {
if (check.isError) {
console.log(` ❌ ${check.type}: ${check.message}`);
} else {
console.log(` ✅ ${check.type}`);
}
}
}
}
}
// Check for errors
if (result.error) {
console.error(`Validation error: ${result.error.type} - ${result.error.message}`);
}Types
interface CoverageValidationTemplateResponse {
results: CoverageValidationTableResponse[];
error?: CoverageValidationError;
}
interface CoverageValidationTableResponse {
tableName: string;
results: CoverageValidationGroupResponse[];
}
interface CoverageValidationGroupResponse {
groupName?: string;
results: CoverageValidationResponse[];
}
interface CoverageValidationResponse {
coverageName: string;
formName?: string;
checks: CoverageValidationCheckResponse[];
}
interface CoverageValidationCheckResponse {
type: CoverageValidationCheckType;
isError: boolean;
message?: string;
}Enums
enum CoverageValidationCheckType {
MINIMUM_COVERAGE = "MINIMUM_COVERAGE", // Coverage meets minimum requirements
PARTIAL_COVERAGE = "PARTIAL_COVERAGE", // Coverage is partial/limited
PRESENT = "PRESENT" // Coverage is present in document
}
enum CoverageValidationInsurer {
INTACT = "intact"
}Extractor
Extract structured data from insurance documents.
Methods
extractDocument(payload): Promise<ExtractedDocument>
Extract structured coverage data from a PDF document.
import { DocumentAnalysisApi } from "@cemiar/document-analysis";
import fs from "fs";
const api = new DocumentAnalysisApi(endpoint, accountId);
const result = await api.extractor.extractDocument({
base64: fs.readFileSync("policy.pdf").toString("base64"),
insurer: "intact",
language: "fr",
operation_id: "op-123"
});
console.log(`Insurer: ${result.insurer}`);
console.log(`Language: ${result.language}`);
console.log(`Premium: ${result.premium}`);
for (const situation of result.situations) {
console.log(`\nSituation: ${situation.label}`);
console.log(` Address: ${situation.address}`);
for (const table of situation.tables) {
console.log(` Table Headers: ${table.header.join(" | ")}`);
for (const row of table.rows) {
console.log(` ${row.join(" | ")}`);
}
}
}Types
interface ExtractDocumentPayload {
base64: string; // Base64-encoded PDF
insurer: string; // Insurer identifier
language: Language; // "en" | "fr"
operation_id: string; // Unique operation ID for tracking
}
interface ExtractedDocument {
insurer: string;
language: Language;
situations: Situation[];
premium?: number | string;
globalSituationLabel?: string;
}
interface Situation {
label: string;
address?: string;
other?: string;
tables: Table[];
}
interface Table {
header: string[];
rows: string[][];
}Common Utilities
Language Type
import { Language } from "@cemiar/document-analysis/common";
const lang: Language = "fr"; // "en" | "fr"Module Imports
You can import modules directly for tree-shaking:
// Main API
import { DocumentAnalysisApi } from "@cemiar/document-analysis";
// Comparator types and schemas
import {
RenewalComparisonPayload,
RenewalComparisonStatePayload,
RenewalComparisonClientPayload
} from "@cemiar/document-analysis/comparator";
// Coverage validation types and enums
import {
CoverageValidationTemplateResponse,
CoverageValidationTableResponse,
CoverageValidationResponse,
CoverageValidationCheckType,
CoverageValidationInsurer
} from "@cemiar/document-analysis/coverage-validation";
// Common utilities
import { Language } from "@cemiar/document-analysis/common";Environment Variables
| Variable | Description |
|----------|-------------|
| DOCUMENT_ANALYSIS_URL | Base URL of the Document Analysis API |
| ACCOUNT_ID | Account identifier for API authentication |
Complete Example
import { DocumentAnalysisApi } from "@cemiar/document-analysis";
import { RenewalComparisonPayload } from "@cemiar/document-analysis/comparator";
import fs from "fs";
async function analyzeRenewal() {
const api = new DocumentAnalysisApi(
process.env.DOCUMENT_ANALYSIS_URL!,
process.env.ACCOUNT_ID!
);
// Read PDF files
const oldPolicy = fs.readFileSync("old-policy.pdf");
const newPolicy = fs.readFileSync("new-policy.pdf");
// Step 1: Validate coverage on new policy
const validation = await api.coverageValidator.validateFile("intact", {
name: "new-policy.pdf",
buffer: newPolicy
});
// Check for coverage issues
const hasErrors = validation.results.some(table =>
table.results.some(group =>
group.results.some(coverage =>
coverage.checks.some(check => check.isError)
)
)
);
if (hasErrors) {
console.warn("⚠️ Coverage validation found issues");
}
// Step 2: Extract data from new policy
const extracted = await api.extractor.extractDocument({
base64: newPolicy.toString("base64"),
insurer: "intact",
language: "fr",
operation_id: `renewal-${Date.now()}`
});
console.log(`Found ${extracted.situations.length} situations`);
// Step 3: Generate comparison report
const payload: RenewalComparisonPayload = {
before: {
base64: oldPolicy.toString("base64"),
year: "2024",
premium: 1200
},
after: {
base64: newPolicy.toString("base64"),
year: "2025",
premium: extracted.premium ? Number(extracted.premium) : 0
},
client: {
name: "Jean Dupont",
address: ["123 Rue Principale", "Montréal, QC H1A 1A1"],
language: "fr"
},
policyNumber: "POL-123456",
type: "habitation",
coverageValidations: validation.results,
operationId: `renewal-${Date.now()}`
};
// Generate Excel report
const excelBuffer = await api.comparator.compareRenewalExcel(payload);
fs.writeFileSync("renewal-comparison.xlsx", excelBuffer);
// Generate HTML report
const htmlBuffer = await api.comparator.compareRenewalHtml(payload);
fs.writeFileSync("renewal-comparison.html", htmlBuffer);
console.log("✅ Renewal analysis complete!");
}
analyzeRenewal().catch(console.error);Building
npm run buildOutput will be generated under dist/.
