{"_id":"@amirandap/data-review-ui","name":"@amirandap/data-review-ui","dist-tags":{"latest":"0.4.0"},"versions":{"0.4.0":{"name":"@amirandap/data-review-ui","version":"0.4.0","description":"Reusable 3-panel data digitization/validation UI — file/related-item list + document viewer (image/PDF/text) + schema-driven form, for human-in-the-loop data entry.","license":"MIT","author":{"name":"Alejandro Miranda","url":"https://github.com/amirandap"},"repository":{"type":"git","url":"git+https://github.com/amirandap/shared-pipeline.git","directory":"packages/ui"},"homepage":"https://github.com/amirandap/shared-pipeline#readme","bugs":{"url":"https://github.com/amirandap/shared-pipeline/issues"},"keywords":["react","mui","data-review","ocr","human-in-the-loop","data-validation","document-viewer"],"type":"module","main":"./dist/data-review-ui.cjs","module":"./dist/data-review-ui.js","types":"./dist/src/index.d.ts","exports":{".":{"types":"./dist/src/index.d.ts","import":"./dist/data-review-ui.js","require":"./dist/data-review-ui.cjs"},"./style.css":"./dist/data-review-ui.css"},"scripts":{"dev":"vite","build":"tsc -b && vite build","prepare":"npm run build","lint":"oxlint","preview":"vite preview","test":"vitest run"},"peerDependencies":{"@emotion/react":"^11.0.0","@emotion/styled":"^11.0.0","@mui/icons-material":"^7.0.0","@mui/material":"^7.0.0","react":"^19.0.0","react-dom":"^19.0.0"},"dependencies":{"@amirandap/data-review-core":"^0.1.0","@rjsf/core":"^6.1.1","@rjsf/mui":"^6.1.1","@rjsf/utils":"^6.1.1","@rjsf/validator-ajv8":"^6.1.1","react-pdf":"^10.1.0","react-resizable-panels":"^4.0.4","react-zoom-pan-pinch":"^4.0.3"},"devDependencies":{"@emotion/react":"^11.14.0","@emotion/styled":"^11.14.0","@mui/icons-material":"^7.1.1","@mui/material":"^7.1.1","@types/node":"^24.13.2","@types/react":"^19.2.17","@types/react-dom":"^19.2.3","@vitejs/plugin-react":"^6.0.3","oxlint":"^1.79.0","react":"^19.2.7","react-dom":"^19.2.7","typescript":"~6.0.2","vite":"^8.1.1","vite-plugin-dts":"^4.5.0","vitest":"^4.1.10"},"gitHead":"6415b77ab858a3cfb583f872b8ece4a6bf37734f","_id":"@amirandap/data-review-ui@0.4.0","_nodeVersion":"24.16.0","_npmVersion":"11.13.0","dist":{"integrity":"sha512-DooV1Tg7Ltm+7pMwaMunDLebSPoyYTYckJ/G4iccPzEd8V1xsHvIHqbbLpkXrilPvHR6RXzR92BnqOA0197uKQ==","shasum":"ee6c2bf372f011c908fa251a9afbf3409a18484a","tarball":"https://registry.npmjs.org/@amirandap/data-review-ui/-/data-review-ui-0.4.0.tgz","fileCount":36,"unpackedSize":11895387,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQC/9qjTsrtS0xMQrZJ+jGULNFU5vadXaQ7Tatqf/0q4lwIgC1eZOdO2U4Yf2ZYqIRQgQLeIwVS1CEWMisJhIMdcP0g="}]},"_npmUser":{"name":"amirandap","email":"amp@softgrouprd.com"},"directories":{},"maintainers":[{"name":"amirandap","email":"amp@softgrouprd.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/data-review-ui_0.4.0_1787240951293_0.9099003127359271"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-20T15:49:11.025Z","0.4.0":"2026-08-20T15:49:11.676Z","modified":"2026-08-20T15:49:11.901Z"},"maintainers":[{"name":"amirandap","email":"amp@softgrouprd.com"}],"description":"Reusable 3-panel data digitization/validation UI — file/related-item list + document viewer (image/PDF/text) + schema-driven form, for human-in-the-loop data entry.","homepage":"https://github.com/amirandap/shared-pipeline#readme","keywords":["react","mui","data-review","ocr","human-in-the-loop","data-validation","document-viewer"],"repository":{"type":"git","url":"git+https://github.com/amirandap/shared-pipeline.git","directory":"packages/ui"},"author":{"name":"Alejandro Miranda","url":"https://github.com/amirandap"},"bugs":{"url":"https://github.com/amirandap/shared-pipeline/issues"},"license":"MIT","readme":"# @amirandap/data-review-ui\n\nReusable 3-panel data digitization/validation UI — a related-items list, a\ndocument viewer (image / PDF / plain text), and a schema-driven field form,\nlaid out in resizable panels. Built for human-in-the-loop data entry\n(reviewing OCR'd invoices, validating imported records, etc.).\n\n100% presentational: no network calls, no domain knowledge (no business\nrules, no field lists hardcoded to a particular use case). All of that lives\nin the consuming app, which wires its own data through props.\n\n> This package lives in the `packages/ui` workspace of a two-package\n> boilerplate repo — see the [repo-root README](../../README.md) for the\n> backend counterpart (`packages/llm-file-pipeline`).\n\n## Install\n\nPublished on npm:\n\n```bash\nnpm install @amirandap/data-review-ui\n```\n\nFor local development against a checkout, `npm link` it into the consuming\napp instead.\n\n## Usage\n\nImport the stylesheet once (it carries `react-pdf`'s text/annotation layer\nCSS — skip it and PDF text selection/rendering will look broken):\n\n```tsx\nimport '@amirandap/data-review-ui/style.css';\n```\n\n```tsx\nimport { DataReviewPanel } from '@amirandap/data-review-ui';\n\n<DataReviewPanel\n  title=\"Factura OCR — NIC 12345\"\n  chips={[{ label: 'EDESUR' }, { label: '05/2026' }]}\n  actions={[\n    { label: 'Validar', variant: 'contained', onClick: handleValidate },\n    { label: 'Invalidar', color: 'error', onClick: handleInvalidate },\n  ]}\n  relatedItemsTitle=\"Registros NIC 12345\"\n  relatedItems={siblingRecords.map(toRelatedItem)}\n  document={{\n    kind: 'image',\n    url: imageUrl,\n    overlayTokens: detectedWords, // pre-matched by the caller (green=matched, yellow=unmatched)\n  }}\n  onPickText={(text) => {/* optional extra side effect; the focused field is auto-filled */}}\n  sections={[\n    {\n      title: 'IDENTIFICACIÓN',\n      fields: [\n        { key: 'nic', label: 'NIC', type: 'text', gridWidth: 6, required: true },\n        { key: 'numero_medidor', label: 'Medidor', type: 'text', gridWidth: 6 },\n      ],\n    },\n    {\n      title: 'MONTOS (RD$)',\n      fields: [\n        { key: 'total_facturado', label: 'Total', type: 'currency', gridWidth: 6, format: fmtRD, parse: parseRD },\n      ],\n    },\n  ]}\n  values={editableFields}\n  onChange={(key, value) => setEditableFields((f) => ({ ...f, [key]: value }))}\n  validationMessages={qcWarnings} // key -> string[] business-rule warnings, computed by the caller\n  autoSaveId=\"ocr-review\" // persist panel widths across sessions (localStorage)\n/>\n```\n\n## PromptVersionManager\n\nFor versioning \"what prompt is used + what output is expected\" as a single\nunit — the same shape whether the storage is SQLite-with-activate or\nClickHouse-append-only. Also 100% presentational.\n\n```tsx\nimport { PromptVersionManager, sectionsToJsonSchema } from '@amirandap/data-review-ui';\n\n<PromptVersionManager\n  versions={promptVersions} // PromptVersion[] — each bundles prompt + inputDescription + outputSections\n  activeVersionId={activeId}\n  onActivate={(id) => activatePromptVersion(id)} // omit if your versioning is append-only (no activate step)\n  onSave={(draft) => savePromptVersion(draft)} // always a NEW version — nothing is edited in place\n  renderVersionMeta={(v) => <span>{v.meta?.usageCount} usos</span>} // optional slot for cost/usage stats you already track\n/>\n```\n\n`outputSections` uses `ExtractionSectionDef[]` — the same shape as\n`DataReviewPanel`'s `sections`, minus `format`/`parse` (functions aren't\nserializable to a DB row or a JSON textarea). The point: the same field\nlist that defines the review form can also generate the JSON Schema you\nsend to an LLM for extraction, via:\n\n```ts\nconst { name, strict, schema } = sectionsToJsonSchema(version.outputSections);\n// -> OpenAI Structured Outputs-compatible schema, ready to pass as response_format\n```\n\nOne source of truth for \"what fields does this extract\" instead of hand-\nmaintaining a form config and an LLM schema separately. On the backend side,\n`packages/llm-file-pipeline`'s `prompt_versions` store (see the repo-root\nREADME) persists exactly this bundle — the same `schema_json` this function\nproduces is what gets sent to OpenAI/Anthropic at extraction time.\n\n## What this package does NOT do\n\n- No fetch/save/validate network calls — wire your own via `actions`.\n- No business validation rules — compute `validationMessages` yourself and pass them in.\n- No OCR — if using the image viewer's overlay, detect/match text yourself and pass `overlayTokens`.\n- No currency/locale formatting defaults — pass `format`/`parse` per field.\n\n## Local development\n\nFrom the repo root:\n\n```bash\nnpm install\nnpm run dev --workspace=packages/ui   # opens the dev/ playground app with mock data\nnpm run build --workspace=packages/ui # builds the library to packages/ui/dist/\n```\n\nOr from within this folder (`packages/ui`) directly: `npm run dev` / `npm run build`.\n","readmeFilename":"README.md","_rev":"1-9a7a142a63f8b77ff8205150f14fec64"}