TASK
Implementation
The command side is the write path in CQRS. Before any state change is applied, the command must pass two layers of validation: schema validation (correct fields and types) and business rule validation (domain constraints). Only then is the command executed and a domain event emitted.
Implement a node that processes commands through both validation layers:
// Schema error: missing required field
{ "type": "CreateUser", "msg_id": 1,
"payload": {"name": "John"} } // email missing
-> { "type": "validation_failed", "in_reply_to": 1,
"valid": false, "errors": ["Email is required"] }
// Business rule error: age constraint
{ "type": "CreateUser", "msg_id": 2,
"payload": {"name": "John", "email": "j@example.com", "age": 16} }
-> { "type": "validation_failed", "in_reply_to": 2,
"valid": false, "errors": ["User must be 18 or older"] }
// All validation passes: execute and emit domain event
{ "type": "CreateUser", "msg_id": 3,
"payload": {"name": "John", "email": "j@example.com", "age": 25} }
-> { "type": "command_executed", "in_reply_to": 3,
"success": true,
"events": [{"type": "UserCreated", "payload": {"id": "<uuid>"}}] }When multiple validations fail, collect all errors and return them together. Never execute the command if any validation fails.
Sample Test Cases
Validate command formatTimeout: 5000ms
Input
{
"src": "client",
"dest": "commandside",
"body": {
"type": "CreateUser",
"msg_id": 1,
"payload": {
"name": "John"
}
}
}Expected Output
{"type": "validation_failed", "in_reply_to": 1, "valid": false, "errors": ["Email is required"]}Validate business rulesTimeout: 5000ms
Input
{
"src": "client",
"dest": "commandside",
"body": {
"type": "CreateUser",
"msg_id": 1,
"payload": {
"name": "John",
"email": "john@example.com",
"age": 16
}
}
}Expected Output
{"type": "validation_failed", "in_reply_to": 1, "valid": false, "errors": ["User must be 18 or older"]}Hints
Hint 1▾
Schema validation: check required fields and types before business rules
Hint 2▾
Business rule validation: enforce domain constraints (age >= 18, unique email, etc.)
Hint 3▾
Return all validation errors together, not just the first one
Hint 4▾
Only call the command handler after all validation passes
Hint 5▾
Emit a domain event (UserCreated) that describes what happened, not what was requested
OVERVIEW
Theoretical Hub
Concept overview coming soon
Key Concepts
command validationbusiness rulescommand handlerdomain eventsinvariant enforcement
main.py
python
1
2
3
4
5
6
7
8
9
10
11
12
13
#!/usr/bin/env python3
import sys
import json
def main():
# Your implementation here
for line in sys.stdin:
msg = json.loads(line)
print(json.dumps(msg), flush=True)
if __name__ == "__main__":
main()