Skip to content

ref(api): promote org-scoped project creation endpoint to public#116333

Merged
betegon merged 1 commit into
masterfrom
ref/promote-org-projects-post-endpoint
May 28, 2026
Merged

ref(api): promote org-scoped project creation endpoint to public#116333
betegon merged 1 commit into
masterfrom
ref/promote-org-projects-post-endpoint

Conversation

@betegon
Copy link
Copy Markdown
Member

@betegon betegon commented May 27, 2026

POST /organizations/{org}/experimental/projects/ has been stable since Jan 2024 — it is what the onboarding UI calls when a member (no project:write) creates a project. Two problems: the /experimental/ path is a one-off with no codebase pattern, and EXPERIMENTAL status excludes it from the OpenAPI spec, so @sentry/api and the CLI have never been able to use it.

POST /organizations/{org}/projects/ was an empty slot (only GET existed). This fills it.

Before

POST /organizations/{org}/experimental/projects/   EXPERIMENTAL  ← not in spec
POST /teams/{org}/{team}/projects/                 PUBLIC

After

POST /organizations/{org}/projects/                PUBLIC  ← same behavior, first-class
POST /organizations/{org}/experimental/projects/   EXPERIMENTAL  ← temporary alias (backward compat)
POST /teams/{org}/{team}/projects/                 PUBLIC

The behavior is identical — auto-creates team-{username} for the caller, requires only project:read. The team-scoped endpoint is untouched.

The /experimental/ alias is kept alive as a backward-compat shim (OrganizationProjectsExperimentalCompatEndpoint) so the frontend doesn't break between this deploy and the frontend PR landing. It's POST-only (http_method_names = ["post", "options"]), marked EXPERIMENTAL so it stays out of the spec, and carries a TODO to remove it once the frontend PR merges.

Also fixes a pre-existing data consistency bug in the moved code: project.add_team(team) was called outside the transaction.atomic() block, meaning a failure there would leave a team and project in the DB without being linked. Moved it inside the transaction.

Housekeeping: organization_projects_experiment.py deleted, constants/helpers folded into organization_projects.py, both apidocs allowlists updated, CODEOWNERS updated, test file renamed test_organization_projects_create.py + new test for the role=member happy path.

Frontend follow-up (separate PR): drop /experimental/ from useCreateProject.ts and useCreateProjectFromWizard.tsx, then a cleanup PR removes the alias.

Legal Boilerplate

Look, I get it. The entity doing business as "Sentry" was incorporated in the State of Delaware in 2015 as Functional Software, Inc. and is gonna need some rights from me in order to utilize my contributions in this here PR. So here's the deal: I retain all rights, title and interest in and to my contributions, and by keeping this boilerplate intact I confirm that Sentry can use, modify, copy, and redistribute my contributions, under Sentry's choice of terms.

@github-actions github-actions Bot added Scope: Backend Automatically applied to PRs that change backend components Scope: Frontend Automatically applied to PRs that change frontend components labels May 27, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🚨 Warning: This pull request contains Frontend and Backend changes!

It's discouraged to make changes to Sentry's Frontend and Backend in a single pull request. The Frontend and Backend are not atomically deployed. If the changes are interdependent of each other, they must be separated into two pull requests and be made forward or backwards compatible, such that the Backend or Frontend can be safely deployed independently.

Have questions? Please ask in the #discuss-dev-infra channel.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 27, 2026

📊 Type Coverage Diff

✅ No new type safety issues introduced. Coverage: 93.58%

@betegon betegon force-pushed the ref/promote-org-projects-post-endpoint branch from 6cd9e2a to 334ae5d Compare May 27, 2026 19:32
@betegon betegon force-pushed the ref/promote-org-projects-post-endpoint branch from 420a530 to 2897b36 Compare May 27, 2026 21:01
@betegon betegon force-pushed the ref/promote-org-projects-post-endpoint branch 2 times, most recently from 6b8576d to ecbe60f Compare May 28, 2026 08:47
@betegon betegon marked this pull request as ready for review May 28, 2026 08:48
@betegon betegon requested review from a team as code owners May 28, 2026 08:48
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ecbe60f. Configure here.

Comment thread src/sentry/core/endpoints/organization_projects.py
@betegon betegon force-pushed the ref/promote-org-projects-post-endpoint branch from ecbe60f to dc65d45 Compare May 28, 2026 08:57
Comment thread src/sentry/core/endpoints/organization_projects.py Outdated
POST /api/0/organizations/{org}/experimental/projects/ has been stable
since Jan 2024 and is what the onboarding UI uses to let org members
(who lack project:write) create a project. The /experimental/ path
segment was a one-off with no codebase convention behind it, and
EXPERIMENTAL status excluded it from the OpenAPI spec and @sentry/api.

Move the POST handler into OrganizationProjectsEndpoint at
POST /organizations/{org}/projects/ (the slot was free — only GET
existed there), promote to PUBLIC, add @extend_schema, and delete the
experimental file. The team-scoped POST /teams/{org}/{team}/projects/
is unchanged — it remains the right call when a team is already known.

Changes:
- Add OrganizationProjectsPermission (StaffPermissionMixin +
  OrganizationPermission, POST scope lowered to project:read to
  preserve member access)
- Add post() to OrganizationProjectsEndpoint with full OpenAPI docs
- Move constants and helpers from organization_projects_experiment.py;
  import AuditData from team_projects.py instead of duplicating it
- Remove experimental URL from urls.py
- Remove experimental entry from api_publish_status_allowlist
- Remove /projects/ from api_ownership_allowlist (now owned by FOUNDATIONS)
- Update CODEOWNERS and coverage baseline to new file paths
- Rename test file and update all imports/patch paths
@betegon betegon merged commit 2db70ec into master May 28, 2026
63 of 64 checks passed
@betegon betegon deleted the ref/promote-org-projects-post-endpoint branch May 28, 2026 15:58
betegon added a commit that referenced this pull request May 29, 2026
…projects/ (#116388)

<!-- Describe your PR here. -->

Backend PR #116333 promoted `POST
/organizations/{org}/experimental/projects/` to `POST
/organizations/{org}/projects/` (PUBLIC). That PR keeps the old
`/experimental/` path alive as a backward-compat alias so the frontend
doesn't break between deploys.

This PR drops the `/experimental/` path from the two hooks that call it
and updates the test mocks and generated URL registry to match.

**Changed hooks:**
- `useCreateProject` — used by the main onboarding flow and the
create-project settings page
- `useCreateProjectFromWizard` — used by the setup wizard

**Also adds** a unit test for `useCreateProject` that explicitly asserts
the URL routing logic (no team slug → org endpoint, team slug present →
teams endpoint). That coverage didn't exist before.

Depends on #116333.

### Legal Boilerplate

Look, I get it. The entity doing business as "Sentry" was incorporated
in the State of Delaware in 2015 as Functional Software, Inc. and is
gonna need some rights from me in order to utilize my contributions in
this here PR. So here's the deal: I retain all rights, title and
interest in and to my contributions, and by keeping this boilerplate
intact I confirm that Sentry can use, modify, copy, and redistribute my
contributions, under Sentry's choice of terms.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants