Skip to content

feat(#1632): reject Guid-shaped display_name on entity create/update - #1640

Merged
savasp-agent[bot] merged 1 commit into
mainfrom
feat/1632-displayname-guid-validator
May 4, 2026
Merged

feat(#1632): reject Guid-shaped display_name on entity create/update#1640
savasp-agent[bot] merged 1 commit into
mainfrom
feat/1632-displayname-guid-validator

Conversation

@savasp-agent

@savasp-agent savasp-agent Bot commented May 4, 2026

Copy link
Copy Markdown
Contributor

Summary

A display_name that parses as a Guid in any standard form would collide with the Guid-first addressing surface defined by #1629 — CLI lookups and API by-id routes would silently bypass display-name search (or, worse, return a different real entity whose Guid happens to match). This PR rejects the collision class at write time.

  • New Cvoya.Spring.Core.Validation.DisplayNameValidator covers every Guid form (N, D, B, P, X) explicitly via Guid.TryParseExactGuid.TryParse is lenient but does NOT accept the hex-block X form, so the explicit fan-out is load-bearing.
  • Also rejects empty / whitespace input, control characters, and values longer than 256 chars, each with its own structured error code (display_name_is_empty, display_name_is_guid_shape, display_name_contains_control_chars, display_name_too_long).
  • Wires the validator into the agent create, unit create + patch, and platform-tenant create + patch endpoints behind a shared DisplayNameProblems helper that emits 400 ProblemDetails with the structured code extension so the CLI and portal can pattern-match on a stable contract.
  • Connector / agent-runtime endpoints don't accept caller-supplied display_name (those values come from the type descriptor); agent metadata PATCH carries no display_name field. No other create/update surface needed wiring.

Per the issue brief, the portal change is intentionally out of scope for this PR — the portal will surface the API's 400 generically and a friendlier message can be a follow-up.

Closes #1632.

Test plan

  • dotnet build SpringVoyage.slnx — 0 warnings, 0 errors.
  • dotnet format SpringVoyage.slnx --verify-no-changes — clean.
  • dotnet test --solution SpringVoyage.slnx --no-build — 3490/3490 passing (4 skipped, 0 failed).
  • npm run lint — clean.
  • npm --workspace=spring-voyage-dashboard run typecheck — clean.
  • npm run --workspace=spring-voyage-dashboard build — clean.
  • New unit-test class covers every Guid form (N / D / B / P / X), surrounding-whitespace, mixed-case, the substring-not-rejected case, control characters, and the length cap.
  • New integration tests cover the 400 + structured-code shape on POST /api/v1/tenant/agents, POST /api/v1/tenant/units, PATCH /api/v1/tenant/units/{id}, POST /api/v1/platform/tenants, PATCH /api/v1/platform/tenants/{id}, plus the PATCH-with-null-DisplayName no-op path.

A display_name that parses as a Guid in any standard form would collide
with the Guid-first addressing surface defined by #1629 — CLI lookups
and API by-id routes would silently bypass display-name search (or
worse, return a different real entity whose Guid happens to match).

Adds Cvoya.Spring.Core.Validation.DisplayNameValidator covering all
five Guid forms (N, D, B, P, X) explicitly via Guid.TryParseExact;
also rejects empty/whitespace, control characters, and >256-char input
with structured error codes. Wires it into the agent / unit / platform-
tenant create+update endpoints behind a shared DisplayNameProblems
helper that emits 400 ProblemDetails with the structured `code`
extension so the CLI and portal can pattern-match on a stable code.

Closes #1632.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@savasp-agent
savasp-agent Bot requested a review from savasp May 4, 2026 02:12
@savasp-agent
savasp-agent Bot enabled auto-merge May 4, 2026 02:12
@savasp-agent
savasp-agent Bot added this pull request to the merge queue May 4, 2026
Merged via the queue into main with commit eea1c01 May 4, 2026
27 checks passed
@savasp-agent
savasp-agent Bot deleted the feat/1632-displayname-guid-validator branch May 4, 2026 02:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Validate display_name is not a parseable Guid in any form

1 participant