Skip to main content

Technology

Clinisync is intentionally boring on the dependency side — every runtime piece is a well-understood Node module and the codebase is plain CommonJS.

Runtime stack

ConcernLibrary
HTTP serverExpress 4
Multipart uploadmulter (disk storage, 5 MB cap, allowlisted extensions)
Spreadsheet parsingSheetJS / xlsxreadFile for input, sheet_to_csv for output
Date mathmoment (only as a transitive helper; the DOB-to-age math is hand-rolled in src/etl/transform.js)
Env loadingdotenv

Optional adapters

These are loaded lazily and only activate when the corresponding environment variable is set, so vanilla npm install does not pull them:

FeatureActivated byAdapter
Multi-process rate-limit storeREDIS_URLioredis (peer-installed)
Virus scanningCLAMAV_TCP_HOSTclamscan (peer-installed), backed by a clamd daemon over TCP

Dev / CI tooling

ConcernLibrary
TestsJest 29 with supertest for the HTTP route
DOM testsjsdom (for public/js/upload.js)
LintESLint 9 flat config
Hookshusky — pre-commit runs npm test
CIGitHub Actions — ci.yml runs lint + tests on every push/PR
DocsDocusaurus 3.10 — built and deployed by docs.yml whenever docs/** changes on main

Layout

src/
app.js # Express wiring; multer + middlewares + upload route
routes/fileUpload.js # /upload handler: ETL pipeline + manifest
etl/
extract.js # xlsx → array-of-rows per sheet
transform.js # header normalization, NHI→ID, DOB→Age, dedup, stats
load.js # async CSV + manifest writers
idMapper.js # createIdMapper() factory + singleton API
retention.js # csvs/ TTL sweeper
middleware/
apiKey.js # CLINISYNC_API_KEY gate
rateLimit.js # in-memory store by default
redisRateLimitStore.js # opt-in distributed store
virusScan.js # noop by default
clamavScanner.js # opt-in clamd adapter
utils/
cleanWorkSheetData.js # public wrapper around transformSheet
generateFixtures.js # produces __tests__/fixtures/*
public/ # tiny vanilla-JS frontend
__tests__/ # 30 unit + integration tests
docs/ # this site