/** * Ports = interfaces only (CLAUDE.md #1). Adapters implement these; apps wire * them. NO framework/SDK imports allowed here (enforced by eslint boundary). */ import type { AdapterCapability, Channel, ProofState, LegalSupportLevel, } from "@courtmitra/contracts"; /** Anything an adapter can do, plus what it can do *right now* in this env. */ export interface CapabilityAware { capabilities(): AdapterCapability[]; } // --- LLM --------------------------------------------------------------------- /** Minimal schema carrier (a Zod schema satisfies this) — keeps ports SDK-free. */ export interface OutputSchema { parse(input: unknown): T; } export interface LlmStructuredRequest { /** Versioned prompt id from packages/prompts — never an inline prompt. */ promptId: string; /** Variables interpolated into the prompt template. */ variables: Record; /** Schema the adapter validates the model output against (CLAUDE.md: never pass through). */ schema: OutputSchema; /** Optional images (data URLs / storage refs) for vision parsing. */ images?: string[]; model?: string; temperature?: number; } export interface LlmStructuredResult { output: T; raw: string; model: string; usage?: { inputTokens: number; outputTokens: number }; } export interface LlmPort { generateStructured(req: LlmStructuredRequest): Promise>; } // --- Embedding --------------------------------------------------------------- export interface EmbeddingPort { embed(texts: string[]): Promise; dimensions: number; } // --- Legal retrieval / verification ----------------------------------------- export interface LegalQuery { missionId: string; issueDomain: string; query: string; topK?: number; } export interface RetrievedLegalSource { chunkId: string; sourceId: string; actName: string | null; sectionNo: string | null; heading: string | null; text: string; score: number; } export interface ClaimSupportCheck { /** Unique mission identifier — required to persist legal_claim_verifications. */ missionId: string; claim: string; quoteSpans: string[]; chunkIds: string[]; } export interface ClaimSupportResult { supported: boolean; supportLevel: LegalSupportLevel; citedChunkIds: string[]; failureReason: string | null; } export interface LegalRetrievalPort { retrieve(q: LegalQuery): Promise; /** Verify = literal quote-span substring match against chunk.text (CLAUDE.md #4). */ verifyClaimSupport(i: ClaimSupportCheck): Promise; } // --- Evidence parsing (Phase 1 = vision-LLM) -------------------------------- export interface EvidenceFile { evidenceItemId: string; storageKey: string; mimeType: string; } export interface ParsedEvidence { rawText: string; entities: Record; dates: string[]; money: { amount: number; currency: string; original: string }[]; parties: string[]; confidence: number; } export interface EvidenceParserPort { parse(file: EvidenceFile): Promise; } // --- ASR / Transcription (Phase 2 Module 2) -------------------------------- export interface AsrTranscribeRequest { audioBytes: Uint8Array; mimeType: string; languageHint?: string; } export interface AsrTranscribeResult { text: string; language: string; confidence: number; durationMs: number; } export interface AsrPort { transcribe(request: AsrTranscribeRequest): Promise; } // --- Translation (Phase 2 Module 3) ---------------------------------------- export interface TranslationDetectRequest { text: string; } export interface TranslationDetectResult { language: string; confidence: number; } export interface TranslationTranslateRequest { text: string; sourceLang?: string; targetLang: string; } export interface TranslationTranslateResult { originalText: string; translatedText: string; sourceLang: string; targetLang: string; confidence: number; model: string; } export interface TranslationPort { detectLanguage(text: string): Promise; translate(request: TranslationTranslateRequest): Promise; } // --- Portal Assist (Phase 2 Module 5) ------------------------------------- export interface PortalAssistSessionState { sessionId: string; state: string; portalUrl: string; formFields: { selector: string; label: string; value: string | null; filled: boolean }[]; screenshotStorageKey: string | null; receiptStorageKey: string | null; errorMessage: string | null; } export interface PortalAssistPort { init(): Promise; fillFields(sessionId: string, url: string, fields: FormField[]): Promise; captureScreenshot(sessionId: string): Promise; waitForUserAction(state: string): Promise; captureScreenshotAfterSubmit(sessionId: string): Promise<{ bytes: Uint8Array; url: string }>; close(): Promise; } export interface FormField { label: string; value: string; } // --- Social Publishing (Phase 2 Module 7) ---------------------------------- export interface SocialPublishRequest { text: string; platform: string; cardBytes?: Uint8Array; cardMimeType?: string; consentGrantId: string; missionId: string; actionId: string; } export interface SocialPublishResult { published: boolean; proofState: string; externalPostId: string | null; postUrl: string | null; failureReason: string | null; } export interface SocialPublisherPort extends CapabilityAware { publish(request: SocialPublishRequest): Promise; } // --- Case Lookup / eCourts (Phase 2 Module 8) ----------------------------- export interface CaseLookupRequest { cnrNumber: string; } export interface CaseLookupResponse { cnrNumber: string; caseNumber: string | null; courtName: string | null; petitioner: string | null; respondent: string | null; caseStatus: string | null; nextHearingDate: string | null; lastOrderDate: string | null; lastOrderSummary: string | null; rawData: Record | null; } export interface CaseLookupPort extends CapabilityAware { lookup(request: CaseLookupRequest): Promise; } // --- Channels ---------------------------------------------------------------- export interface ChannelMessage { channel: Channel; to: string; body: string; } export interface InteractiveMessage extends ChannelMessage { buttons: { id: string; label: string }[]; } export interface ChannelSendResult { providerMessageId: string | null; proofState: ProofState; } export interface ChannelPort extends CapabilityAware { sendMessage(m: ChannelMessage): Promise; sendInteractive(m: InteractiveMessage): Promise; } // --- Submission (email / portal packet) ------------------------------------- export interface SubmissionRequest { missionId: string; actionId: string; destination: string; subject?: string; body: string; attachments: { id: string; storageKey: string; filename: string }[]; idempotencyKey: string; } export interface SubmissionResult { proofState: ProofState; externalReference: string | null; proofRef: Record; } export interface SubmissionPort extends CapabilityAware { submit(r: SubmissionRequest): Promise; } // --- Email (dedicated port, separate from generic SubmissionPort) ----------- export interface EmailSendRequest { to: string; subject: string; body: string; replyTo?: string; /** Attachments as base64-encoded content (referenced by storage key). */ attachments?: { filename: string; storageKey: string; contentType?: string }[]; } export interface EmailSendResult { proofState: ProofState; providerMessageId: string | null; proofRef: Record; } export interface EmailPort extends CapabilityAware { send(req: EmailSendRequest): Promise; } // --- Redaction --------------------------------------------------------------- export type RedactionMode = "mask" | "remove" | "tag"; export interface RedactionSpan { start: number; end: number; piiType: string; replacement: string; } export interface RedactionPort { detect(text: string): Promise | RedactionSpan[]; redact(text: string, mode: RedactionMode): Promise | string; } // --- Workflow / audit -------------------------------------------------------- export interface WorkflowEvent { name: string; data: Record; } export interface WorkflowPort { send(event: WorkflowEvent): Promise; sleepUntil(date: Date): Promise; } export interface AuditEvent { actorType: string; actorId: string; action: string; resourceType: string; resourceId: string; before?: Record; after?: Record; } export interface AuditPort { append(e: AuditEvent): Promise; } // --- Storage ----------------------------------------------------------------- export interface StoredObject { storageKey: string; sha256: string; sizeBytes: number; mimeType: string | null; } export interface StoragePort { put(input: { key: string; bytes: Uint8Array; mimeType?: string }): Promise; getBytes(key: string): Promise; /** Returns a URL the web app can fetch. In dev this may be a local served path. */ publicUrl(key: string): string; }