Dynadot's real api3.json response places ResponseCode + Status + Error
DIRECTLY under each <Command>Response envelope; there is no nested
`ResponseHeader` object — the prior decode shape was a misread of the
docs that survived because every test fixture used the same fictional
shape.
Live capture (2026-05-05, omani.works domain_info success):
{"DomainInfoResponse":{"ResponseCode":0,"Status":"success",
"DomainInfo":{...}}}
Live capture (error envelope):
{"DomainInfoResponse":{"ResponseCode":"-1","Status":"error",
"Error":"could not find domain in your account"}}
Note: ResponseCode is JSON int 0 on success but JSON string "-1" on
error. Switched to json.Number so both shapes round-trip without an
Unmarshal failure, and added codeIsZero() to normalise comparison.
What's fixed in this commit:
- core/pool-domain-manager/internal/registrar/dynadot:
ValidateToken / SetNameservers / GetNameservers / GetGlueRecord /
RegisterGlueRecord (all five command paths) now decode against the
real shape. Tightened classifyDynadotError so "could not find domain
in your account" maps to ErrDomainNotInAccount before the auth
matcher (which would otherwise grab on the substring "auth").
- core/pkg/dynadot-client: GetDomainInfo (was the last set_dns2 sibling
still using the wrapper) aligned with the rest of the client.
- products/catalyst/bootstrap/api/internal/dynadot: AddRecord rebound
to SetDnsResponse (not the SetDns2Response key it never returned)
with code+status at the top — fixes the silent-success-on-failure
loophole the catalyst-api was hitting.
Tests use real api3.json fixture shapes; new regression coverage for:
- ResponseCode=int 0 w/o Status field (Dynadot omits Status sometimes)
- "could not find domain in your account" → ErrDomainNotInAccount
- "needs to be registered with an ip address" set_ns rejection (#900)
Verified via live integration call against api.dynadot.com:
- ValidateToken(omani.works) -> success
- ValidateToken(google.com) -> ErrDomainNotInAccount
- GetNameservers(omani.works) -> ["ns1.openova.io","ns2.openova.io"]
Refs #939, #170, #900, #825.
Co-authored-by: hatiyildiz <269457768+hatiyildiz@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>