HomeChallengesRepsProblemsLeaderboardTake a challenge

Domain Model Security Guard

A Payment whose state anyone can change, twice, without recording a transaction id. Close the door.

Intermediate20 min on the clock6 graded checks · 100 pointsASP.NET Core RefactorPro
Graded by reading your code against the checklist below.

What you build

  • Give every state property a private setter
  • Move the transition behind a named method: MarkAsPaid(externalTransactionId)
  • Record the transaction id and the timestamp as part of the transition
  • Throw InvalidOperationException if it is already paid
  • Write the test that proves paying twice throws

Done means

The only route into Paid is MarkAsPaid, it records the id, and it refuses to run twice.

How it is graded

Published in full, before you start — every point is one of these and there is nothing else.

  1. State properties have private setters+20Objects that protect themselves
  2. No state property is left publicly settable+10Objects that protect themselves
  3. The transition is a named domain method+25Objects that protect themselves
  4. The transition records the transaction id+15Objects that protect themselves
  5. Paying twice throws InvalidOperationException+15Enforcing the rules of your data
  6. A test proves the second call throws+15Enforcing the rules of your data

What it teaches

The rest of ASP.NET Core Refactor