Repository: getsentry/sentry

Issue:
Pege not found when configuring DSN keys for project name "onboarding"
### Environment

SaaS (https://sentry.io/)

### Version

_No response_

### Link

_No response_

### DSN

_No response_

### Steps to Reproduce

1. Create or rename a project to "onboarding"
2. Go to Client Keys -> Configure

### Expected Result

Open the Client key configuration page

### Actual Result

Page not found error, as in the screenshot below.

Current workaround: rename the project.

URL: https://dev-curumas.sentry.io/settings/projects/onboarding/a9217e8f8e01407a9b6df81101793546/

![Screenshot 2023-03-24 at 07 59 44](https://user-images.githubusercontent.com/64906376/227448378-f017bf85-b321-4803-9006-7bc9e13d7048.png)



Discussion:
Assigning to @getsentry/support for [routing](https://open.sentry.io/triage/#2-route), due by **<time datetime=2023-03-24T21:00:00.000Z>Friday, March 24th at 17:00</time> (yyz)**. ⏲️
Routing to @getsentry/growth for [triage](https://develop.sentry.dev/processing-tickets/#3-triage), due by **<time datetime=2023-03-28T00:00:00.000Z>Monday, March 27th at 5:00 pm</time> (sfo)**. ⏲️

Resolving patch:
diff --git a/src/sentry/api/utils.py b/src/sentry/api/utils.py
--- a/src/sentry/api/utils.py
+++ b/src/sentry/api/utils.py
@@ -271,10 +271,13 @@ def generate_region_url(region_name: str | None = None) -> str:
     ),
     # Move /settings/:orgId/:section -> /settings/:section
     # but not /settings/organization or /settings/projects which is a new URL
-    (re.compile(r"\/?settings\/(?!account)(?!projects)(?!teams)[^\/]+\/(.*)"), r"/settings/\1"),
-    (re.compile(r"\/?join-request\/[^\/]+\/?.*"), r"/join-request/"),
-    (re.compile(r"\/?onboarding\/[^\/]+\/(.*)"), r"/onboarding/\1"),
-    (re.compile(r"\/?[^\/]+\/([^\/]+)\/getting-started\/(.*)"), r"/getting-started/\1/\2"),
+    (re.compile(r"^\/?settings\/(?!account)(?!projects)(?!teams)[^\/]+\/(.*)"), r"/settings/\1"),
+    (re.compile(r"^\/?join-request\/[^\/]+\/?.*"), r"/join-request/"),
+    (re.compile(r"^\/?onboarding\/[^\/]+\/(.*)"), r"/onboarding/\1"),
+    (
+        re.compile(r"\/?(?:[^\/]+(?<!settings))\/([^\/]+)\/getting-started\/(.*)"),
+        r"/getting-started/\1/\2",
+    ),
 ]
 
 


Test patch:
diff --git a/tests/sentry/api/test_utils.py b/tests/sentry/api/test_utils.py
--- a/tests/sentry/api/test_utils.py
+++ b/tests/sentry/api/test_utils.py
@@ -113,10 +113,19 @@ def test_customer_domain_path():
             "/getting-started/project-slug/python",
         ],
         ["/settings/projects/python/filters/", "/settings/projects/python/filters/"],
+        ["/settings/projects/onboarding/abc123/", "/settings/projects/onboarding/abc123/"],
+        [
+            "/settings/projects/join-request/abc123/",
+            "/settings/projects/join-request/abc123/",
+        ],
         [
             "/settings/projects/python/filters/discarded/",
             "/settings/projects/python/filters/discarded/",
         ],
+        [
+            "/settings/projects/getting-started/abc123/",
+            "/settings/projects/getting-started/abc123/",
+        ],
         ["/settings/teams/peeps/", "/settings/teams/peeps/"],
     ]
     for input_path, expected in scenarios: