Product EngineeringFeaturesFile Type Report Upload

Overview

High-level picture of how PDF lab reports are handled when labs choose to upload a finished document rather than manually inputting values into the system

πŸ‘€ Rucha Mahesh KulkarniπŸ“… Updated: Apr 16, 2026πŸ“ File Type Report Upload

Overview

Overview

This guide is written for engineers to read and learn about the File Type Report Revamp: why it exists, how it differs from the legacy server-mediated upload path, what the observed livehealth-frontend + livehealthapp (PY-2) happy path does today, and where PY-3 + Lambda-facing surfaces extend the architecture without necessarily being the only production path visible in a given repo snapshot.

Use the sibling pages for depth:

  • Workflow Guide - step-by-step lifecycle, setup, verification, failure modes
  • Frontend - React entry points, helpers, presigned orchestration
  • Backend - PY-2 finalization, Storage Manager, PY-3 helpers, persistence and indexing
  • Design Decisions - tradeoffs, dual paths, caveats

Prerequisites

RequirementWhy it matters
User with allow_report_file_conversion (or API-allowed doctor access)Without it, convert-to-file is blocked in operations.
Report not radiologyConversion / upload paths reject radiology in PY-2 guards.
S3 + Storage Manager mapping for FileTypeReportPresigned generation needs account, bucket, region, and extension allowlist.
PY-2 routes reachable from the browsersm_generate_presigned_url/, sm_reconcile_presigned_url/, uploadFileTypeReport/, convertReportToFileOrNormal/.
Pusher + patient-report Elasticsearch healthyCompletion is persisted even if UI looks stale when realtime/indexing fails.
Optional Lambda pathS3 events, deployed Lambda, X-Lambda-Token / CRON_SIGNING_KEY, and PY-3 file-type endpoints, only if that deployment shape is used.

What Is It For

  • Product: Let a lab attach a finished report file (PDF or supported image) as the analytical result instead of typing every parameter.
  • Operations: Reduce friction for high-volume reporting where the authoritative artifact already exists outside the LIS parameter grid.
  • Engineering: Remove the application server from the binary upload path on the default flow so large multi-page PDFs are practical, while keeping domain finalization (report row, audit, search, realtime) on trusted backend code.

Key Features

TopicSummary
What is a file type report?A report where the system stores a file path (typically PDF or image) instead of manually entered parameter values.
Why was the revamp needed?The old architecture pushed the entire file payload through the backend, creating payload-size and performance bottlenecks for larger lab reports.
What changed?The new architecture uses Storage Manager presigned upload URLs so the browser uploads directly to object storage instead of sending the raw file through the application backend on the main path.
Biggest practical gainFile transfer is offloaded from the app server, reducing request pressure and earlier size restrictions tied to backend payload transport.
Core business effectLabs can attach a finished report document instead of keying every value manually.
Important nuance from codeThe current livehealth-frontend happy path definitely uses presigned upload plus PY-2 finalization. The repository also contains PY-3 Lambda-facing endpoints for a more decoupled path; Lambda source is not in the inspected repo snapshot.
Another important nuanceThe β€œApply header and footer” flow still uses the legacy server-mediated upload path and does not use the presigned upload flow.

Glossary

