Malformed JSON on any POST endpoint previously bubbled a SyntaxError to
the top-level handler, which mapped every throw to 500. Client input
errors now respond 400 { "error": "Invalid JSON body" } via a typed
InvalidJsonBodyError thrown from readJson().
Adds contract tests covering all four POST endpoints plus a control
asserting schema-invalid (but well-formed) bodies still return 422.
Fixes#11