Files
tech-log-backend/src/adapter
DongHyeonkaandClaude Opus 5 c8a891c407 fix: honour the contract's nullable fields and its error codes
Two contract mismatches, both found by driving the API and both invisible
from inside the repository because nothing compares the wire to the spec.

Nullable-but-required. The contract says required means "the key is
present", not "the value is set" — WorkingCopyInputBase spells it out:
"불완전한 초안도 저장할 수 있어야 하므로 필드는 required이되 빈 값과 null을
허용한다". The generator moves `required` straight to @NotNull, so
topicId, projectId, lastVerifiedOn, verifiedOn, decidedOn, decisionStatus
and questionStatus all became non-null, and saving a partial draft failed:

  {"projectId": null} → 400 NOT_NULL "Required value is missing"

prepareStudioCodegenSpec already derives a codegen-only copy of the spec,
so the relaxation happens there — 33 properties leave `required` in that
copy and the canonical file is untouched, which matters because the
frontend reads the same file and its reading is the correct one. Value
constraints stay: title still carries @NotNull @Size(max = 120).

  all-null / omitted / empty slug   201
  title 121 chars                   422
  slug "Bad Slug!"                  422

Error codes. Body validation fell through to the template's handler and
answered 400 VALIDATION_FAILED, a code the Studio contract does not
declare (it knows REQUEST_VALIDATION_FAILED and DOCUMENT_VALIDATION_
FAILED); denials answered AUTHZ_INSUFFICIENT_PERMISSION where the
contract assigns STUDIO_ACCESS_DENIED to 403. The frontend validates the
envelope's code against an enum, so an undeclared code breaks parsing
rather than surfacing as the error it is. Both now map in
StudioExceptionHandler, which is already scoped to the techlog package so
fileserver and healthcheck keep their existing shapes.

  body validation  422 REQUEST_VALIDATION_FAILED
  denial           403 STUDIO_ACCESS_DENIED

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 01:49:05 +09:00
..