feat: refactor GET /api/organizations to use auth-derived accountId#216
Conversation
Replace unauthenticated accountId query param with auth-derived account using validateAuthContext + buildGetOrganizationsParams pattern. - Add buildGetOrganizationsParams with access control (canAccessAccount) - Add validateGetOrganizationsRequest (auth + Zod query validation) - Update getOrganizationsHandler to use new validation pipeline - Add 7 unit tests for buildGetOrganizationsParams - Delete replaced validateOrganizationsQuery.ts - Rename param from accountId to account_id (snake_case) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThe changes refactor the GET /api/organizations endpoint to improve separation of concerns: API documentation clarifies authentication requirements and account filtering behavior, while three new/modified modules centralize request validation and parameter construction based on API key type and access permissions. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Poem
🚥 Pre-merge checks | ❌ 1❌ Failed checks (1 warning)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@lib/organizations/validateGetOrganizationsRequest.ts`:
- Around line 59-75: The discriminated-union narrowing is lost by destructuring
{ params, error } from buildGetOrganizationsParams; instead keep the result as a
single variable (e.g., result = await buildGetOrganizationsParams(...)), check
result.error and return the NextResponse when present, and only then return
result.params (which TS will correctly narrow to GetAccountOrganizationsParams).
Update the code paths around buildGetOrganizationsParams, error, and params to
use the single result object so the function's declared return type
Promise<NextResponse | GetAccountOrganizationsParams> is satisfied.
🧹 Nitpick comments (1)
lib/organizations/validateGetOrganizationsRequest.ts (1)
9-11: Consider exporting the inferred query schema type.The coding guidelines for
validate*.tsfiles state: "Export inferred types for validated data." You could export the inferred type fromgetOrganizationsQuerySchemafor reuse.export type GetOrganizationsQuery = z.infer<typeof getOrganizationsQuerySchema>;As per coding guidelines,
lib/**/validate*.ts: "Export inferred types for validated data."
| const { params, error } = await buildGetOrganizationsParams({ | ||
| accountId, | ||
| orgId, | ||
| targetAccountId, | ||
| }); | ||
|
|
||
| if (error) { | ||
| return NextResponse.json( | ||
| { | ||
| status: "error", | ||
| error, | ||
| }, | ||
| { status: 403, headers: getCorsHeaders() }, | ||
| ); | ||
| } | ||
|
|
||
| return params; |
There was a problem hiding this comment.
TypeScript narrowing lost after destructuring the discriminated union.
After destructuring { params, error }, TypeScript can no longer correlate the two fields. Even though the if (error) guard on Line 65 returns early, params remains typed as GetAccountOrganizationsParams | null — so Line 75 could return null, which doesn't satisfy the declared return type Promise<NextResponse | GetAccountOrganizationsParams>.
Avoid destructuring the result to preserve the discriminated union narrowing:
🛡️ Proposed fix
- const { params, error } = await buildGetOrganizationsParams({
+ const result = await buildGetOrganizationsParams({
accountId,
orgId,
targetAccountId,
});
- if (error) {
+ if (result.error) {
return NextResponse.json(
{
status: "error",
- error,
+ error: result.error,
},
{ status: 403, headers: getCorsHeaders() },
);
}
- return params;
+ return result.params;🤖 Prompt for AI Agents
In `@lib/organizations/validateGetOrganizationsRequest.ts` around lines 59 - 75,
The discriminated-union narrowing is lost by destructuring { params, error }
from buildGetOrganizationsParams; instead keep the result as a single variable
(e.g., result = await buildGetOrganizationsParams(...)), check result.error and
return the NextResponse when present, and only then return result.params (which
TS will correctly narrow to GetAccountOrganizationsParams). Update the code
paths around buildGetOrganizationsParams, error, and params to use the single
result object so the function's declared return type Promise<NextResponse |
GetAccountOrganizationsParams> is satisfied.
…216) Replace unauthenticated accountId query param with auth-derived account using validateAuthContext + buildGetOrganizationsParams pattern. - Add buildGetOrganizationsParams with access control (canAccessAccount) - Add validateGetOrganizationsRequest (auth + Zod query validation) - Update getOrganizationsHandler to use new validation pipeline - Add 7 unit tests for buildGetOrganizationsParams - Delete replaced validateOrganizationsQuery.ts - Rename param from accountId to account_id (snake_case) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Summary
GET /api/organizationsto usevalidateAuthContext+buildGetOrganizationsParamspattern (matching pulses, chats, sandboxes)accountIdtoaccount_id(snake_case consistency)account_idis now optional — only used by org keys to filter to a specific memberChanges
lib/organizations/buildGetOrganizationsParams.tslib/organizations/__tests__/buildGetOrganizationsParams.test.ts(7 tests)lib/organizations/validateGetOrganizationsRequest.tslib/organizations/getOrganizationsHandler.tsapp/api/organizations/route.ts(JSDoc only)lib/organizations/validateOrganizationsQuery.tsTest plan
buildGetOrganizationsParamsrecoup orgs listCLI works without code changes (derives account from API key)curl -H "x-api-key: $KEY" .../api/organizationsreturns orgs for authenticated accountcurl .../api/organizationsreturns 401 (was previously 400 for missing accountId)🤖 Generated with Claude Code
Summary by CodeRabbit
Documentation
accountId(required) toaccount_id(optional) for filtering.Refactor