first commit
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
# CTM Document Builder
|
||||
|
||||
Electron + React desktop app for CTM document workflows: instruction PDFs and vaccination records, backed by a **cloud PocketBase** instance for instruction storage.
|
||||
|
||||
## Setup
|
||||
|
||||
### 1. Install dependencies
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
### 2. Configure PocketBase (internal build)
|
||||
|
||||
Edit `electron/main/pocketbase-config.js` with your instance URL and superuser credentials. Values are bundled into the desktop app — no `.env` file is required.
|
||||
|
||||
### 3. Cloud PocketBase collection
|
||||
|
||||
Your PocketBase instance should have an `instructions` collection with:
|
||||
|
||||
- `vaccine` — Text
|
||||
- `instruction` — Text
|
||||
|
||||
The app authenticates as a `_superusers` account (PocketBase v0.23+).
|
||||
|
||||
### 4. Run the app
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Restart Electron after changes to `electron/main/` (e.g. PDF import).
|
||||
|
||||
## Features
|
||||
|
||||
Three tabs:
|
||||
|
||||
- **Instructions** — Compose instruction documents from library entries; reorder and edit on the canvas; export a portrait PDF with logo and header.
|
||||
- **Instruction Manager** — Create, edit, and delete instruction entries in PocketBase.
|
||||
- **Vaccination Record** — Patient header, up to 15 vaccination rows, and notes; export a landscape PDF; **Import from PDF** to reload a previously exported record.
|
||||
|
||||
## PDF export
|
||||
|
||||
PDFs are generated with Chromium `printToPDF` in a hidden Electron `BrowserWindow`. The app logo is loaded from `assets/logo.png` (bundled as `extraResources` in packaged builds).
|
||||
|
||||
## Vaccination record import (metadata-only)
|
||||
|
||||
Import reads **embedded machine-readable metadata** from PDFs exported by this app. There is no visual/layout fallback.
|
||||
|
||||
- Only PDFs with valid `CTM_VR` metadata can be imported.
|
||||
- **Last update** is always set to **today** on import (not read from the PDF).
|
||||
- Import **replaces** the current builder data (with a confirm dialog if data already exists).
|
||||
- Third-party PDFs, scanned documents, or files with stripped or tampered metadata will show an error.
|
||||
|
||||
## Metadata format (developers)
|
||||
|
||||
Vaccination record PDFs embed a hidden text payload for round-trip import.
|
||||
|
||||
**Wire format:**
|
||||
|
||||
```
|
||||
CTM_VR:<version>:<base64url(JSON)>
|
||||
```
|
||||
|
||||
**Current version:** `1`
|
||||
|
||||
**v1 JSON fields:**
|
||||
|
||||
| Field | Type | Notes |
|
||||
|-------|------|--------|
|
||||
| `patientName` | string | |
|
||||
| `dateOfBirth` | string | ISO `YYYY-MM-DD` |
|
||||
| `notes` | string | |
|
||||
| `rows` | array | Max 15 rows |
|
||||
| `rows[].diseaseKey` | string | Key from `DISEASE_OPTIONS` |
|
||||
| `rows[].date` | string | ISO `YYYY-MM-DD` |
|
||||
| `rows[].productBrand` | string | |
|
||||
| `rows[].lotNumber` | string | |
|
||||
| `rows[].provider` | string | |
|
||||
|
||||
`lastUpdate` is intentionally omitted from metadata; the UI sets it on import.
|
||||
|
||||
**Implementation:** [`src/lib/vaccinationRecordMetadata.js`](src/lib/vaccinationRecordMetadata.js)
|
||||
|
||||
**Adding a new version:** register a parser in `VERSION_PARSERS`, bump `VR_METADATA_LATEST_VERSION` for export, and keep older parsers so previously exported PDFs still import.
|
||||
|
||||
## Scripts
|
||||
|
||||
- `npm run dev` — Start Vite dev server + Electron
|
||||
- `npm run build` — Build and package with electron-builder
|
||||
- `npm run preview` — Vite preview (renderer only; no PDF export)
|
||||
|
||||
## Packaging
|
||||
|
||||
`assets/` (logo and icon) are included as `extraResources` for packaged builds. No local PocketBase binary is bundled.
|
||||
Reference in New Issue
Block a user