TermMeaning in this systemTypical place seen in code
File Type ReportA report whose result is a file attachment path rather than traditional report parameter values.fileInputReport, ReportValue.value
fileInputReportFlag on labReportRelation / LabReportRelation indicating file-based report behavior.PY-2 labs/API.py, PY-3 report/models/lab_report_relation.py
Report ValueDB row storing the effective value for a report parameter; for file reports, value is the file path.PY-2 save_file_type_report_to_report_value, PY-3 update_lab_report_and_report_value_with_path
Storage ManagerShared file-storage abstraction: paths, presigned URLs, metadata logs, cleanup, download/reconcile.PY-2 labs/storage_manager.py, PY-3 core/utils/storage_manager/*
Presigned URLShort-lived direct-upload contract from backend so the client uploads straight to S3.sm_generate_presigned_url, storage-manager generate-presigned-url
ReconcilePost-upload step verifying the object exists and updating Storage Manager logs with final size / status.sm_reconcile_presigned_url, presigned reconcile
Temporary pathCaller-specified path before canonical Storage Manager placement.FileTypeReports/... prefix patterns
Concrete pathCanonical Storage Manager path matching standard SM conventions.IN/<lab>/<patient>/FileTypeReport/<cloudDocId>_<filename>.pdf style paths
Pusher updateReal-time report / waiting-list refresh after upload or finalization.commonPusherFunctionForLabReportRelation
ESElasticsearch - patient/report search indexing and Storage Manager log records.LabReportRelationES, StorageManagerLog

What problem the revamp solves

Old behavior

Under the older mechanism, file type reports were uploaded via the backend store path:

  • the browser read the file
  • the raw payload moved through the application request
  • the backend validated and stored the file
  • only then was the report updated

Predictable pain points:

  • large request bodies
  • backend CPU and memory pressure
  • poor scaling for high-resolution and multi-page PDFs
  • stricter effective file-size limits because the application server sat in the middle of the upload stream

New behavior

The revamp shifts bulk transfer out of the application tier:

  • the frontend asks for a presigned upload contract
  • the backend generates an S3 target and logs the request
  • the frontend uploads directly to S3
  • the system then reconciles metadata and finalizes the report record

Architecture-level impact

AreaOld modelNew model
Raw file transportBrowser β†’ Backend β†’ StorageBrowser β†’ Storage
App-server involvement during uploadHighLow
Payload bottleneck on app serverYesLargely removed
File-size toleranceConstrained by backend transportMuch better when S3 receives the binary directly
Post-upload bookkeepingBackend onlySplit across frontend metadata calls, Storage Manager logs, report finalization
ExtensibilityTight couplingBetter decoupling when Lambda / PY-3 helpers are used

Reality check from the codebase

The architecture described in product/technical context and the architecture visible in source code are closely related, but not one single linear path in every deployment.

What is definitely live in the current frontend code

The current livehealth-frontend upload flow does this:

  1. Validate the selected file.
  2. Request a presigned upload from PY-2 sm_generate_presigned_url/.
  3. Upload the binary to S3 directly.
  4. Reconcile via sm_reconcile_presigned_url/.
  5. Call PY-2 uploadFileTypeReport/ with metadata only, especially initialFilePath.
  6. Let PY-2 update the report value, send Pusher updates, and re-index the report in ES.

What also exists in the repository

Broader Lambda / PY-3 support surfaces:

  • PY-3 Storage Manager APIs
  • Lambda auth via X-Lambda-Token
  • PY-3 endpoint to convert a temporary file path into a concrete Storage Manager path
  • PY-3 endpoint to update the report value with the final file path
  • the presigned-upload revamp is implemented in the FE + PY-2 path
  • the PY-3 / Lambda support surfaces are present in crelio-app
  • the exact production Lambda implementation is external to this repo snapshot or lives in another repo / deployment artifact

Cross-repo map (repositories and ownership)

Repo / appLayerWhy it matters for this revamp
livehealth-frontendBrowser UI and orchestrationStarts upload, requests presigned URL, uploads to S3, reconciles, triggers report finalization
livehealthappPY-2 operational backendOwns the currently observed finalization endpoint, report conversion, Pusher trigger, patient-report ES re-index
crelio-appPY-3 services and newer Storage Manager stackModern Storage Manager endpoints, canonical path utilities, Lambda auth, file-type-report Lambda-facing helpers

Suggested mental model (Level 0)

  1. Product meaning - the report result is a file, not typed values.
  2. State meaning - fileInputReport = 1; ReportValue.value stores a path.
  3. Upload meaning - Storage Manager gives the browser a direct lane into S3.
  4. Domain finalization meaning - backend still decides when the report becomes complete and searchable.
  5. Infra-assisted evolution - PY-3 and Lambda support preprocessing and path normalization more decoupled than the older PY-2-only synchronous path.

The technical essence: storage-transport decoupling with report-state side effects still owned by the domain layer. See Design Decisions for explicit tradeoffs and caveats.

On this page