Digital Consent Forms with Fingerprint Signing
A clinic consent workflow that captures a patient fingerprint, validates the signing flow with Hawiti (Kuwait Mobile ID), and stores a signed PDF.
Role: Full Stack
Overview
A Patient-module workflow for creating, assigning, completing, and retaining clinical consent forms. The dashboard captures a fingerprint from a ZKTeco reader through a local Node.js service, validates the signing flow through Hawiti (Kuwait Mobile ID), stores protected capture data through the Laravel API, stamps a non-row-ID reference into the consent HTML, and saves the resulting PDF as an appointment document.
Tech Stack
backend
frontend
data
integrations
devops
The Problem
Clinical consent forms needed to be associated with procedures, completed in the dashboard, and retained as signed documents.
- Connecting a USB fingerprint reader without exposing hardware access directly to the browser or Laravel API.
- Protecting biometric templates and fingerprint images while linking each capture to the signed consent document.
- Preventing expired, reused, or user-mismatched fingerprint captures from signing a form.
The Solution
- 1Use a local smartcard-service on the reader-connected Windows machine, proxied through Next.js API routes.
- 2Persist captures through permission-protected Laravel endpoints and bind a capture to the generated appointment document within a database transaction.
- 3Validate the signing flow with Hawiti (Kuwait Mobile ID), then render consent HTML to PDF after replacing the patient signature marker with a timestamped fingerprint reference.
Procedure consent administration
Links active medical consent forms to procedures and records whether each form is required.
Fingerprint-gated signing
Requires a captured fingerprint before a patient or procedure consent can be submitted for PDF generation.
Hawiti identity validation
After fingerprint signing, validates the consent signing flow through the Hawiti (Kuwait Mobile ID) integration before the document is finalized.
Local reader bridge
Uses a Node.js service on port 4000 to obtain a ZKTeco template and PNG image, with Next.js routes providing status and capture proxies.
Signed consent archive
Lists signed consent documents for a patient and opens the stored PDF.
Biometric-data protection
Encrypts fingerprint templates through Laravel's encrypted cast, encrypts image files on private storage, and hides templates from responses.
Architecture
Modular Laravel application with a Next.js dashboard and a local hardware bridge
- 1A user opens a procedure consent form and completes its HTML fields.
- 2The dashboard checks reader status, captures a fingerprint through the local service, and saves the capture through the Laravel API.
- 3The dashboard submits the form with the capture ID.
- 4The backend validates ownership, freshness, one-time use, and the signature marker; validates the signing flow with Hawiti (Kuwait Mobile ID); stamps the capture reference into the HTML; generates a PDF; stores a document record; and attaches the capture to that document.
- 1The dashboard requests patient documents with the consent-only filter.
- 2The backend returns consent document records.
- 3The dashboard displays signed forms and opens the PDF through the document viewer.
Components
Dashboard
Next.js, React, TypeScript, next-intlManages consent-form dialogs, reader status, capture interaction, validation, and signed-form viewing.
Hardware bridge
Node.js, Express, koffiRuns near the USB device, loads the ZKTeco SDK on Windows, and exposes fingerprint status and capture endpoints.
Backend
Laravel, PHP, mPDF, Hawiti (Kuwait Mobile ID)Provides authenticated consent and fingerprint APIs, validates the signing flow with Hawiti, enforces signing rules, generates PDFs, and links captures to documents.
Data and storage
MySQL, Laravel private local diskStores consent links, document records, encrypted fingerprint templates, metadata, and encrypted fingerprint-image files.
- The browser accesses the reader through Next.js API proxies rather than directly.
- The ZKTeco service must run on the Windows machine connected to the USB reader.
- Biometric templates are hidden from API responses; signed PDFs contain a generated capture reference rather than the template or row ID.
Scheduled Maintenance
- Laravel model pruning removes unused fingerprint captures older than one day and deletes their encrypted image files.
Key Decisions
Use a local Node.js reader service instead of connecting the reader to the API directly.
Why: The ZKTeco USB reader and Windows DLL must run on the machine connected to the device; the dashboard communicates through proxied HTTP endpoints.
Trade-off: The reader service must be deployed and running alongside the dashboard or on a configured reachable host.
Use a generated reference in the signed PDF instead of embedding biometric data.
Why: The PDF can identify the associated capture without exposing the template or database row ID.
Trade-off: The reference must be resolved through protected application data.
Make fingerprint captures single-use and short-lived for signing.
Why: The backend rejects captures belonging to another user, already attached to a document, or older than 15 minutes.
Trade-off: A patient must be rescanned when a capture expires or has been used.
Technical Challenges
Safely handle biometric data.
Solution: Encrypt templates through the model cast, encrypt image files on private storage, hide templates by default, and prune unused captures.
Outcome: Captured biometric material is not returned in normal API responses and unused captures are removed.
Prevent a capture from being reused across consent forms.
Solution: Lock the capture during signing, validate that it is unlinked and recent, then attach it to the resulting document in the transaction.
Outcome: A capture can be associated with one signed document.
Support development without reader hardware.
Solution: Provide an explicit mock fingerprint driver and automated tests using a fake SDK.
Outcome: Capture and UI behavior can be tested without a physical reader.
Outcomes
- Delivered consent-form assignment and completion flows for procedures.
- Delivered fingerprint-backed consent signing with Hawiti (Kuwait Mobile ID) validation, PDF generation, and document linkage.
- Delivered a signed-consent list for patient records.
- Delivered deployment guidance for the local reader service, including PM2 configuration and Windows SDK setup.
Engineering Practices
- JWT-protected fingerprint routes require dedicated create and view permissions.
- Reader-status and capture proxies use no-store requests, timeout handling, and clear unavailable-service responses.
- The ZKTeco adapter polls non-blocking SDK capture calls, prevents concurrent capture requests, and produces a PNG from raw grayscale image data.
- Backend feature tests cover encrypted storage, signing constraints, signature-marker replacement, and pruning; frontend and local-service tests cover reader states, bridge behavior, and SDK adapters.
- Consent-form links use update-or-create behavior to avoid duplicate procedure/form links.