You're joining the returns team for a day. We run the customer-facing returns portals for a lot of brands you have heard of. Customers look up their order, see which items are eligible for return, and submit a request, you might have been in this situation yourself. The portal is live, but it's rough around the edges: the previous engineer left before finishing some critical backend work, tests are failing, and a few things are broken.
Below is the current backlog. The first three tasks (BR-001β003) are required; you don't have to do everything else β pick the electives that best show what you can do, and explain your choices in DECISIONS.md.
Please do not fork this repository. Clone it without forking work locally, and submit as as personal repo on Github, Gitlab, Codebergm ... or just zip us a file.
Stack: Python 3.13+, Django, pytest, ruff, mypy. PyYAML is included if you want it for rules config.
uv sync
pytest # you'll see some failures β that's intentional
python manage.py runserverOpen http://localhost:8000/returns/ and try order RMA-1001 with email alex@example.com or zip 10115.
portal/
data/orders_raw.json # raw order payloads from upstream
data/ # your rules config goes here (you define the format)
services/mapper.py # maps raw payload β domain model (incomplete)
services/eligibility.py # return eligibility evaluator (stubbed)
templates/returns/* # Django + HTMX UI
tests/* # pytest suite (some tests intentionally failing)
Time limit: 4 hours. If you hit the limit, stop and submit what you have. We'd rather see clean, well-reasoned partial work than a rushed complete solution.
AI tools are welcome. If you use them, keep a brief log in AI_LOG.md β we're curious how you use them, not whether you do.
BR-001, BR-002, and BR-003 are required β they're the core of the challenge and what every submission gets compared on. Everything else is an elective: pick one or two that play to your strengths, skip the rest, and tell us why in DECISIONS.md. Depth beats breadth.
Our upstream order system sends rich payloads, but the mapper was left unfinished β item-level flags never got wired up. The eligibility engine needs these to make decisions.
Missing fields on each article:
is_digitalis_final_salecategory
Look at the raw data in orders_raw.json and the test fixtures to understand the different payload shapes you need to handle.
Right now, evaluate_eligibility() just marks everything as returnable. We need a real rules engine β one that's configurable, not hardcoded.
Design your own rules format (JSON, YAML, whatever you prefer) and implement the evaluator. It should return a clear result per item (returnable or not, reason, matched rule) and handle at least:
- Return window (delivered date + allowed days)
- Already fully returned
- Digital items
- Final-sale items
We intentionally don't provide a rules file β we want to see how you'd structure it.
Several tests are failing. Some depend on BR-001 and BR-002 being done, others may have their own issues. Make the suite green and add tests that give you confidence in your implementation.
Product just told us: different categories need different return windows. Electronics should be 14 days, apparel gets 30, and so on. If your rules engine is well-designed, this should be a natural extension β add per-category window config and make the evaluator respect it. Fall back to the order-level default when a category isn't configured.
A security researcher has contacted us claiming they can access customer order data they shouldn't be able to. They want a fee to disclose the details. We'd rather understand our own exposure.
Audit the portal's authentication and authorization model β how a customer proves who they are, and how the app decides what they're allowed to see. We're not looking for a single planted bug; we want your assessment of the system.
Produce a short write-up (in DECISIONS.md or a SECURITY.md) that:
- Lists the threats you found β each with a one-line description of how it's exploited and what it exposes.
- Ranks them by real-world exploitability β not theoretical severity. A trivially scriptable attack against live customer data outranks one that needs a session you can't get.
- Fixes the one you judge most important, with a test that demonstrates the exploit before the fix and its absence after.
- Says why you deprioritized the rest β what you'd do with another day, and what you'd escalate to the team rather than fix solo.
We care more about how you reason about the exposure and where you choose to spend limited time than about the length of the list.
Support keeps asking: can customers filter the articles list to only see what's actually returnable? Add a "Show returnable only" toggle using HTMX β no full page reload.
The "Continue" button on the articles page is dead β the rest of the flow was apparently deleted before the last push. Build the missing pieces: article selection β confirmation β success. A customer should be able to complete a return end-to-end, and a submitted return must survive a server restart β persist it.
One thing support keeps seeing: impatient customers double-click submit, or hit refresh on the success page. What should happen then? Your call β just make it deliberate.
See something that bugs you? Have an idea that would make the portal better? Go for it β just keep it scoped and tell us about it in DECISIONS.md.
- Working, type-safe code
- Small, readable commits
DECISIONS.mdβ what you picked, what you skipped, and whyAI_LOG.mdβ if you used AI tools
Β© parcelLab β May your returns always be smooth.