Skip to content

Latest commit

 

History

History
124 lines (94 loc) · 4.24 KB

File metadata and controls

124 lines (94 loc) · 4.24 KB

DocSort CLI — Technical Architecture & Component Guide

This document outlines the software architecture, modular service design, and component responsibilities for the DocSort CLI application.


1. System Component Design

DocSort CLI follows a Modular Single-Responsibility Service Architecture:

DocSortCLI/
├── src/
│   ├── commands/               # CLI Command definitions
│   │   └── scan.command.ts     # Orchestrates directory scanning
│   │
│   ├── services/               # Core isolated business services
│   │   ├── pdf.service.ts      # Text & metadata extraction (pdfjs-dist)
│   │   ├── image.service.ts    # Page 1 PNG rendering fallback (pdf-to-img)
│   │   ├── ai.service.ts       # Text & Vision analysis via Ollama (qwen2.5vl:3b)
│   │   └── file.service.ts     # Move, rename, and soft-delete file operations
│   │
│   ├── ui/                     # Terminal UI presentation components
│   │   ├── card.ui.ts          # Formatted ASCII cards (cli-table3 & chalk)
│   │   ├── menu.ui.ts          # Interactive decision prompts (inquirer)
│   │   └── report.ui.ts        # End-of-session summary displays
│   │
│   ├── types/                  # Shared TypeScript interfaces & types
│   │   └── docsort.types.ts
│   │
│   ├── config/                 # Application constants & default paths
│   │   └── constants.ts
│   │
│   └── index.ts                # Application entry point & CLI initialization

2. Component Responsibilities

Service Layer (src/services/)

pdf.service.ts

  • Reads PDF files using pdfjs-dist/legacy/build/pdf.mjs.
  • Extracts page count, document metadata (Author, CreationDate, Title), and raw text content.
  • Filters scanner boilerplate watermarks (SCANNER_BOILERPLATE_REGEX) and evaluates non-watermark text length ($\ge 100$ characters) to determine whether text-based AI analysis is viable.

image.service.ts

  • Handles scanned or non-searchable PDFs.
  • Utilizes pdf-to-img with scale: 1.25 (1.25x resolution optimized for 4 GB VRAM GPUs) to render Page 1 into a PNG image Buffer.
  • Converts the buffer into a Base64 string for multimodal Vision AI input.

ai.service.ts

  • Interacts with the local Ollama server using the ollama SDK.
  • Sends text snippets (~300 words / 1,500 chars) or Base64 PNG images to qwen2.5vl:3b with num_ctx: 4096.
  • Configures format: "json" to enforce structured JSON output conforming to DocAnalysisResult.
  • Safely handles malformed JSON outputs (AI_INVALID_JSON) and token context overflows (AI_CONTEXT_EXCEEDED).

file.service.ts

  • Manages file system operations using Node.js fs/promises.
  • Handles file relocation, renaming, and soft-deletion staging into ./.docsort-trash/.

UI & Presentation Layer (src/ui/)

card.ui.ts

  • Renders a structured, colorized terminal summary card for each document using chalk and cli-table3.

menu.ui.ts

  • Displays interactive prompt options using inquirer:
    • [K] Keep — Maintain current file location.
    • [M] Move — Relocate file to category folder.
    • [R] Rename — Apply standardized suggested file name.
    • [D] Delete — Move file to .docsort-trash/.
    • [S] Skip — Defer decision and proceed to next file.

report.ui.ts

  • Displays session completion statistics (total files processed, kept, moved, renamed, trashed, and skipped).

3. Data Interfaces (src/types/docsort.types.ts)

export interface ExtractedPdfData {
    numPages: number;
    metadata: Record<string, unknown>;
    text: string;
    hasEnoughText: boolean;
}

export interface RenderedPageResult {
    pageNumber: number;
    imageBuffer: Buffer;
    base64Image: string;
    mimeType: "image/png";
}

export interface DocAnalysisResult {
    title: string;
    category: string;
    summary: string;
    tags: string[];
    sensitive: boolean;
    confidence: number;
    suggestedFileName: string;
}

export interface ProcessedDocument {
    filePath: string;
    fileName: string;
    numPages: number;
    extractionMode: "text" | "image_fallback";
    aiResult: DocAnalysisResult;
}