LumiMeds engineering take-home

Run the pharmacy desk for a week

Pharmacy emails and patient orders arrive throughout the day. Your app reads the emails with AI, works out what's true about each pharmacy at every moment, and decides where every order goes, safely.

2 hourshard stop
~1.5 hcore
TypeScriptany framework
AI welcomeyou own what ships
Everything here is made up: the pharmacies, people, addresses, orders and emails.
Chapter 1

How it runs

We give you a simulator. It replays a week against your app as webhooks, and it plays the pharmacies' order API. You build everything in the blue boxes.

Simulatorsim/sim.mjs · ours Pharmacy APIpart of the simulator Waits for your replythen sends the next event YOUR APP POST /webhooksemail · order · simulation.started AI readsemail → changes Routepick a pharmacy Checks + what's true nowtrusted changes, with dates · orders today
  
An email, then an order.
Chapter 2

Watch a morning at the desk

An illustration with the pharmacies from week A, but made-up events. It's not the week you'll get: it shows the mechanics, not the tricky parts. Those are yours to find.

Monday08:00
Webhooks received
    Your app
    Waiting for the first event…
    MANUALa person routes it: only when no pharmacy can safely take the order
    Chapter 3

    One event at a time: reply when you're done

    The simulator only sends the next event after you reply. Your reply is the signal that you've finished. That's how a whole week replays in a minute or two, in the right order, however long your AI call takes.

    Do this finish, save, then reply

    Simulator
    Your app

    Not this reply first, work later

    Simulator
    Your app
    In production you'd acknowledge a webhook straight away and process it in the background. Here we've simplified it so the core fits in the time. Tell us in your README how you'd do it for real.
    Chapter 4

    Business goals, in priority order

    Goals, not an algorithm. When two of them conflict, decide what's right and explain it in your README.

    1
    SafeNever send an order to a pharmacy that can't ship to that state, doesn't have that exact dose, is closed, or is full for today.
    2
    Follow LumiMeds ops instructionsOnly our ops team decides where orders go. Pharmacies tell us about themselves.
    3
    Fastest deliveryThe patient gets their medication sooner.
    4
    Then cheapestAmong equally fast options, the one that costs us less.
    5
    MANUAL only when nobody canA person picks it up. Every unnecessary MANUAL is a patient waiting.
    Anything you're not sure about must not change what you believe about a pharmacy. Put it on Sam's list with the reason, and let a person decide.
    Chapter 5

    What to build

    There's more here than fits in two hours, on purpose. We'd rather see a core that's right in every case than many features done halfway.

    Core about 1.5 hours

    Webhook endpointthe three event types
    AI extractionemail → typed changes
    Checks in codewhich changes to trust
    What's true nowdates, capacity, every moment
    Routingby the goals, then send it
    Sam's listwhat you held back, and why

    When the core works, commit with the message core done.

    Bonuses pick, don't spread

    🟢 Testsfor the parts you think are risky
    🟢 Audit logevery change, when, and which email
    🟡 Flag sent ordersa pharmacy later says it can't fill them
    🟡 Evalslabel emails, measure your extraction
    🔴 Bad starting datasomething will cause unsafe routes if trusted as-is
    Core
    Bonus
    0:00commit "core done"2:00 hard stop
    Chapter 6

    Get started in two minutes

    Set up any TypeScript server with one POST endpoint, then point the simulator at it. --ping sends just three events to check your wiring.

    Full contract: sim/README.md in the repo. Keep state in memory between requests, and use the event's occurred_at as "now", never the computer's clock.

    Chapter 7

    How we evaluate

    A different week

    We replay a week you haven't seen

    The same kinds of emails and orders, different details. Three times, because AI answers vary.

    Safety first

    One unsafe order outweighs everything

    An order sent where it can't be filled is the worst outcome.

    Then quality

    Ops, MANUAL, speed, cost

    Did you follow instructions, use MANUAL only when needed, and ship fast and cheap?

    Your judgment

    The README matters

    What you chose not to do and why, the conflicts you resolved, and where you overrode the AI.

    Quality over quantity. A small core that's right in every case beats every feature done halfway.