Skip to main content
MediumBackendRefactor

Refactor Duplicate Validation and Decouple Database Access

`main.py` has three handler functions: `register_user`, `update_profile`, and `create_post`. They all work — but the code has two problems. First, the same username validation block is copy-pasted into all three handler...

What you will practice

PythonREST APIs / RoutesRefactoringDRYDependency Injection

Requirements

  • `register_user`, `update_profile`, and `create_post` must return identical responses to the originals for all valid and invalid inputs.
  • The username validation logic must not be duplicated — it must live in exactly one place.
  • A `validators.py` file must exist and contain the extracted validation logic.
  • `main.py` must not import `Database` from `db.py`.
  • Each handler must accept its save mechanism as an external dependency so tests can pass a mock without touching the real database.

Starter files

main.pyEditable starter
db.pyReference starter

What the judge checks

  • Runs in the python environment with the python-pytest runner.
  • Uses a 5000ms judge budget.
  • Behavior rules include: Behavior Preserved, Validation Not Duplicated, Database Not Imported In Main, Validators Module Exists.

Constraints

  • Do not change the response shape or error messages.
  • Do not modify `db.py`.

Example behavior

Input
register_user({'username': 'alice', 'email': 'a@b.com'}, save=mock_save)
Output
{'status': 'ok', 'data': {'username': 'alice', 'email': 'a@b.com'}}
Input
register_user({'username': 'x'}, save=mock_save)
Output
{'error': 'username must be between 3 and 20 characters'}

Follow-up

If you needed to support multiple database backends (Postgres, SQLite, in-memory), what would you change about the interface you designed?