A mobile app, admin panel and calculation services for physicians
A physician-focused platform combining reference-guided AI and TUS / DHY preference tools. I took end-to-end technical responsibility across the mobile app, admin panel, backend and background computation systems.
Reference-guided AIPrekura workersOperational adminTraceable data
01 / The product
What I built for BTM
BTM helps physicians consult forensic-medicine references and compare positions during TUS and DHY placement rounds. I built both experiences into the mobile app, with separate data models and access rules for each.
Alongside the mobile app, I built APIs, database models and admin tools for document reviews, official data imports and calculations. The mobile app and admin panel use the same backend, with different permissions for users and administrators.
BTM AI: reference-guided support.
I built the mobile chat and backend flow that bring case findings, conversation history and a reference document into a controlled LLM request. Access, conversation ownership and usage limits are checked on the server.
Gemini · Edge Functions · Mobile chat
Prekura: preferences in context.
I built position discovery, filters, map views, historical results and term-specific preference lists. TUS positions are modeled as hospital–specialty pairs, while DHY keeps its distinct lottery and preference rules.
TUS / DHY · History · Preference management
Admin: the tools behind the product.
I developed the Next.js panel for document review, position management, moderation and computation tracking, connecting operator decisions to permission-checked backend actions and the mobile experience.
Next.js · Server permissions · Operations
02 / BTM AI
AI chat grounded in a reference guide
I connected Gemini to the reference document and conversation history, with instructions to stay within the source, acknowledge missing information and ask for clarification when findings are ambiguous. The application controls document preparation, authorization and persistence.
I also developed an SSE response path and mobile chunk handling for incremental answers, including partial-response and interruption handling. Reference versions and provider-file validity are checked before reuse.
Reading and validating ÖSYM result documents
For ÖSYM result documents, text PDFs are parsed directly; scanned content can use Gemini for transcription. A deterministic parser then interprets and validates the score fields. This keeps the data rules inspectable even when the source needs OCR.
BTM AI provides information from a reference guide to support a physician’s assessment. I also built streaming responses, which can be enabled through the app’s release settings.
03 / Prekura computation
How I built the TUS and DHY calculations
I built separate engines for TUS score-based placement and DHY lottery scenarios. Heavy computation runs in background services using PostgreSQL job queues and Node.js worker threads.
I save the inputs for each run and use a fixed random seed so the same calculation can be repeated. Input and output hashes help identify the data used. TUS scores use an integer representation to avoid rounding differences. These checks make calculations reproducible; they do not establish how accurately a model predicts real placements.
01
Batch computation
Admin-created runs freeze the candidate, preference and position inputs. Node.js worker threads process TUS placements or DHY scenarios, prepare results in stages and publish the completed run.
02
Recalculating after preference changes
Preference and profile changes create new revisions. I added job ownership, heartbeats, retries and stale-job handling so an older calculation cannot replace the result of newer input. Final runs receive priority.
03
DHY scenario processing
A separate worker follows DHY’s lottery model. Rapid input changes are grouped before computation, with leases and heartbeats coordinating work and allowing final calculations to take precedence.
04
Controlled result delivery
Shadow, pilot and enabled modes separate computation from user publication. A notification outbox rechecks the active term, release mode and user permission before sending, with deduplication and invalid-token cleanup.
A separate environment for testing placement models
I built a separate system for testing different candidate distributions. Each run records its model version and results, and cannot start if the required model files are missing or invalid.
Research and testing
I designed the probability calculations to run independently of whether their results are shown to users. The national model using synthetic candidates remains separate for research and testing.
04 / The admin panel
An admin panel for day-to-day operations
I built the Next.js admin around the work that happens after a user submits a document, reports a message or changes a preference. Review queues, filters, decisions and calculation details turn those events into manageable operational workflows.
01
Verification queues
The panel lets reviewers filter pending documents, open them through temporary links and record their decisions. The server checks their permissions before granting access.
02
Moderation that reaches the backend
Administrators can review reported comments and messages and manage blocked users. Blocking rules are also enforced by the backend.
03
Positions and computation runs
The panel lets administrators manage positions for each term and inspect calculation inputs, progress and results. Long-running calculations continue in background services.
04
Traceable changes
For important changes, I record who made the change and the previous and updated values of selected fields. Administrators can use this history to investigate past decisions.
Server-side authorization
I enforced role and action permissions on the server, alongside user ownership and row-level data access controls. Document review receives temporary access only after authorization, keeping sensitive operational work behind explicit checks.
05 / Official data
Updating position data while preserving preferences
I developed import and validation tooling to move official position data through source capture, parsing, staging, review and publication. Existing position identifiers and history are preserved so new data does not break preference links.
Source hashes, import-run records and validation reports make the publication traceable. The workflow combines scripts with human review before approved data reaches production.
01
Capture source
Save the official source and the information needed to identify it.
02
Parse & stage
Prepare the records in a staging area for review.
03
Review & validate
Review record matches, totals and existing preference links.
04
Publish
Publish the approved data and keep a record of the import.
3,825position records
15,501total available places
I imported 3,825 position records covering 15,501 available places for the 130th DHY round.
06 / Architecture & delivery
Three applications. A shared backend.
Mobile appReact Native / Expo
Operations panelNext.js / Server permissions
Product websiteNext.js / Account links
Authorized data access + server operations↓
Supabase / PostgreSQLShared data, identity and service layer
Simplified system architecture. Sentry reports mobile errors; service timings and worker heartbeats help follow backend activity.
Handling duplicate and out-of-order subscription events
I implemented subscription entitlement handling for duplicate and out-of-order RevenueCat webhook events, protecting access and usage limits from delivery ordering issues. Push delivery uses deduplication records and device-token cleanup.
App releases and maintenance
I worked across EAS builds, OTA configuration, release maintenance and Sentry integration. Parser, placement-engine and subscription-event tests support the underlying rules, while worker status and heartbeat records expose long-running activity.
Node.js worker threads, PostgreSQL job queues, TUS placement, DHY Monte Carlo
AI & documents
Gemini, reference document context, SSE, PDF parsing / OCR
Product operations
RevenueCat, Expo Push, Sentry, data import and validation tooling
For BTM, I developed the mobile app, admin panel, AI integration and background calculation services. I also handled the data models, subscription integration and release maintenance.