Skip to content

Comments

feat: add RECOUP_ORG_ID constant for accountId override#109

Merged
sweetmantech merged 12 commits intotestfrom
sweetmantech/myc-3914-api-apichats-and-apichatgenerate-allow-accountid-param-for
Jan 14, 2026
Merged

feat: add RECOUP_ORG_ID constant for accountId override#109
sweetmantech merged 12 commits intotestfrom
sweetmantech/myc-3914-api-apichats-and-apichatgenerate-allow-accountid-param-for

Conversation

@sweetmantech
Copy link
Contributor

@sweetmantech sweetmantech commented Jan 14, 2026

Summary

  • Add RECOUP_ORG_ID constant to lib/const.ts with the Recoup admin organization UUID
  • This constant enables the accountId override feature for organization API keys
  • API keys from the Recoup admin org will have universal access to specify any accountId when creating chats

Test plan

  • Verify constant is exported correctly from const.ts
  • Run pnpm test - all 64 unit tests pass
  • Verify constant is accessible in consuming modules (canAccessAccount, getApiKeyDetails - to be implemented)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Organizations can now specify account IDs when creating chats, with built-in access validation.
    • Added API key validation and details retrieval for enhanced security.
  • Tests

    • Added comprehensive test coverage for chat creation, account validation, and access control.
  • Documentation

    • Added database operations guide covering import rules, directory structure, and usage patterns.

✏️ Tip: You can customize this high-level summary in your review settings.

Add the Recoup admin organization UUID constant to support the accountId
override feature. API keys from this organization have universal access
and can specify any accountId when creating chats.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@vercel
Copy link
Contributor

vercel bot commented Jan 14, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
recoup-api Ready Ready Preview Jan 14, 2026 7:55pm

@coderabbitai
Copy link

coderabbitai bot commented Jan 14, 2026

📝 Walkthrough

Walkthrough

This PR introduces account ID override functionality for organization API keys. It adds API key validation, organization access checking, and modifies chat creation to support accountId parameter overrides when authorized. A new Recoup admin organization constant grants universal access permissions.

Changes

Cohort / File(s) Summary
Constants & Documentation
lib/const.ts, CLAUDE.md
Introduces RECOUP_ORG_ID constant for Recoup admin organization with universal access; adds comprehensive Supabase database operation guidelines.
Authorization & Validation Layer
lib/accounts/validateOverrideAccountId.ts, lib/organizations/canAccessAccount.ts, lib/keys/getApiKeyDetails.ts
New modules implementing API key detail retrieval, organization access checks (with Recoup admin bypass), and accountId override validation with proper error responses.
Chat Handler Updates
lib/chats/createChatHandler.ts, lib/chats/validateCreateChatBody.ts
Extends chat creation to accept optional accountId in request body; integrates override validation for organization API keys with access permission checks.
Database Layer
lib/supabase/account_organization_ids/getAccountOrganizations.ts
Makes accountId parameter optional; broadens query logic to support filtering by accountId only, organizationId only, or both.
Test Suites
lib/accounts/__tests__/validateOverrideAccountId.test.ts, lib/chats/__tests__/createChatHandler.test.ts, lib/chats/__tests__/validateCreateChatBody.test.ts, lib/keys/__tests__/getApiKeyDetails.test.ts, lib/organizations/__tests__/canAccessAccount.test.ts
Comprehensive test coverage for new validation functions and chat handler accountId override scenarios; includes error cases, access denial, and API key validation.

Sequence Diagram

