Spring Boot backend + static HTML/JS frontend that turns a lab report PDF into a plain-language explanation via Google Gemini.
- Rotate the Gemini API key. The original key was committed to source control in a prior version of this project. Revoke it at https://aistudio.google.com/apikey and generate a new one, even though the code no longer contains it.
- Copy
.env.exampleto.envand fill in real values (DB password, new Gemini key, your frontend's real URL forCORS_ALLOWED_ORIGIN). - Never commit
.env— it's already in.gitignore.
- Authorization was missing entirely — any request could read or delete
any user's medical reports just by knowing/guessing an ID. Login now
issues an opaque session token (
Authorization: Bearer <token>header), and every report/medication/trend endpoint verifies the token's owner actually owns the resource being requested before returning anything. This is an in-memory token store — fine for a single backend instance, but if you ever scale to multiple instances or need persistent sessions across restarts, swapSessionServicefor Spring Security + JWT or a Redis-backed store. - All secrets (DB password, Gemini key) now come from environment
variables instead of being hardcoded in
application.properties. - CORS is now a single configurable origin (
CORS_ALLOWED_ORIGIN) instead of*on every controller. - Upload size capped at 15MB.
- Real user-uploaded PDFs that were sitting in
uploads/have been stripped from this deployable copy. - Password hashes are no longer echoed back in the register/login API responses.
cp .env.example .env
# edit .env with real values
docker compose up --buildBackend comes up on http://localhost:8080. Then just open
frontend/index.html in a browser, or serve it with any static file
server. If your frontend isn't on http://localhost:8080, set
window.MEDEXPLAIN_API_BASE before app.js loads, e.g. in index.html:
<script>window.MEDEXPLAIN_API_BASE = "http://localhost:8080";</script>
<script src="app.js"></script>Requires Java 21, Maven, and a local MySQL instance.
export DB_URL=jdbc:mysql://localhost:3306/med_explain_db
export DB_USERNAME=root
export DB_PASSWORD=yourpassword
export GEMINI_API_KEY=your-new-key
export CORS_ALLOWED_ORIGIN=http://127.0.0.1:5500
./mvnw spring-boot:runA reasonable free/cheap path for a first deploy:
- Backend + DB: Railway or Render — both support Docker Compose-style
deployments and managed MySQL. Set the same env vars from
.envin their dashboard (never in the repo). - Frontend: since it's static HTML/JS, Vercel, Netlify, or GitHub
Pages all work — just make sure
window.MEDEXPLAIN_API_BASEpoints at your deployed backend's URL, and that URL is exactly what you set asCORS_ALLOWED_ORIGINon the backend. - File storage: the
uploads/volume is fine to start, but note that most free-tier hosts wipe local disk on redeploy. If reports need to survive redeploys, move to S3-compatible storage (e.g. Cloudflare R2) down the line — not needed for a first launch.
- Sessions are in-memory and single-instance only (see above).
- No rate limiting on
/api/users/loginor/api/reports/upload— someone could hammer either endpoint. Fine for a small personal-project launch, worth adding (e.g. Bucket4j) before real traffic. - No email verification on registration.
- Gemini API costs money per report analyzed once you're past any free tier — there's no per-user quota, so a malicious user could run up your bill by uploading reports in a loop. Worth adding a simple daily upload cap per user if this goes properly public.