/** * @file contract.ts * @description Enhanced portable contract interface * The main contract data structure that ties all modules together */ import * as plugins from './plugins.js'; import type { TContractCategory, TContractType, TContractStatus, TPartyRole, TSigningDependency, TLegalCapacity, TSectionType, TVariableType, TConditionOperator, TConditionCombine, TLegalReferenceType, TDisputeResolution, TSignatureType, TSignatureLegalLevel, TConfidentialityLevel, } from './types.js'; import type { IFinancialTerms, ITimeTerms, IObligationTerms, createEmptyFinancialTerms, createEmptyTimeTerms, createEmptyObligationTerms, } from './terms.js'; import type { ISignature, ISignatureFieldPlacement, ISignatureFieldRequirements, ISignatureDependency } from './signature.js'; import type { IIdentityVerificationResult } from './identity.js'; import type { ILegalComplianceProof } from './legal.js'; import type { IVersionHistory, IVersion } from './versioning.js'; import type { ICollaborator, ICommentThread, ISuggestion } from './collaboration.js'; import type { IDocumentLifecycle, IAuditLog } from './lifecycle.js'; import type { IContractAttachment, IPriorContractReference } from './attachments.js'; import type { IPdfGenerationConfig } from './pdf.js'; // ============================================================================ // METADATA // ============================================================================ /** * Governing law and jurisdiction */ export interface IGoverningLaw { country: string; state?: string; applicableLaws: string[]; disputeJurisdiction?: string; disputeResolution: TDisputeResolution; arbitrationInstitution?: string; arbitrationRules?: string; arbitrationSeat?: string; numberOfArbitrators?: number; proceedingsLanguage?: string; } /** * Contract metadata */ export interface IContractMetadata { contractNumber?: string; category: TContractCategory; contractType: TContractType; language: string; additionalLanguages: string[]; bindingLanguage?: string; governingLaw: IGoverningLaw; tags: string[]; internalReference?: string; externalReference?: string; templateId?: string; parentContractId?: string; relatedContractIds: string[]; confidentialityLevel: TConfidentialityLevel; customFields: Record; } // ============================================================================ // ROLES AND PARTIES // ============================================================================ /** * Role definition */ export interface IRole { id: string; name: string; description: string; category: 'party' | 'witness' | 'notary' | 'guarantor' | 'beneficiary'; signatureRequired: boolean; defaultSigningOrder: number; legalCapacity?: TLegalCapacity; notifyOnChanges: boolean; notifyOnComments: boolean; displayColor?: string; icon?: string; minParties?: number; maxParties?: number; } /** * Legal proxy information */ export interface ILegalProxy { type: 'self' | 'company_representative' | 'power_of_attorney' | 'guardian' | 'other'; representedEntity: plugins.tsclass.business.TContact; position?: string; poaDocumentId?: string; authorityScope?: string; } /** * Party signature status */ export interface IPartySignature { status: 'pending' | 'viewed' | 'signed' | 'declined' | 'voided'; signedAt?: number; signature?: ISignature; declinedAt?: number; declineReason?: string; } /** * Involved party in contract */ export interface IInvolvedParty { partyId: string; roleId: string; contact: plugins.tsclass.business.TContact; partyRole: TPartyRole; signingOrder: number; signingDependency: TSigningDependency; dependsOnParties: string[]; signature: IPartySignature; identityVerification?: IIdentityVerificationResult; legalComplianceProof?: ILegalComplianceProof; actingAsProxy: boolean; legalProxy?: ILegalProxy; deliveryEmail?: string; deliveryPhone?: string; preferredLanguage?: string; internalNotes?: string; invitationSentAt?: number; remindersSent: number; lastReminderAt?: number; firstViewedAt?: number; lastViewedAt?: number; totalViews: number; metadata: Record; } // ============================================================================ // CONTENT STRUCTURE // ============================================================================ /** * Variable validation rules */ export interface IVariableValidation { pattern?: string; minLength?: number; maxLength?: number; min?: number; max?: number; options?: string[]; } /** * Variable format specification */ export interface IVariableFormat { dateFormat?: string; numberFormat?: string; currencyFormat?: string; } /** * Variable source configuration */ export interface IVariableSource { type: 'party_field' | 'contract_field' | 'calculated' | 'external' | 'manual'; path?: string; formula?: string; externalSource?: string; } /** * Variable/placeholder definition */ export interface IVariable { variableId: string; name: string; type: TVariableType; value?: unknown; defaultValue?: unknown; required: boolean; source?: IVariableSource; validation?: IVariableValidation; format?: IVariableFormat; } /** * Condition for conditional content */ export interface ICondition { conditionId: string; field: string; operator: TConditionOperator; value: unknown; combine?: TConditionCombine; nestedConditions: ICondition[]; } /** * Legal reference annotation */ export interface ILegalReference { type: TLegalReferenceType; citation: string; url?: string; jurisdiction?: string; effectiveDate?: number; } /** * Paragraph translation */ export interface IParagraphTranslation { title: string; content: string; } /** * Paragraph/section in contract */ export interface IParagraph { uniqueId: string; parentId: string | null; title: string; content: string; sectionType: TSectionType; numbering?: string; order: number; depth: number; required: boolean; isEditable: boolean; variables: IVariable[]; conditions: ICondition[]; legalReferences: ILegalReference[]; language?: string; translations: Record; crossReferences: string[]; attachmentReferences: string[]; jurisdictions: string[]; tags: string[]; aiGenerated: boolean; templateSourceId?: string; lastEditedBy?: string; lastEditedAt?: number; lockedBy?: string; lockedAt?: number; } // ============================================================================ // SIGNATURE FIELDS // ============================================================================ /** * Signer assignment to signature field */ export interface ISignerAssignment { id: string; partyId?: string; email: string; phone?: string; signingOrder: number; invitationStatus: 'not_sent' | 'sent' | 'delivered' | 'opened' | 'bounced'; invitationSentAt?: number; deliveredAt?: number; openedAt?: number; remindersSent: number; lastReminderAt?: number; accessTokenHash?: string; tokenExpiresAt?: number; } /** * Signature field in contract */ export interface ISignatureField { id: string; name: string; description?: string; placement: ISignatureFieldPlacement; requirements: ISignatureFieldRequirements; dependencies: ISignatureDependency[]; assignedSigner?: ISignerAssignment; status: 'pending' | 'ready' | 'in_progress' | 'completed' | 'declined' | 'expired' | 'voided'; signature?: ISignature; createdAt: number; updatedAt: number; } // ============================================================================ // MAIN CONTRACT INTERFACE // ============================================================================ /** * Complete portable contract interface * All fields are required - use empty arrays/objects where no data */ export interface IPortableContract { // Core Identity id: string; title: string; context: string; metadata: IContractMetadata; // Parties and Roles availableRoles: IRole[]; involvedParties: IInvolvedParty[]; // Content Structure paragraphs: IParagraph[]; variables: IVariable[]; signatureFields: ISignatureField[]; // Structured Terms financialTerms: IFinancialTerms; timeTerms: ITimeTerms; obligationTerms: IObligationTerms; // Documents priorContracts: IPriorContractReference[]; attachments: IContractAttachment[]; // Versioning versionHistory: IVersionHistory; // Collaboration collaborators: ICollaborator[]; commentThreads: ICommentThread[]; suggestions: ISuggestion[]; // Lifecycle and Audit lifecycle: IDocumentLifecycle; auditLog: IAuditLog; // PDF Generation (optional) pdfConfig?: IPdfGenerationConfig; finalDocument?: plugins.tsclass.business.IPdf; renderTemplateId?: string; renderOptions?: Record; // Timestamps createdAt: number; createdBy: string; updatedAt: number; updatedBy?: string; // Organization organizationId?: string; visibility: 'private' | 'organization' | 'public'; // Integrations integrations: { crmId?: string; erpId?: string; customIntegrations: Record; }; } // ============================================================================ // FACTORY FUNCTIONS // ============================================================================ import { createEmptyFinancialTerms as _createEmptyFinancialTerms, createEmptyTimeTerms as _createEmptyTimeTerms, createEmptyObligationTerms as _createEmptyObligationTerms, } from './terms.js'; import { createInitialVersion, createEmptyVersionHistory } from './versioning.js'; import { createInitialLifecycle, createEmptyAuditLog } from './lifecycle.js'; /** * Create default governing law */ export function createDefaultGoverningLaw(): IGoverningLaw { return { country: '', applicableLaws: [], disputeResolution: 'litigation', }; } /** * Create default contract metadata */ export function createDefaultMetadata( category: TContractCategory, contractType: TContractType, language: string = 'en' ): IContractMetadata { return { category, contractType, language, additionalLanguages: [], governingLaw: createDefaultGoverningLaw(), tags: [], relatedContractIds: [], confidentialityLevel: 'internal', customFields: {}, }; } /** * Create a new empty contract */ export function createEmptyContract( title: string, category: TContractCategory, contractType: TContractType, createdBy: string, language: string = 'en' ): IPortableContract { const id = crypto.randomUUID(); const now = Date.now(); const initialVersion = createInitialVersion(createdBy); return { id, title, context: '', metadata: createDefaultMetadata(category, contractType, language), availableRoles: [], involvedParties: [], paragraphs: [], variables: [], signatureFields: [], financialTerms: _createEmptyFinancialTerms(), timeTerms: _createEmptyTimeTerms(), obligationTerms: _createEmptyObligationTerms(), priorContracts: [], attachments: [], versionHistory: createEmptyVersionHistory(id, initialVersion), collaborators: [], commentThreads: [], suggestions: [], lifecycle: createInitialLifecycle(id), auditLog: createEmptyAuditLog(id), createdAt: now, createdBy, updatedAt: now, visibility: 'private', integrations: { customIntegrations: {}, }, }; } /** * Create a new role */ export function createRole( id: string, name: string, description: string, options: Partial = {} ): IRole { return { id, name, description, category: 'party', signatureRequired: true, defaultSigningOrder: 1, notifyOnChanges: true, notifyOnComments: true, ...options, }; } /** * Create an involved party */ export function createInvolvedParty( roleId: string, contact: plugins.tsclass.business.TContact, signingOrder: number = 1 ): IInvolvedParty { return { partyId: crypto.randomUUID(), roleId, contact, partyRole: 'signer', signingOrder, signingDependency: 'none', dependsOnParties: [], signature: { status: 'pending', }, actingAsProxy: false, remindersSent: 0, totalViews: 0, metadata: {}, }; } /** * Create a paragraph */ export function createParagraph( title: string, content: string, sectionType: TSectionType = 'clause', order: number = 0 ): IParagraph { return { uniqueId: crypto.randomUUID(), parentId: null, title, content, sectionType, order, depth: 0, required: true, isEditable: true, variables: [], conditions: [], legalReferences: [], translations: {}, crossReferences: [], attachmentReferences: [], jurisdictions: [], tags: [], aiGenerated: false, }; } /** * Create a variable */ export function createVariable( variableId: string, name: string, type: TVariableType, required: boolean = true ): IVariable { return { variableId, name, type, required, }; }