sequenceDiagram
    participant Client
    participant Handler as createChatHandler
    participant Validator as validateOverrideAccountId
    participant KeySvc as getApiKeyDetails
    participant OrgSvc as canAccessAccount
    participant DB as getAccountOrganizations
    participant ChatDB as insertRoom

    Client->>Handler: POST /chat (with optional accountId)
    Handler->>Handler: Extract API key from auth
    alt bodyAccountId provided
        Handler->>Validator: validateOverrideAccountId(apiKey, targetAccountId)
        Validator->>KeySvc: getApiKeyDetails(apiKey)
        KeySvc->>DB: getAccountOrganizations()
        DB-->>KeySvc: org membership details
        KeySvc-->>Validator: { accountId, orgId }
        Validator->>OrgSvc: canAccessAccount(orgId, targetAccountId)
        alt orgId equals RECOUP_ORG_ID
            OrgSvc-->>Validator: true (universal access)
        else organization member access
            OrgSvc->>DB: getAccountOrganizations(accountId, orgId)
            DB-->>OrgSvc: membership check
            OrgSvc-->>Validator: boolean result
        end
        alt Access granted
            Validator-->>Handler: { accountId: targetAccountId }
            Handler->>Handler: Override accountId
        else Access denied
            Validator-->>Handler: 403 Forbidden
            Handler-->>Client: Error response
        end
    end
    Handler->>ChatDB: insertRoom(with resolved accountId)
    ChatDB-->>Handler: room created
    Handler-->>Client: 200 Success
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • Test #69: Modifies getAccountOrganizations.ts parameter handling for accountId filtering, aligning with this PR's optional accountId changes.
  • API: Add Organization API endpoints #44: Extends organization-access logic and account-organization utilities; complements this PR's new canAccessAccount and override validation functions.

Poem

With keys in paw and orgs in sight,
We hop through access checks so tight!
Recoup admins bound without a care,
Chat accounts linked everywhere! 🐰🔐✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the primary change: adding the RECOUP_ORG_ID constant and its purpose for enabling accountId override functionality for organization API keys.
Docstring Coverage ✅ Passed Docstring coverage is 88.89% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

🧹 Recent nitpick comments
lib/supabase/account_organization_ids/getAccountOrganizations.ts (1)

56-60: Consider logging database errors for observability.

Errors are silently swallowed, which could mask database connectivity issues or query problems in production. Consider adding error logging while still returning the empty array.

♻️ Suggested improvement
   const { data, error } = await query;

-  if (error) return [];
+  if (error) {
+    console.error("[ERROR] getAccountOrganizations:", error);
+    return [];
+  }

   return (data as AccountOrganization[]) || [];
lib/keys/__tests__/getApiKeyDetails.test.ts (2)

93-138: Consider adding a test for exception handling.

The test suite covers null/empty returns well, but doesn't exercise the catch block (lines 47-50 in getApiKeyDetails.ts). Consider adding a test where a dependency throws to verify error logging and null return.

💡 Example test case
it("returns null and logs error when dependency throws", async () => {
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => {});
  vi.mocked(selectAccountApiKeys).mockRejectedValue(new Error("DB connection failed"));

  const result = await getApiKeyDetails("test_api_key");

  expect(result).toBeNull();
  expect(consoleSpy).toHaveBeenCalledWith(
    "[ERROR] getApiKeyDetails:",
    expect.any(Error)
  );
  consoleSpy.mockRestore();
});

73-79: Mock data is missing created_at field.

The AccountOrganization type includes created_at from the database table, but this mock is missing it. While the test may pass due to mock flexibility, consider adding the field for type consistency with the actual schema.

♻️ Suggested fix
       vi.mocked(getAccountOrganizations).mockResolvedValue([
         {
           account_id: "member-1",
           organization_id: orgId,
+          created_at: new Date().toISOString(),
           organization: null,
         },
       ]);
lib/accounts/validateOverrideAccountId.ts (2)

15-27: Clean up auto-generated JSDoc parameters.

The JSDoc contains duplicate auto-generated parameter entries (root0, root0.apiKey, root0.targetAccountId) that should be removed for clarity.

📝 Suggested JSDoc cleanup
 /**
  * Validates that an API key has permission to override to a target accountId.
  *
  * Used when an org API key wants to create resources on behalf of another account.
  * Checks that the API key belongs to an org with access to the target account.
  *
  * `@param` params.apiKey - The x-api-key header value
  * `@param` params.targetAccountId - The accountId to override to
- * `@param` root0
- * `@param` root0.apiKey
- * `@param` root0.targetAccountId
  * `@returns` The validated accountId or a NextResponse error
  */

