diff --git a/.claude/CLAUDE-KNOWLEDGE.md b/.claude/CLAUDE-KNOWLEDGE.md index 7580fcaf5..f6eb84ce8 100644 --- a/.claude/CLAUDE-KNOWLEDGE.md +++ b/.claude/CLAUDE-KNOWLEDGE.md @@ -538,3 +538,6 @@ A: Import `generatedSetupPromptText` from `docs-mintlify/snippets/home-prompt-is ## Q: Where should Mintlify docs for restricted users live? A: Put restricted-user docs at `docs-mintlify/guides/apps/authentication/restricted-users.mdx` and register the page in the Authentication group in `docs-mintlify/docs.json`. The page should cover `includeRestricted: true`, `user.isRestricted`, `user.restrictedReason`, anonymous users being restricted by definition, and JWKS `include_restricted=true` for services that intentionally accept restricted-user tokens. + +## Q: How should e2e tests switch to a newly created project? +A: `Project.createAndSwitch` should leave `backendContext.projectKeys` set to real project API keys, not only `{ projectId, adminAccessToken }`. Internal admin access tokens are regular short-lived access tokens; keeping one in the default project context makes later server/admin requests fail with `ADMIN_ACCESS_TOKEN_EXPIRED` or validate the token against the wrong project. diff --git a/apps/backend/src/lib/config.tsx b/apps/backend/src/lib/config.tsx index bf5be93c1..9c535d095 100644 --- a/apps/backend/src/lib/config.tsx +++ b/apps/backend/src/lib/config.tsx @@ -775,11 +775,7 @@ import.meta.vitest?.test('_validateConfigOverrideSchemaImpl(...)', async ({ expe type: 'postgres', connectionString: 'postgres://user:pass@host:port/db', }, - })).toEqual(Result.error(deindent` - [WARNING] sourceOfTruth is not matched by any of the provided schemas: - Schema 0: - sourceOfTruth.type must be one of the following values: hosted - `)); + })).toEqual(Result.ok(null)); expect(await validateConfigOverrideSchema(projectConfigSchema, projectSchemaBase, { sourceOfTruth: { type: 'postgres', @@ -788,6 +784,10 @@ import.meta.vitest?.test('_validateConfigOverrideSchemaImpl(...)', async ({ expe [WARNING] sourceOfTruth is not matched by any of the provided schemas: Schema 0: sourceOfTruth.type must be one of the following values: hosted + Schema 1: + sourceOfTruth.connectionStrings must be defined + Schema 2: + sourceOfTruth.connectionString must be defined `)); // Dot-notation keys that dot into nothing — detected by simulating the rendering pipeline diff --git a/apps/e2e/tests/backend/backend-helpers.ts b/apps/e2e/tests/backend/backend-helpers.ts index 09da1f189..f67364333 100644 --- a/apps/e2e/tests/backend/backend-helpers.ts +++ b/apps/e2e/tests/backend/backend-helpers.ts @@ -1340,6 +1340,11 @@ export namespace Project { }, userAuth: null }); + const { projectKeys } = await InternalApiKey.create(createResult.adminAccessToken); + backendContext.set({ + projectKeys, + userAuth: null + }); return createResult; } diff --git a/apps/e2e/tests/backend/endpoints/api/v1/integrations/neon/projects/provision.test.ts b/apps/e2e/tests/backend/endpoints/api/v1/integrations/neon/projects/provision.test.ts index bb8c98748..73b2453d4 100644 --- a/apps/e2e/tests/backend/endpoints/api/v1/integrations/neon/projects/provision.test.ts +++ b/apps/e2e/tests/backend/endpoints/api/v1/integrations/neon/projects/provision.test.ts @@ -255,9 +255,7 @@ it("ignores connection_strings while provisioning with hosted source-of-truth", expect(configResponse.body.config_string).toBeDefined(); const sourceOfTruth = JSON.parse(configResponse.body.config_string).sourceOfTruth; expect(sourceOfTruth).toMatchInlineSnapshot(` - { - "type": "hosted", - } + { "type": "hosted" } `); }); @@ -295,8 +293,6 @@ it("accepts connection_strings updates without changing hosted source-of-truth", expect(configResponse.body.config_string).toBeDefined(); const sourceOfTruth = JSON.parse(configResponse.body.config_string).sourceOfTruth; expect(sourceOfTruth).toMatchInlineSnapshot(` - { - "type": "hosted", - } + { "type": "hosted" } `); }); diff --git a/apps/e2e/tests/backend/endpoints/api/v1/internal-metrics.test.ts b/apps/e2e/tests/backend/endpoints/api/v1/internal-metrics.test.ts index 958e99a3a..288658ae8 100644 --- a/apps/e2e/tests/backend/endpoints/api/v1/internal-metrics.test.ts +++ b/apps/e2e/tests/backend/endpoints/api/v1/internal-metrics.test.ts @@ -473,10 +473,12 @@ it("should return correct auth_overview breakdown including teams", async ({ exp // Create an anonymous user await Auth.Anonymous.signUp(); - await wait(2000); - - const response = await niceBackendFetch("/api/v1/internal/metrics", { accessType: 'admin' }); - expect(response.status).toBe(200); + const response = await waitForMetricsMatch(false, (r) => { + const authOverview = r.body?.auth_overview; + if (authOverview == null) return false; + const nonAnonFromOverview = authOverview.verified_users + authOverview.unverified_users; + return authOverview.anonymous_users >= 1 && nonAnonFromOverview >= 1 && authOverview.total_teams >= 1; + }); const authOverview = response.body.auth_overview;