Lab-result history, API and web
SmartHealth
An API and a web application that turn the lab's PDF into a per-metric history, with the reference range picked by the owner's sex and age, a body-composition target and a shareable slice behind a link and a password.
- Role
- API and frontend review, academic project built by a pair
- Period
- March to November 2023
- Status
- Open source, completed in 2023

What the system does
- Reading the lab's PDF and extracting the value of every metric in the catalog.
- A per-marker history, with the reference range picked by the owner's sex and age.
- A body-composition target, with skinfold anthropometry and server-side calculation of density, body fat, lean mass and basal metabolic rate.
- Sharing a slice with the doctor, by link with a password or by QR code, with no signup for the recipient.
- A clinical catalog of twenty-five metrics and fifty-four reference ranges, loaded by migration.
Architecture
- A NestJS API with Swagger-documented REST, a global ValidationPipe and eleven domain modules, plus two submodules nested through RouterModule.
- Dependency by contract: each module declares an operations interface and registers the implementation behind an injection token, so the controller depends on the token and not on the class.
- Domain modules do not return entities: each has an assembler that builds the DTO, and that is where the user's password disappears.
- TypeORM over PostgreSQL, with one migration that loads the clinical catalog: twenty-five metrics with their units and fifty-four reference ranges keyed by sex and age interval.
- JWT authentication in global middleware with an exclusion list, plus a second middleware that matches the token's subject against the id in the URL before letting the request through.
- PDF reading with pdfjs-dist: each page's text layer becomes a normalized string, and every catalog metric is searched by a regular expression.
- Result classification happens on write, not on read: the item is compared with the owner's range and the verdict is stored together with the range that was used.
- Sharing by point-in-time copy across three dedicated tables, opened by a random identifier and a bcrypt-hashed password, on two public routes.
- A Next.js web app on the pages router, with no API routes of its own, consuming the API through axios, with each marker's series in Chart.js.
- A two-person flow with mandatory pull-request approval on both production branches, force pushes blocked and the branch-origin policy enforced by a workflow.
Implementation details
- GraphQL with Apollo existed from March to September 2023, alongside REST. The module and its four resolvers were removed once no consumer was using them.
- PDF extraction tolerates whitespace between the letters of the word RESULTADO, because the lab's text layer does not always come contiguous.
- The recipient lands on a page that first checks whether the link exists and only then asks for the password. An invalid link never reveals whether a share existed.
Technologies
- NestJS
- The API framework, with modules, middleware and token-based injection.
- TypeScript
- The API's language.
- TypeORM
- Entity mapping and the clinical catalog migration.
- PostgreSQL
- The database for exams, metrics, targets and shared copies.
- Swagger
- API documentation, served by the application itself.
- JWT
- Authentication in global middleware, with an exclusion list.
- bcrypt
- Hashing the user's password and the share password.
- pdf.js
- Reading the text layer of the exam PDF.
- Next.js e React
- The web application, on the pages router, consuming the API.
- Chart.js
- Each marker's history series.
- Jest
- API tests, covering the assemblers and the PDF extractor.
- Docker
- The local environment, with PostgreSQL next to the API.
- GitHub Actions
- A build on every pull request and the branch-origin policy.

The tracking screen, with each marker's evolution over time. 
Exam upload, the entry point of the module that reads the PDF and extracts the values. 
The sharing flow, where the patient picks which results the doctor gets to see. Diagram of the exam path: the PDF is read, the owner's reference range is applied on write, and the shared slice goes out through a link with a password.
Want to talk about architecture, technical decisions and shipping to production?