32-57: Consider using 401 status for authentication failures.

Returning 500 for missing or invalid API keys conflates client errors with server errors. A 401 Unauthorized status would be more semantically correct for authentication failures, while 500 should be reserved for unexpected server-side issues.

That said, if returning 500 is intentional to avoid leaking information about key validity, this is acceptable as a security measure.

lib/chats/createChatHandler.ts (1)

36-48: Variable shadowing: validated is declared twice.

The validated variable at line 40 shadows the outer validated declared at line 31. While functionally correct (the outer variable is fully consumed at line 36 before the inner one is declared), this can cause confusion during maintenance.

♻️ Rename inner variable to avoid shadowing
     const { artistId, chatId, accountId: bodyAccountId } = validated;

     // Handle accountId override for org API keys
     if (bodyAccountId) {
-      const validated = await validateOverrideAccountId({
+      const overrideResult = await validateOverrideAccountId({
         apiKey: request.headers.get("x-api-key"),
         targetAccountId: bodyAccountId,
       });
-      if (validated instanceof NextResponse) {
-        return validated;
+      if (overrideResult instanceof NextResponse) {
+        return overrideResult;
       }
-      accountId = validated.accountId;
+      accountId = overrideResult.accountId;
     }

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a843bed and d601fda.

📒 Files selected for processing (9)
  • lib/accounts/__tests__/validateOverrideAccountId.test.ts
  • lib/accounts/validateOverrideAccountId.ts
  • lib/chats/__tests__/createChatHandler.test.ts
  • lib/chats/createChatHandler.ts
  • lib/keys/__tests__/getApiKeyDetails.test.ts
  • lib/keys/getApiKeyDetails.ts
  • lib/organizations/__tests__/canAccessAccount.test.ts
  • lib/organizations/canAccessAccount.ts
  • lib/supabase/account_organization_ids/getAccountOrganizations.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • lib/chats/tests/createChatHandler.test.ts
🧰 Additional context used
📓 Path-based instructions (1)
lib/**/validate*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

lib/**/validate*.ts: Create validation files following the naming convention: validate<EndpointName>Body.ts for POST/PUT request bodies
Create validation files following the naming convention: validate<EndpointName>Query.ts for GET query parameters
Use Zod for schema validation in validation files with proper error handling returning NextResponse with status 400 on validation failure

Files:

  • lib/accounts/validateOverrideAccountId.ts
  • lib/accounts/__tests__/validateOverrideAccountId.test.ts
🧠 Learnings (3)
📚 Learning: 2026-01-09T15:08:44.122Z
Learnt from: CR
Repo: Recoupable-com/Recoup-API PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-09T15:08:44.122Z
Learning: Applies to lib/**/validate*.ts : Use Zod for schema validation in validation files with proper error handling returning NextResponse with status 400 on validation failure

Applied to files:

  • lib/accounts/validateOverrideAccountId.ts
📚 Learning: 2026-01-09T15:08:44.122Z
Learnt from: CR
Repo: Recoupable-com/Recoup-API PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-09T15:08:44.122Z
Learning: Applies to lib/**/validate*.ts : Create validation files following the naming convention: `validate<EndpointName>Body.ts` for POST/PUT request bodies

Applied to files:

  • lib/accounts/__tests__/validateOverrideAccountId.test.ts
📚 Learning: 2026-01-09T15:08:44.122Z
Learnt from: CR
Repo: Recoupable-com/Recoup-API PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-09T15:08:44.122Z
Learning: Applies to lib/**/validate*.ts : Create validation files following the naming convention: `validate<EndpointName>Query.ts` for GET query parameters

Applied to files:

  • lib/accounts/__tests__/validateOverrideAccountId.test.ts
🧬 Code graph analysis (5)
lib/organizations/__tests__/canAccessAccount.test.ts (2)
lib/organizations/canAccessAccount.ts (1)
  • canAccessAccount (21-42)
lib/supabase/account_organization_ids/getAccountOrganizations.ts (1)
  • getAccountOrganizations (31-61)
lib/keys/__tests__/getApiKeyDetails.test.ts (3)
lib/supabase/account_api_keys/selectAccountApiKeys.ts (1)
  • selectAccountApiKeys (13-32)
lib/supabase/account_organization_ids/getAccountOrganizations.ts (1)
  • getAccountOrganizations (31-61)
lib/keys/getApiKeyDetails.ts (1)
  • getApiKeyDetails (20-51)
lib/accounts/validateOverrideAccountId.ts (3)
lib/networking/getCorsHeaders.ts (1)
  • getCorsHeaders (6-12)
lib/keys/getApiKeyDetails.ts (1)
  • getApiKeyDetails (20-51)
lib/organizations/canAccessAccount.ts (1)
  • canAccessAccount (21-42)
lib/chats/createChatHandler.ts (1)
lib/accounts/validateOverrideAccountId.ts (1)
  • validateOverrideAccountId (28-78)
lib/organizations/canAccessAccount.ts (2)
lib/const.ts (1)
  • RECOUP_ORG_ID (30-30)
lib/supabase/account_organization_ids/getAccountOrganizations.ts (1)
  • getAccountOrganizations (31-61)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Vercel Agent Review
🔇 Additional comments (9)
lib/supabase/account_organization_ids/getAccountOrganizations.ts (1)

36-54: LGTM! Well-structured query mode flexibility.

The implementation correctly handles three query modes with a sensible guard clause preventing unbounded queries. The conditional query building is clean and maintains type safety.

lib/organizations/canAccessAccount.ts (2)

21-42: LGTM! Clear access control implementation.

The function correctly implements the access control logic with proper input validation, universal admin access for RECOUP_ORG_ID, and organization membership verification. The early returns and guard clauses are well-structured.


30-33: Verify hardcoded admin org ID is intentional.

The RECOUP_ORG_ID grants universal access to all accounts. Ensure this UUID is treated as sensitive and consider whether it should be an environment variable for easier rotation, or if the current approach (hardcoded constant) better fits your security model.

lib/organizations/__tests__/canAccessAccount.test.ts (1)

1-111: LGTM! Comprehensive test coverage.

The test suite thoroughly covers all access paths:

  • Universal admin access bypasses database queries
  • Organization membership verification with proper mock assertions
  • Edge cases for invalid inputs (null orgId, empty targetAccountId)

The mock setup correctly uses Vitest's hoisting behavior.

lib/keys/getApiKeyDetails.ts (1)

39-46: LGTM! Clear organization detection logic.

The approach of checking for organization members to determine if the API key belongs to an organization vs personal account is straightforward and aligns with the data model.

lib/keys/__tests__/getApiKeyDetails.test.ts (1)

29-91: LGTM! Good coverage of valid API key scenarios.

The tests properly verify:

  • Personal keys return orgId: null when account has no members
  • Organization keys return matching accountId and orgId when members exist
  • Mock assertions confirm correct parameters passed to getAccountOrganizations
lib/accounts/__tests__/validateOverrideAccountId.test.ts (1)

1-131: Test coverage looks comprehensive.

The tests cover the key scenarios: successful validation, missing API key, invalid API key, and access denied (both for org keys without access and personal keys). The mocks are properly configured and cleared between tests.

Consider adding a test case for when targetAccountId is an empty string to ensure the validator handles this edge case correctly (though canAccessAccount may already handle this by returning false).

lib/accounts/validateOverrideAccountId.ts (1)

28-78: Implementation is clean and handles all error cases.

The function correctly validates API key presence, retrieves key details, and checks access permissions. The control flow is clear with appropriate early returns for error cases.

Note: Per coding guidelines, Zod is recommended for validate*.ts files, but those guidelines specifically target request body/query validation files (validate<EndpointName>Body.ts or validate<EndpointName>Query.ts). Since this file performs authorization validation rather than schema validation, the current approach without Zod is appropriate.

lib/chats/createChatHandler.ts (1)

20-48: Override flow implementation is correct and secure.

The handler properly:

  1. Validates the API key first via getApiKeyAccountId
  2. Parses and validates the request body
  3. Only attempts override validation when bodyAccountId is provided
  4. Correctly updates accountId only after successful authorization

The separation of authentication (line 22) and authorization for override (lines 40-46) is clean.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Adds a new authentication utility that extracts both accountId and orgId
from an API key. This is needed for the accountId override feature where
org API keys can specify a target accountId.

- Returns accountId from the API key's account field
- Returns orgId if the account is an organization (exists in account_organization_ids)
- Returns null orgId for personal API keys
- Includes 7 unit tests covering all scenarios

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@lib/auth/getApiKeyDetails.ts`:
- Line 28: getApiKeyDetails currently calls hashApiKey(apiKey,
PRIVY_PROJECT_SECRET) but PRIVY_PROJECT_SECRET is typed string | undefined; add
an explicit guard in getApiKeyDetails to handle undefined PRIVY_PROJECT_SECRET
before calling hashApiKey (e.g., log an error and return null or throw a clear
Error) so hashApiKey always receives a string; reference PRIVY_PROJECT_SECRET,
hashApiKey, and getApiKeyDetails when updating the code and ensure any callers
handle the null/error return.
🧹 Nitpick comments (3)
lib/auth/getApiKeyDetails.ts (1)

42-48: Consider logging supabase query errors.

The error from the account_organization_ids query is destructured away. While returning null for orgId on failure is acceptable, silently ignoring database errors makes debugging harder.

♻️ Suggested improvement
     // Check if this account is an organization by looking it up in account_organization_ids
-    const { data: orgRecord } = await supabase
+    const { data: orgRecord, error: orgError } = await supabase
       .from("account_organization_ids")
       .select("organization_id")
       .eq("organization_id", accountId)
       .maybeSingle();

+    if (orgError) {
+      console.error("[ERROR] getApiKeyDetails: Failed to check organization:", orgError);
+    }
+
     const orgId = orgRecord?.organization_id ?? null;
lib/auth/__tests__/getApiKeyDetails.test.ts (2)

38-64: Consider verifying mock invocations.

The tests verify the return value but don't assert that dependencies were called with the expected arguments. Adding these checks would improve confidence that the function integrates correctly.

♻️ Example verification additions
import { hashApiKey } from "@/lib/keys/hashApiKey";

// Inside the test after calling getApiKeyDetails:
expect(hashApiKey).toHaveBeenCalledWith("test_api_key", "test_secret");
expect(selectAccountApiKeys).toHaveBeenCalledWith({ keyHash: "hashed_test_api_key" });
expect(supabase.from).toHaveBeenCalledWith("account_organization_ids");

17-27: Consider adding a test for supabase query failure.

The implementation's try-catch block would handle a thrown error from the supabase query, but there's no test verifying this path or that the error is logged correctly.

♻️ Suggested additional test
it("returns result with null orgId when supabase org lookup fails", async () => {
  vi.mocked(selectAccountApiKeys).mockResolvedValue([
    {
      id: "key-1",
      account: "account-123",
      name: "Test Key",
      key_hash: "hashed_test_key",
      created_at: "2024-01-01T00:00:00Z",
      last_used: null,
    },
  ]);

  // Mock supabase to return an error
  const mockMaybeSingle = vi.fn().mockResolvedValue({ 
    data: null, 
    error: { message: "Database error" } 
  });
  const mockEq = vi.fn().mockReturnValue({ maybeSingle: mockMaybeSingle });
  const mockSelect = vi.fn().mockReturnValue({ eq: mockEq });
  vi.mocked(supabase.from).mockReturnValue({ select: mockSelect } as any);

  const result = await getApiKeyDetails("test_key");

  // Currently implementation ignores error and returns null orgId
  expect(result).toEqual({
    accountId: "account-123",
    orgId: null,
  });
});
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d69feaf and e3f4ae1.

📒 Files selected for processing (2)
  • lib/auth/__tests__/getApiKeyDetails.test.ts
  • lib/auth/getApiKeyDetails.ts
🧰 Additional context used
🧬 Code graph analysis (2)
lib/auth/getApiKeyDetails.ts (3)
lib/keys/hashApiKey.ts (1)
  • hashApiKey (10-12)
lib/const.ts (1)
  • PRIVY_PROJECT_SECRET (14-14)
lib/supabase/account_api_keys/selectAccountApiKeys.ts (1)
  • selectAccountApiKeys (13-32)
lib/auth/__tests__/getApiKeyDetails.test.ts (2)
lib/supabase/account_api_keys/selectAccountApiKeys.ts (1)
  • selectAccountApiKeys (13-32)
lib/auth/getApiKeyDetails.ts (1)
  • getApiKeyDetails (20-58)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Vercel Agent Review
🔇 Additional comments (3)
lib/auth/getApiKeyDetails.ts (1)

6-9: Well-structured implementation with good defensive coding.

The function properly handles null/empty inputs, wraps database operations in try-catch, and provides clear JSDoc documentation. The interface is cleanly defined with appropriate nullability for orgId.

Also applies to: 20-57

lib/auth/__tests__/getApiKeyDetails.test.ts (2)

66-95: Organization key test correctly validates orgId derivation.

The test properly mocks the scenario where account_organization_ids returns a matching record, and verifies that both accountId and orgId are set to the same organization ID. This aligns with the implementation logic.


98-143: Good coverage of edge cases and error paths.

The invalid input tests comprehensively cover: empty string, undefined coercion, not found in DB, selectAccountApiKeys returning null (error case), and API key record with null account. This provides solid defensive coverage.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
sweetmantech and others added 2 commits January 14, 2026 14:02
Document that all Supabase calls must be in lib/supabase/[table_name]/[function].ts
- Add directory structure example
- Add naming conventions (select, insert, update, delete, get)
- Add code pattern template

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add accountId field to POST /api/chats validation schema to enable
account override for organization API keys. Includes 9 unit tests
for the validation logic.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Allow org API keys to create chat rooms for accounts within their org.
- When accountId provided, validates access via getApiKeyDetails + canAccessAccount
- Returns 403 if access denied, 500 if API key validation fails
- Recoup admin org has universal access to all accounts
- Includes 6 unit tests

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add CRITICAL marker: NEVER import serverClient outside lib/supabase/
- Add 3-step process for database access in domain code
- Add WRONG vs CORRECT code examples
- Make rule more prominent and actionable

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace direct Supabase query with existing getAccountOrganizations()
lib function, following the architecture pattern documented in CLAUDE.md.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Extracted direct Supabase call from getApiKeyDetails.ts into a new
isOrganization() function in lib/supabase/account_organization_ids/.
This follows the architecture pattern of using supabase lib functions
instead of direct queries.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
canAccessAccount is about organization access control, not authentication.
Moving it to lib/organizations for better code organization.

- Moved lib/auth/canAccessAccount.ts to lib/organizations/canAccessAccount.ts
- Moved tests to lib/organizations/__tests__/canAccessAccount.test.ts
- Updated imports in createChatHandler.ts and its tests

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move getApiKeyDetails to lib/keys since it's about API key operations,
not authentication. Updated imports in createChatHandler and its tests.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create lib/accounts/validateOverrideAccountId.ts for SRP
- Update createChatHandler to use validateOverrideAccountId
- Replace isOrganization with getAccountOrganizations in getApiKeyDetails
- Extend getAccountOrganizations to support organizationId-only queries
- Delete isOrganization.ts and its tests

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@sweetmantech sweetmantech changed the base branch from main to test January 14, 2026 20:03
@sweetmantech sweetmantech reopened this Jan 14, 2026
@sweetmantech sweetmantech merged commit dac4fb7 into test Jan 14, 2026
5 checks passed
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