diff --git a/PROJECT_CONTEXT.md b/PROJECT_CONTEXT.md index 785692e..403f988 100644 --- a/PROJECT_CONTEXT.md +++ b/PROJECT_CONTEXT.md @@ -4,437 +4,221 @@ MifKit — MapInfo data toolkit (desktop GUI + CLI). Renamed from MifMapXL in 1.1.0. -The notes below describe the original `mif-to-xlsx` feature, which remains the first converter. Newer converters (KML/KMZ ↔ MapInfo, GeoJSON, Shapefile, etc.) are added as additional entries in `src/core/converters/` under the same Converter contract — see `src/core/converters/types.js` and `registry.js`. - ## Purpose -This is a desktop app for converting MapInfo `.mif` + `.mid` pairs into: - -- `.xlsx` files with all original attribute fields -- optional `.csv` export -- an extra column `region_color_hex` -- optional row background fill in Excel using the region fill color -- optional skip for black fill (`#000000`) - -The app is intended for non-technical Windows users who should be able to run a normal GUI app instead of using Node.js scripts in a terminal. - ---- - -## Product goal - -The user wants a simple Windows executable with UI where they can: +A growing collection of converters for MapInfo `.mif/.mid` and adjacent geo formats (KML/KMZ, GeoJSON, Shapefile, Excel). Packaged as a desktop GUI (Electron) and — once the CLI ships — a terminal binary built on the same engine. -- choose a folder or specific files for processing -- recursively scan subfolders if needed -- generate Excel files from MapInfo data -- add a color column extracted from polygon style -- optionally fill Excel rows with that color -- skip black fill if configured -- optionally merge all outputs into one workbook -- optionally also export CSV +The target user is non-technical (Windows + MapInfo Pro), so the GUI is the primary front-end. The CLI is for power users, automation, and CI pipelines. -The user is pragmatic and wants a working tool, not a theoretical one. +The product mood is **ffmpeg for MapInfo data**: one engine, every conversion direction surfaces in both the GUI and CLI through the same contract, behavior is deterministic, output is correct enough to import into MapInfo Pro without manual fixing. ---- +## Architecture -## Current stack +### Three layers -- Electron -- Node.js -- exceljs -- electron-builder +1. **Core engine** — `src/core/`. Pure Node.js, no Electron dependency, testable in isolation. Each converter is one folder under `src/core/converters/` exporting a Converter object. +2. **Desktop shell** — `src/main/` (Electron main process, IPC, worker orchestration) + `src/renderer/` (HTML/JS UI). The renderer is thin and schema-driven — it does not know any converter-specific details, it just renders forms from each converter's declarative `options[]` schema and dispatches the user's selection back through IPC. +3. **CLI (planned)** — `bin/mifkit` will be a thin wrapper over the same registry. The same option schema validates CLI flags. GUI and CLI are interchangeable entry points to the same core. ---- - -## High-level architecture +``` +src/ + main/ Electron shell + main.js · preload.js · worker.js + renderer/ Desktop UI + index.html · renderer.js · styles.css · i18n.js + core/ + common/ Shared utilities + color.js KML AABBGGRR <-> MapInfo int <-> #RRGGBB + zip.js Minimal ZIP reader (zlib only) + converters/ + registry.js register / get / list / validateOptions + types.js JSDoc Converter contract + index.js Auto-registers all built-in converters + mif-to-xlsx/ MapInfo MIF/MID -> Excel/CSV + kml-to-mif/ KML/KMZ -> MapInfo MIF/MID + convert.js Legacy orchestration for mif-to-xlsx + (still used inside that converter; will + fold into the converter folder later) + mif.js · mid.js MapInfo MIF/MID parsers + excel.js · csv.js Output writers + files.js Folder scan, MIF/MID pairing + encoding.js Charset detection via iconv-lite + settings.js Settings persistence with v1 -> v2 migration +test/ + core/ · integration/ · fixtures/ node:test suite, runs on every PR +``` -The project has 2 main parts: +### The Converter contract + +Every converter exports a plain object of this shape (full JSDoc lives in `src/core/converters/types.js`): + +```js +{ + id: 'kml-to-mif', // stable kebab-case + name: 'KML/KMZ → MapInfo MIF/MID', + description: '...', + inputs: { extensions: ['.kml', '.kmz'], type: 'file-or-folder' }, + outputs: { extensions: ['.mif', '.mid'], type: 'folder' }, + options: [ + { key: 'flat', type: 'boolean', default: false, label: '...', description: '...' }, + { key: 'charset', type: 'enum', values: ['WindowsCyrillic', 'Neutral'], default: 'WindowsCyrillic', label: '...' }, + // ... + ], + async run({ inputs, output, options }, ctx) { + // ctx.log(message) + // ctx.progress({ total, done, currentFile }) + // returns { outputs: string[], stats: { processed, skipped, errors: [{file, error}] } } + }, +} +``` -### 1. Desktop UI -Electron app with: -- main process -- preload bridge -- renderer UI +The registry validates this shape on `register()`. `validateOptions()` checks each option against its declared type/enum/range before the converter runs. -Responsibilities: -- choose input folder or files -- choose output folder -- edit settings -- start conversion -- show logs and results +### How the GUI talks to the engine -### 2. Conversion engine -Pure Node.js logic that: -- scans files -- matches `.mif` with corresponding `.mid` -- parses MIF metadata and geometry style -- parses MID records -- builds CSV/XLSX output -- applies Excel row fill -- skips black when requested +``` +renderer (renderer.js) + ├─ window.api.listConverters() → IPC converters:list → registry.list() + ├─ renders