Skip to content

Fix organization and project name validation - #2422

Merged
niemyjski merged 2 commits into
mainfrom
issue/remove-obsolete-name-checks
Jul 30, 2026
Merged

Fix organization and project name validation#2422
niemyjski merged 2 commits into
mainfrom
issue/remove-obsolete-name-checks

Conversation

@niemyjski

@niemyjski niemyjski commented Jul 29, 2026

Copy link
Copy Markdown
Member

Summary

  • remove obsolete organization name uniqueness enforcement, its check-name endpoint, and the legacy Angular organization-name validator
  • keep project names unique within an organization, remove the unscoped project check-name route, and exclude the current project with projectId
  • remove failed-mutation query invalidation in Svelte because a rejected PATCH does not change server state
  • preserve existing wire statuses: project check-name 201 means unavailable, 204 means available, and duplicate project mutations remain 400 Bad Request

Root cause

Organization create/update enforced an obsolete uniqueness rule. Update validation also searched every visible organization without excluding the organization being updated, so an explicit same-name PATCH collided with itself.

Project validation had the same self-collision bug. Its unscoped route could also search across organizations even though the current UIs operate in an organization context.

The extra GET after a failed Svelte PATCH came from onError invalidating unchanged cached state. Successful server changes still use the existing WebSocket invalidation flow; this PR does not change WebSocket handling or add local echo state.

API behavior

  • organization names may be duplicated
  • project names remain case-insensitively unique within one organization
  • GET /api/v2/organizations/{organizationId}/projects/check-name accepts optional projectId
  • the legacy 201/204 meanings are unchanged; only their reversed OpenAPI descriptions were corrected
  • duplicate project create/update and empty organization names remain 400 Bad Request

Verification

  • backend build: 0 errors, 0 warnings
  • project check-name contract tests: 4 passed
  • project name mutation tests: 4 passed
  • organization name mutation tests: 4 passed
  • OpenAPI and endpoint-manifest snapshot tests: 5 passed
  • Svelte lint and Svelte check: 0 errors, 0 warnings
  • legacy Angular lint and production build passed
  • localhost Svelte dogfood:
    • successful organization/project rename: one PATCH plus one canonical detail GET
    • duplicate project rename: PATCH 400 with no failure-triggered GET
    • duplicate organization rename: PATCH 200
  • localhost legacy Angular dogfood:
    • no organization check-name request
    • duplicate project check: scoped request with projectId, 201, no PATCH
    • current project name with different casing: scoped request with projectId, 204, PATCH 200
  • removed organization and unscoped project check-name routes return 404; retained scoped route requires authentication
  • seed names restored after dogfood

Breaking changes

The obsolete unscoped GET /api/v2/projects/check-name and GET /api/v2/organizations/check-name routes are removed. The organization-scoped project check-name route remains available.

@niemyjski
niemyjski force-pushed the issue/remove-obsolete-name-checks branch 2 times, most recently from 7bf6f5d to ddbbe3b Compare July 29, 2026 03:41

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 366626430b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Exceptionless.Web/Api/Endpoints/ProjectEndpoints.cs
Comment thread src/Exceptionless.Web/Api/Handlers/ProjectHandler.cs Outdated
Comment thread src/Exceptionless.Web/ClientApp/src/lib/features/organizations/api.svelte.ts Outdated
@niemyjski niemyjski self-assigned this Jul 30, 2026
@niemyjski
niemyjski force-pushed the issue/remove-obsolete-name-checks branch from ddbbe3b to 2ea92b3 Compare July 30, 2026 18:07
@niemyjski
niemyjski merged commit 38e6e35 into main Jul 30, 2026
6 of 7 checks passed
@niemyjski
niemyjski deleted the issue/remove-obsolete-name-checks branch July 30, 2026 18:29

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ce4569e6fe

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

var changed = changes.GetEntity();
if (!await IsOrganizationNameAvailableInternalAsync(changed.Name, httpContext))
return Result.BadRequest("A organization with this name already exists.");
if (changes.ContainsChangedProperty(p => p.Name) && String.IsNullOrEmpty(changes.GetEntity().Name))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reject whitespace-only organization names

BLOCKER: When an organization PATCH or PUT supplies a name containing only spaces, String.IsNullOrEmpty accepts it and the handler persists a blank display name. The previous availability check used String.IsNullOrWhiteSpace, so this regresses the existing required-name contract; use the whitespace-aware check here as well.

AGENTS.md reference: AGENTS.md:L67-L67

Useful? React with 👍 / 👎.

@github-actions

Copy link
Copy Markdown

Code Coverage

Package Line Rate Branch Rate Complexity Health
Exceptionless.Core 74% 66% 9626
Exceptionless.AppHost 38% 40% 139
Exceptionless.Insulation 37% 35% 286
Exceptionless.Web 84% 67% 6925
Summary 77% (22916 / 29831) 66% (10528 / 16060) 16976

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.

1 participant