Skip to content

Repository files navigation

Lab Automation System - Backend Technical Exercise

Context

This is a simplified lab automation backend — software that coordinates robotic lab equipment to run scientific experiments. The system models:

  • Devices — Physical lab instruments: liquid handlers (move liquids between wells), incubators (control temperature), plate readers (measure samples). Each device can only be used by one workflow at a time.
  • Workflows — A named sequence of operations on a device (e.g. "PCR Amplification": pipette transfer → incubate → plate read). States: createdrunningcompleted.
  • Samples — Biological specimens (blood, tissue, saliva) stored in plates at specific well positions (e.g. PLATE-01, well A1). Workflows process one or more samples.
  • Bookings — When a workflow starts, it books a device exclusively. The device is released when the workflow completes.

Overview

Microservice-based backend for managing laboratory workflows and devices. Two Python/Flask services communicating over HTTP, backed by PostgreSQL.

Time: ~40 minutes

Interviewer? See the cheatsheet (internal, requires Notion access).

Architecture

┌─────────────────┐ HTTP ┌─────────────────┐
│ │ ────────────> │ │
│ Workflow Service│ │ Device Service │
│ (port 5002) │ │ (port 5001) │
│ │ │ │
│ - Workflows │ │ - Devices │
│ - Samples │ │ - Bookings │
│ - Steps │ │ - Execution Logs │
└────────┬────────┘ └────────┬─────────┘
│ │
│ ┌──────────┐ │
└────────>│ Postgres │<───────────┘
│ (5432) │
└──────────┘

Getting Started

Prerequisites

  • Docker and Docker Compose
  • curl (or similar HTTP client)

Setup

docker compose up --build

First startup takes ~60 seconds to seed the database with test data.

Code changes auto-reload — no need to rebuild containers after editing Python files.

Verify

./verify-setup.sh

Exercise

Phase 1: Debugging (~20 minutes)

The system has 6 known bugs. Your task: find the root cause of each and fix them.

Issue 1: Service won't start

The workflow-service container crashes immediately on startup. Expected: Both services should start and respond to health checks.

docker compose logs workflow-service
# After fix:
curl http://localhost:5002/health # should return {"status": "healthy"}

Issue 2: Workflows can't be started

Creating a workflow succeeds, but starting it fails. The device service returns a 404. Expected: Starting a workflow should book the device and transition the workflow to running status.

curl -X POST http://localhost:5002/workflows \
-H "Content-Type: application/json" \
-d '{"name": "Test", "device_id": "liquid-handler-1", "steps": ["pipette_transfer"]}'
curl -X POST http://localhost:5002/workflows/{id}/start
# After fix: should return {"message": "Workflow started", "workflow": {"status": "running", ...}}

Issue 3: Race condition in device booking

Multiple workflows can book the same device simultaneously. Expected: Only one workflow should successfully book a device. All other concurrent attempts should fail with a 409 conflict. The device_bookings table should contain exactly one active booking per device.

./test-race-condition.sh
# After running, check how many active bookings exist for the device
docker compose exec postgres psql -U lab_admin -d device_db \
-c "SELECT * FROM device_bookings WHERE device_id = 'liquid-handler-1' AND status = 'active';"

Issue 4: Listing workflows is slow

The GET /workflows endpoint generates an excessive number of SQL queries. Check the workflow-service logs after hitting the endpoint. Expected: The endpoint should return all workflows with their samples and steps using a small, constant number of queries regardless of how many workflows exist.

curl http://localhost:5002/workflows
docker compose logs workflow-service | grep SELECT | wc -l

Issue 5: Searching execution logs is slow

Searching execution logs by time range is slower than expected. Expected: The search should return results quickly. Investigate why it's slow and fix it.

curl "http://localhost:5001/execution-logs/search?start=2025-01-01&end=2025-01-02"
docker compose exec postgres psql -U lab_admin -d device_db \
-c "EXPLAIN ANALYZE SELECT * FROM execution_logs WHERE started_at >= '2025-01-01' AND started_at <= '2025-01-02';"

Issue 6: Fetching all execution logs crashes the service

Requesting all execution logs causes the device-service container to crash. Expected: The endpoint should return results without crashing, regardless of how much data exists.

curl http://localhost:5001/execution-logs
docker compose ps # observe device-service has exited

Tips:

  • Check service logs: docker compose logs <service-name>
  • Use curl to test endpoints
  • Connect to the database: docker compose exec postgres psql -U lab_admin -d device_db

Phase 2: Feature Implementation (~20 minutes)

Implement a Device Scheduling/Queue System.

When a device is busy, booking requests should enter a priority queue instead of failing.

Requirements:

  • POST /devices/{id}/queue - Queue a booking request with priority (urgent, normal, low)
  • GET /devices/{id}/queue - View current queue for a device
  • GET /devices/{id}/wait-time - Get estimated wait time and queue position
  • When a device is released, the next queued request should be automatically booked
  • Priority ordering: urgent > normal > low, FIFO within same priority

Consider:

  • Concurrency: what if two requests queue simultaneously?
  • Edge cases: what if a queued workflow is cancelled?
  • Transaction safety on the release + auto-book sequence

API Reference

Device Service (port 5001)

MethodEndpointDescription
GET/healthHealth check
GET/devicesList all devices
GET/devices/{id}Get device details
POST/devices/{id}/bookBook device for workflow
POST/devices/{id}/releaseRelease device
POST/devices/{id}/executeExecute operation on device
GET/execution-logsGet execution logs
GET/execution-logs/search?start=X&end=YSearch logs by time range
GET/execution-logs/{device_id}Get logs for specific device

Workflow Service (port 5002)

MethodEndpointDescription
GET/healthHealth check
GET/workflowsList all workflows
GET/workflows/{id}Get workflow details
POST/workflowsCreate workflow
POST/workflows/{id}/startStart workflow
POST/workflows/{id}/completeComplete workflow
POST/workflows/{id}/execute-stepExecute next step
GET/samplesList all samples
GET/samples/{barcode}Get sample by barcode
POST/samples/validateValidate sample barcodes

Example Requests

# Create a workflow
curl -X POST http://localhost:5002/workflows \
-H "Content-Type: application/json" \
-d '{"name": "My Test Workflow", "device_id": "liquid-handler-1", "sample_barcodes": ["SAMPLE001", "SAMPLE002"], "steps": ["pipette_transfer", "dispense_reagent"]}'# Start a workflow
curl -X POST http://localhost:5002/workflows/{id}/start
# Search execution logs
curl "http://localhost:5001/execution-logs/search?start=2025-01-01&end=2025-01-02"# Check device status
curl http://localhost:5001/devices/liquid-handler-1

Useful Commands

# View logs
docker compose logs -f device-service
docker compose logs -f workflow-service
# Restart a service after code changes
docker compose restart device-service
# Rebuild after dependency changes
docker compose up --build device-service
# Connect to postgres (from inside docker network)
docker compose exec postgres psql -U lab_admin -d device_db
docker compose exec postgres psql -U lab_admin -d workflow_db
# Connect to postgres (from host)
psql -h localhost -p 5432 -U lab_admin -d device_db
# Test race condition
./test-race-condition.sh
# Reset database (wipes all data and re-seeds)
docker compose down -v && docker compose up -d
# Quick reset: clear bookings and release devices without full restart
docker compose exec postgres psql -U lab_admin -d device_db \
-c "DELETE FROM device_bookings; UPDATE devices SET status = 'available';"

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages