From 54db327ee8570b2a5cdf3ffac4b8891aa9856da3 Mon Sep 17 00:00:00 2001 From: Arpit Gupta Date: Fri, 29 May 2026 20:53:09 +0530 Subject: [PATCH 1/8] feat(api): migrate GET /api/chats to session-scoped shape MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reads chats joined to sessions via a new selectChatsWithSessions helper and projects rows to { id, title, accountId, sessionId, updatedAt } so clients can render canonical /sessions/{sid}/chats/{cid} URLs. Recoup admin → all chats; personal/org → caller's account (or target with canAccessAccount). artist_account_id is accepted but ignored for backward compatibility. The MCP get_chats tool gets the same treatment. Co-Authored-By: Claude Opus 4.7 (1M context) --- app/api/chats/route.ts | 9 +- lib/chats/__tests__/getChatsHandler.test.ts | 274 +++++++----------- .../__tests__/validateGetChatsRequest.test.ts | 208 +++---------- lib/chats/getChatsHandler.ts | 63 ++-- lib/chats/validateGetChatsRequest.ts | 87 +++--- .../__tests__/registerGetChatsTool.test.ts | 91 +++--- lib/mcp/tools/chats/registerGetChatsTool.ts | 64 ++-- .../__tests__/selectChatsWithSessions.test.ts | 97 +++++++ lib/supabase/chats/selectChatsWithSessions.ts | 58 ++++ 9 files changed, 478 insertions(+), 473 deletions(-) create mode 100644 lib/supabase/chats/__tests__/selectChatsWithSessions.test.ts create mode 100644 lib/supabase/chats/selectChatsWithSessions.ts diff --git a/app/api/chats/route.ts b/app/api/chats/route.ts index 3a3070950..453fd1b51 100644 --- a/app/api/chats/route.ts +++ b/app/api/chats/route.ts @@ -21,13 +21,16 @@ export async function OPTIONS() { /** * GET /api/chats * - * Retrieves chat rooms for an account. + * Retrieves chats joined with their owning session. Each row carries + * `sessionId` and the owning `accountId` so clients can render canonical + * `/sessions/{sessionId}/chats/{chatId}` URLs. * * Authentication: x-api-key header or Authorization Bearer token required. * * Query parameters: - * - account_id (required): UUID of the account whose chats to retrieve - * - artist_account_id (optional): Filter to chats for a specific artist (UUID) + * - account_id (optional): UUID of the target account (validated for access). + * - artist_account_id (optional): Accepted for backward compatibility but + * ignored — reserved for the artist-surface migration. * * @param request - The request object containing query parameters * @returns A NextResponse with chats data or an error diff --git a/lib/chats/__tests__/getChatsHandler.test.ts b/lib/chats/__tests__/getChatsHandler.test.ts index 45c80c769..f453028ce 100644 --- a/lib/chats/__tests__/getChatsHandler.test.ts +++ b/lib/chats/__tests__/getChatsHandler.test.ts @@ -4,7 +4,7 @@ import { getChatsHandler } from "../getChatsHandler"; import { validateAuthContext } from "@/lib/auth/validateAuthContext"; import { canAccessAccount } from "@/lib/organizations/canAccessAccount"; -import { selectRooms } from "@/lib/supabase/rooms/selectRooms"; +import { selectChatsWithSessions } from "@/lib/supabase/chats/selectChatsWithSessions"; vi.mock("@/lib/auth/validateAuthContext", () => ({ validateAuthContext: vi.fn(), @@ -14,12 +14,8 @@ vi.mock("@/lib/organizations/canAccessAccount", () => ({ canAccessAccount: vi.fn(), })); -vi.mock("@/lib/supabase/account_organization_ids/getAccountOrganizations", () => ({ - getAccountOrganizations: vi.fn(), -})); - -vi.mock("@/lib/supabase/rooms/selectRooms", () => ({ - selectRooms: vi.fn(), +vi.mock("@/lib/supabase/chats/selectChatsWithSessions", () => ({ + selectChatsWithSessions: vi.fn(), })); vi.mock("@/lib/networking/getCorsHeaders", () => ({ @@ -32,10 +28,6 @@ vi.mock("@/lib/const", () => ({ /** * Creates a mock NextRequest with the given URL and headers. - * - * @param url - The URL for the request - * @param apiKey - The API key header value - * @returns A mock NextRequest */ function createMockRequest(url: string, apiKey = "test-api-key"): NextRequest { return { @@ -63,29 +55,31 @@ describe("getChatsHandler", () => { expect(response.status).toBe(401); expect(json.status).toBe("error"); - expect(selectRooms).not.toHaveBeenCalled(); + expect(selectChatsWithSessions).not.toHaveBeenCalled(); }); }); describe("personal key behavior", () => { - it("returns chats for personal key owner without account_id param", async () => { + it("returns chats projected to the new shape for personal key", async () => { const accountId = "123e4567-e89b-12d3-a456-426614174000"; - const mockChats = [ - { - id: "chat-1", - account_id: accountId, - artist_id: null, - topic: "Chat 1", - updated_at: "2024-01-01T00:00:00Z", - }, - ]; - vi.mocked(validateAuthContext).mockResolvedValue({ accountId, - orgId: null, // Personal key + orgId: null, authToken: "test-token", }); - vi.mocked(selectRooms).mockResolvedValue(mockChats); + vi.mocked(selectChatsWithSessions).mockResolvedValue([ + { + id: "chat-1", + title: "Hello", + session_id: "sess-1", + updated_at: "2024-01-02T00:00:00Z", + created_at: "2024-01-01T00:00:00Z", + active_stream_id: null, + last_assistant_message_at: null, + model_id: null, + session: { id: "sess-1", account_id: accountId }, + }, + ]); const request = createMockRequest("http://localhost/api/chats"); const response = await getChatsHandler(request); @@ -93,11 +87,16 @@ describe("getChatsHandler", () => { expect(response.status).toBe(200); expect(json.status).toBe("success"); - expect(json.chats).toEqual(mockChats); - expect(selectRooms).toHaveBeenCalledWith({ - account_ids: [accountId], - artist_id: undefined, - }); + expect(json.chats).toEqual([ + { + id: "chat-1", + title: "Hello", + accountId, + sessionId: "sess-1", + updatedAt: "2024-01-02T00:00:00Z", + }, + ]); + expect(selectChatsWithSessions).toHaveBeenCalledWith({ accountIds: [accountId] }); }); it("returns 403 when personal key tries to filter by account_id", async () => { @@ -106,7 +105,7 @@ describe("getChatsHandler", () => { vi.mocked(validateAuthContext).mockResolvedValue({ accountId, - orgId: null, // Personal key + orgId: null, authToken: "test-token", }); vi.mocked(canAccessAccount).mockResolvedValue(false); @@ -117,129 +116,65 @@ describe("getChatsHandler", () => { expect(response.status).toBe(403); expect(json.status).toBe("error"); - expect(json.error).toBe("Access denied to specified account_id"); - expect(selectRooms).not.toHaveBeenCalled(); + expect(selectChatsWithSessions).not.toHaveBeenCalled(); }); }); - describe("org key behavior", () => { - it("returns chats for org key owner without account_id param", async () => { - const orgId = "123e4567-e89b-12d3-a456-426614174000"; - const mockChats = [ - { - id: "chat-1", - account_id: orgId, - artist_id: null, - topic: "Chat 1", - updated_at: "2024-01-01T00:00:00Z", - }, - ]; + describe("backwards compat", () => { + it("accepts artist_account_id but does not filter on it", async () => { + const accountId = "123e4567-e89b-12d3-a456-426614174000"; + const artistId = "223e4567-e89b-12d3-a456-426614174001"; vi.mocked(validateAuthContext).mockResolvedValue({ - accountId: orgId, - orgId, + accountId, + orgId: null, authToken: "test-token", }); - vi.mocked(selectRooms).mockResolvedValue(mockChats); + vi.mocked(selectChatsWithSessions).mockResolvedValue([]); - const request = createMockRequest("http://localhost/api/chats"); + const request = createMockRequest(`http://localhost/api/chats?artist_account_id=${artistId}`); const response = await getChatsHandler(request); const json = await response.json(); expect(response.status).toBe(200); expect(json.status).toBe("success"); - expect(json.chats).toEqual(mockChats); - expect(selectRooms).toHaveBeenCalledWith({ - account_ids: [orgId], - artist_id: undefined, - }); + expect(selectChatsWithSessions).toHaveBeenCalledWith({ accountIds: [accountId] }); }); + }); - it("allows org key to filter by account_id for org member", async () => { - const orgId = "123e4567-e89b-12d3-a456-426614174000"; - const memberId = "223e4567-e89b-12d3-a456-426614174000"; - const mockChats = [ - { - id: "chat-1", - account_id: memberId, - artist_id: null, - topic: "Chat 1", - updated_at: "2024-01-01T00:00:00Z", - }, - ]; - + describe("admin behavior", () => { + it("passes undefined accountIds for Recoup admin (no target filter)", async () => { + const recoupOrgId = "recoup-org-id"; vi.mocked(validateAuthContext).mockResolvedValue({ - accountId: orgId, - orgId, + accountId: recoupOrgId, + orgId: recoupOrgId, authToken: "test-token", }); - vi.mocked(canAccessAccount).mockResolvedValue(true); - vi.mocked(selectRooms).mockResolvedValue(mockChats); + vi.mocked(selectChatsWithSessions).mockResolvedValue([]); - const request = createMockRequest(`http://localhost/api/chats?account_id=${memberId}`); + const request = createMockRequest("http://localhost/api/chats"); const response = await getChatsHandler(request); - const json = await response.json(); expect(response.status).toBe(200); - expect(json.status).toBe("success"); - expect(selectRooms).toHaveBeenCalledWith({ - account_ids: [memberId], - artist_id: undefined, - }); - }); - - it("returns 403 when org key tries to access non-member account", async () => { - const orgId = "123e4567-e89b-12d3-a456-426614174000"; - const nonMemberId = "323e4567-e89b-12d3-a456-426614174000"; - - vi.mocked(validateAuthContext).mockResolvedValue({ - accountId: orgId, - orgId, - authToken: "test-token", - }); - vi.mocked(canAccessAccount).mockResolvedValue(false); - - const request = createMockRequest(`http://localhost/api/chats?account_id=${nonMemberId}`); - const response = await getChatsHandler(request); - const json = await response.json(); - - expect(response.status).toBe(403); - expect(json.status).toBe("error"); - expect(json.error).toBe("Access denied to specified account_id"); - expect(selectRooms).not.toHaveBeenCalled(); + expect(selectChatsWithSessions).toHaveBeenCalledWith({ accountIds: undefined }); }); - }); - describe("Recoup admin key behavior", () => { - it("returns chats for admin account without account_id param", async () => { + it("scopes admin to the target account when account_id is provided", async () => { const recoupOrgId = "recoup-org-id"; - const mockChats = [ - { - id: "chat-1", - account_id: recoupOrgId, - artist_id: null, - topic: "Chat 1", - updated_at: "2024-01-01T00:00:00Z", - }, - ]; - + const target = "323e4567-e89b-12d3-a456-426614174000"; vi.mocked(validateAuthContext).mockResolvedValue({ accountId: recoupOrgId, orgId: recoupOrgId, authToken: "test-token", }); - vi.mocked(selectRooms).mockResolvedValue(mockChats); + vi.mocked(canAccessAccount).mockResolvedValue(true); + vi.mocked(selectChatsWithSessions).mockResolvedValue([]); - const request = createMockRequest("http://localhost/api/chats"); + const request = createMockRequest(`http://localhost/api/chats?account_id=${target}`); const response = await getChatsHandler(request); - const json = await response.json(); expect(response.status).toBe(200); - expect(json.status).toBe("success"); - expect(selectRooms).toHaveBeenCalledWith({ - account_ids: [recoupOrgId], - artist_id: undefined, - }); + expect(selectChatsWithSessions).toHaveBeenCalledWith({ accountIds: [target] }); }); }); @@ -257,7 +192,7 @@ describe("getChatsHandler", () => { expect(response.status).toBe(400); expect(json.status).toBe("error"); - expect(selectRooms).not.toHaveBeenCalled(); + expect(selectChatsWithSessions).not.toHaveBeenCalled(); }); it("returns 400 when artist_account_id is invalid UUID", async () => { @@ -273,45 +208,12 @@ describe("getChatsHandler", () => { expect(response.status).toBe(400); expect(json.status).toBe("error"); - expect(selectRooms).not.toHaveBeenCalled(); + expect(selectChatsWithSessions).not.toHaveBeenCalled(); }); }); - describe("successful responses", () => { - it("returns filtered chats when artist_account_id is provided", async () => { - const accountId = "123e4567-e89b-12d3-a456-426614174000"; - const artistId = "223e4567-e89b-12d3-a456-426614174001"; - const mockChats = [ - { - id: "chat-1", - account_id: accountId, - artist_id: artistId, - topic: "Artist Chat", - updated_at: "2024-01-01T00:00:00Z", - }, - ]; - - vi.mocked(validateAuthContext).mockResolvedValue({ - accountId, - orgId: null, // Personal key - authToken: "test-token", - }); - vi.mocked(selectRooms).mockResolvedValue(mockChats); - - const request = createMockRequest(`http://localhost/api/chats?artist_account_id=${artistId}`); - const response = await getChatsHandler(request); - const json = await response.json(); - - expect(response.status).toBe(200); - expect(json.status).toBe("success"); - expect(json.chats).toEqual(mockChats); - expect(selectRooms).toHaveBeenCalledWith({ - account_ids: [accountId], - artist_id: artistId, - }); - }); - - it("returns empty array when no chats found", async () => { + describe("error handling", () => { + it("returns 500 when selectChatsWithSessions returns null", async () => { const accountId = "123e4567-e89b-12d3-a456-426614174000"; vi.mocked(validateAuthContext).mockResolvedValue({ @@ -319,20 +221,18 @@ describe("getChatsHandler", () => { orgId: null, authToken: "test-token", }); - vi.mocked(selectRooms).mockResolvedValue([]); + vi.mocked(selectChatsWithSessions).mockResolvedValue(null); const request = createMockRequest("http://localhost/api/chats"); const response = await getChatsHandler(request); const json = await response.json(); - expect(response.status).toBe(200); - expect(json.status).toBe("success"); - expect(json.chats).toEqual([]); + expect(response.status).toBe(500); + expect(json.status).toBe("error"); + expect(json.error).toBe("Failed to retrieve chats"); }); - }); - describe("error handling", () => { - it("returns 500 when selectRooms returns null", async () => { + it("returns 500 when an exception is thrown", async () => { const accountId = "123e4567-e89b-12d3-a456-426614174000"; vi.mocked(validateAuthContext).mockResolvedValue({ @@ -340,7 +240,7 @@ describe("getChatsHandler", () => { orgId: null, authToken: "test-token", }); - vi.mocked(selectRooms).mockResolvedValue(null); + vi.mocked(selectChatsWithSessions).mockRejectedValue(new Error("Database error")); const request = createMockRequest("http://localhost/api/chats"); const response = await getChatsHandler(request); @@ -348,26 +248,56 @@ describe("getChatsHandler", () => { expect(response.status).toBe(500); expect(json.status).toBe("error"); - expect(json.error).toBe("Failed to retrieve chats"); + expect(json.error).toBe("Database error"); }); + }); - it("returns 500 when an exception is thrown", async () => { + describe("response projection", () => { + it("skips rows whose session embed is missing", async () => { const accountId = "123e4567-e89b-12d3-a456-426614174000"; - vi.mocked(validateAuthContext).mockResolvedValue({ accountId, orgId: null, authToken: "test-token", }); - vi.mocked(selectRooms).mockRejectedValue(new Error("Database error")); + vi.mocked(selectChatsWithSessions).mockResolvedValue([ + { + id: "chat-keep", + title: "Keep", + session_id: "sess-1", + updated_at: "2024-01-02T00:00:00Z", + created_at: "2024-01-01T00:00:00Z", + active_stream_id: null, + last_assistant_message_at: null, + model_id: null, + session: { id: "sess-1", account_id: accountId }, + }, + { + id: "chat-orphan", + title: "Orphan", + session_id: "sess-2", + updated_at: "2024-01-03T00:00:00Z", + created_at: "2024-01-01T00:00:00Z", + active_stream_id: null, + last_assistant_message_at: null, + model_id: null, + session: null, + }, + ]); const request = createMockRequest("http://localhost/api/chats"); const response = await getChatsHandler(request); const json = await response.json(); - expect(response.status).toBe(500); - expect(json.status).toBe("error"); - expect(json.error).toBe("Database error"); + expect(json.chats).toEqual([ + { + id: "chat-keep", + title: "Keep", + accountId, + sessionId: "sess-1", + updatedAt: "2024-01-02T00:00:00Z", + }, + ]); }); }); }); diff --git a/lib/chats/__tests__/validateGetChatsRequest.test.ts b/lib/chats/__tests__/validateGetChatsRequest.test.ts index b28f253c1..540ce877e 100644 --- a/lib/chats/__tests__/validateGetChatsRequest.test.ts +++ b/lib/chats/__tests__/validateGetChatsRequest.test.ts @@ -5,7 +5,6 @@ import { validateGetChatsRequest } from "../validateGetChatsRequest"; import { validateAuthContext } from "@/lib/auth/validateAuthContext"; import { canAccessAccount } from "@/lib/organizations/canAccessAccount"; -// Mock dependencies vi.mock("@/lib/auth/validateAuthContext", () => ({ validateAuthContext: vi.fn(), })); @@ -14,10 +13,6 @@ vi.mock("@/lib/organizations/canAccessAccount", () => ({ canAccessAccount: vi.fn(), })); -vi.mock("@/lib/supabase/account_organization_ids/getAccountOrganizations", () => ({ - getAccountOrganizations: vi.fn(), -})); - vi.mock("@/lib/networking/getCorsHeaders", () => ({ getCorsHeaders: vi.fn(() => new Headers()), })); @@ -31,7 +26,7 @@ describe("validateGetChatsRequest", () => { vi.clearAllMocks(); }); - it("should return error if auth fails", async () => { + it("returns auth error if validateAuthContext fails", async () => { vi.mocked(validateAuthContext).mockResolvedValue( NextResponse.json({ status: "error", error: "Unauthorized" }, { status: 401 }), ); @@ -40,51 +35,39 @@ describe("validateGetChatsRequest", () => { const result = await validateGetChatsRequest(request); expect(result).toBeInstanceOf(NextResponse); - const response = result as NextResponse; - expect(response.status).toBe(401); + expect((result as NextResponse).status).toBe(401); }); - it("should return single account ID for personal key", async () => { - const mockAccountId = "personal-account-123"; + it("scopes personal key to the caller's account", async () => { + const accountId = "personal-account-123"; vi.mocked(validateAuthContext).mockResolvedValue({ - accountId: mockAccountId, - orgId: null, // Personal key + accountId, + orgId: null, authToken: "test-token", }); - const request = new NextRequest("http://localhost/api/chats", { - headers: { "x-api-key": "test-api-key" }, - }); + const request = new NextRequest("http://localhost/api/chats"); const result = await validateGetChatsRequest(request); expect(result).not.toBeInstanceOf(NextResponse); - expect(result).toEqual({ - account_ids: [mockAccountId], - artist_id: undefined, - }); + expect(result).toEqual({ accountIds: [accountId] }); }); - it("should return account_ids for org key", async () => { - const mockOrgId = "org-123"; + it("scopes org key to the caller's org account (target unspecified)", async () => { + const orgId = "org-123"; vi.mocked(validateAuthContext).mockResolvedValue({ - accountId: mockOrgId, - orgId: mockOrgId, + accountId: orgId, + orgId, authToken: "test-token", }); - const request = new NextRequest("http://localhost/api/chats", { - headers: { "x-api-key": "test-api-key" }, - }); + const request = new NextRequest("http://localhost/api/chats"); const result = await validateGetChatsRequest(request); - expect(result).not.toBeInstanceOf(NextResponse); - expect(result).toEqual({ - account_ids: [mockOrgId], - artist_id: undefined, - }); + expect(result).toEqual({ accountIds: [orgId] }); }); - it("should return account_ids for Recoup admin key", async () => { + it("returns undefined accountIds for Recoup admin (no target)", async () => { const recoupOrgId = "recoup-org-id"; vi.mocked(validateAuthContext).mockResolvedValue({ accountId: recoupOrgId, @@ -92,174 +75,75 @@ describe("validateGetChatsRequest", () => { authToken: "test-token", }); - const request = new NextRequest("http://localhost/api/chats", { - headers: { "x-api-key": "recoup-admin-key" }, - }); - const result = await validateGetChatsRequest(request); - - expect(result).not.toBeInstanceOf(NextResponse); - expect(result).toEqual({ - account_ids: [recoupOrgId], - artist_id: undefined, - }); - }); - - it("should parse artist_account_id query parameter correctly", async () => { - const mockAccountId = "account-123"; - const artistId = "a1111111-1111-4111-8111-111111111111"; - vi.mocked(validateAuthContext).mockResolvedValue({ - accountId: mockAccountId, - orgId: null, - authToken: "test-token", - }); - - const request = new NextRequest(`http://localhost/api/chats?artist_account_id=${artistId}`, { - headers: { "x-api-key": "test-api-key" }, - }); - const result = await validateGetChatsRequest(request); - - expect(result).not.toBeInstanceOf(NextResponse); - expect(result).toEqual({ - account_ids: [mockAccountId], - artist_id: artistId, - }); - }); - - it("should reject invalid artist_account_id query parameter", async () => { - vi.mocked(validateAuthContext).mockResolvedValue({ - accountId: "account-123", - orgId: null, - authToken: "test-token", - }); - - const request = new NextRequest("http://localhost/api/chats?artist_account_id=invalid", { - headers: { "x-api-key": "test-api-key" }, - }); - const result = await validateGetChatsRequest(request); - - expect(result).toBeInstanceOf(NextResponse); - const response = result as NextResponse; - expect(response.status).toBe(400); - }); - - it("should reject personal key trying to filter by account_id", async () => { - const mockAccountId = "a1111111-1111-4111-8111-111111111111"; - const otherAccountId = "b2222222-2222-4222-8222-222222222222"; - vi.mocked(validateAuthContext).mockResolvedValue({ - accountId: mockAccountId, - orgId: null, // Personal key - authToken: "test-token", - }); - - const request = new NextRequest(`http://localhost/api/chats?account_id=${otherAccountId}`, { - headers: { "x-api-key": "test-api-key" }, - }); + const request = new NextRequest("http://localhost/api/chats"); const result = await validateGetChatsRequest(request); - expect(result).toBeInstanceOf(NextResponse); - const response = result as NextResponse; - expect(response.status).toBe(403); + expect(result).toEqual({ accountIds: undefined }); }); - it("should allow org key to filter by account_id within org", async () => { - const mockOrgId = "c3333333-3333-4333-8333-333333333333"; - const targetAccountId = "d4444444-4444-4444-8444-444444444444"; + it("scopes admin to a specific account when account_id is supplied", async () => { + const recoupOrgId = "recoup-org-id"; + const target = "a1111111-1111-4111-8111-111111111111"; vi.mocked(validateAuthContext).mockResolvedValue({ - accountId: mockOrgId, - orgId: mockOrgId, + accountId: recoupOrgId, + orgId: recoupOrgId, authToken: "test-token", }); vi.mocked(canAccessAccount).mockResolvedValue(true); - const request = new NextRequest(`http://localhost/api/chats?account_id=${targetAccountId}`, { - headers: { "x-api-key": "test-api-key" }, - }); + const request = new NextRequest(`http://localhost/api/chats?account_id=${target}`); const result = await validateGetChatsRequest(request); expect(canAccessAccount).toHaveBeenCalledWith({ - targetAccountId, - currentAccountId: mockOrgId, - }); - expect(result).not.toBeInstanceOf(NextResponse); - expect(result).toEqual({ - account_ids: [targetAccountId], - artist_id: undefined, + targetAccountId: target, + currentAccountId: recoupOrgId, }); + expect(result).toEqual({ accountIds: [target] }); }); - it("should reject org key filtering by account_id not in org", async () => { - const mockOrgId = "f6666666-6666-4666-8666-666666666666"; - const notInOrgId = "b8888888-8888-4888-8888-888888888888"; + it("rejects personal key trying to filter by account_id", async () => { + const accountId = "a1111111-1111-4111-8111-111111111111"; + const other = "b2222222-2222-4222-8222-222222222222"; vi.mocked(validateAuthContext).mockResolvedValue({ - accountId: mockOrgId, - orgId: mockOrgId, + accountId, + orgId: null, authToken: "test-token", }); vi.mocked(canAccessAccount).mockResolvedValue(false); - const request = new NextRequest(`http://localhost/api/chats?account_id=${notInOrgId}`, { - headers: { "x-api-key": "test-api-key" }, - }); + const request = new NextRequest(`http://localhost/api/chats?account_id=${other}`); const result = await validateGetChatsRequest(request); - expect(canAccessAccount).toHaveBeenCalledWith({ - targetAccountId: notInOrgId, - currentAccountId: mockOrgId, - }); expect(result).toBeInstanceOf(NextResponse); - const response = result as NextResponse; - expect(response.status).toBe(403); + expect((result as NextResponse).status).toBe(403); }); - it("should allow Recoup admin to filter by any account_id", async () => { - const recoupOrgId = "recoup-org-id"; - const anyAccountId = "a1111111-1111-4111-8111-111111111111"; + it("accepts but ignores artist_account_id (reserved for artist-surface migration)", async () => { + const accountId = "personal-account-123"; + const artistId = "a1111111-1111-4111-8111-111111111111"; vi.mocked(validateAuthContext).mockResolvedValue({ - accountId: recoupOrgId, - orgId: recoupOrgId, + accountId, + orgId: null, authToken: "test-token", }); - vi.mocked(canAccessAccount).mockResolvedValue(true); // Admin always has access - const request = new NextRequest(`http://localhost/api/chats?account_id=${anyAccountId}`, { - headers: { "x-api-key": "recoup-admin-key" }, - }); + const request = new NextRequest(`http://localhost/api/chats?artist_account_id=${artistId}`); const result = await validateGetChatsRequest(request); - expect(canAccessAccount).toHaveBeenCalledWith({ - targetAccountId: anyAccountId, - currentAccountId: recoupOrgId, - }); - expect(result).not.toBeInstanceOf(NextResponse); - expect(result).toEqual({ - account_ids: [anyAccountId], - artist_id: undefined, - }); + expect(result).toEqual({ accountIds: [accountId] }); }); - it("should allow combining account_id and artist_account_id filters", async () => { - const mockOrgId = "c3333333-3333-4333-8333-333333333333"; - const targetAccountId = "d4444444-4444-4444-8444-444444444444"; - const artistId = "e5555555-5555-4555-8555-555555555555"; + it("returns 400 for invalid artist_account_id UUID", async () => { vi.mocked(validateAuthContext).mockResolvedValue({ - accountId: mockOrgId, - orgId: mockOrgId, + accountId: "account-123", + orgId: null, authToken: "test-token", }); - vi.mocked(canAccessAccount).mockResolvedValue(true); - const request = new NextRequest( - `http://localhost/api/chats?account_id=${targetAccountId}&artist_account_id=${artistId}`, - { - headers: { "x-api-key": "test-api-key" }, - }, - ); + const request = new NextRequest("http://localhost/api/chats?artist_account_id=invalid"); const result = await validateGetChatsRequest(request); - expect(result).not.toBeInstanceOf(NextResponse); - expect(result).toEqual({ - account_ids: [targetAccountId], - artist_id: artistId, - }); + expect(result).toBeInstanceOf(NextResponse); + expect((result as NextResponse).status).toBe(400); }); }); diff --git a/lib/chats/getChatsHandler.ts b/lib/chats/getChatsHandler.ts index da180ddfa..58e87f252 100644 --- a/lib/chats/getChatsHandler.ts +++ b/lib/chats/getChatsHandler.ts @@ -1,19 +1,27 @@ import { NextRequest, NextResponse } from "next/server"; import { getCorsHeaders } from "@/lib/networking/getCorsHeaders"; import { validateGetChatsRequest } from "@/lib/chats/validateGetChatsRequest"; -import { selectRooms } from "@/lib/supabase/rooms/selectRooms"; +import { selectChatsWithSessions } from "@/lib/supabase/chats/selectChatsWithSessions"; /** * Handler for retrieving chats. + * * Requires authentication via x-api-key header or Authorization bearer token. * - * For personal keys: Returns array of chats for the account (if exists). - * For org keys: Returns array of chats for accounts in the organization. - * For Recoup admin key: Returns array of ALL chat records. + * Returns chats joined with their owning session so the response carries the + * `sessionId` and the owning `accountId` per row, enabling clients to render + * canonical `/sessions/{sid}/chats/{cid}` URLs. + * + * Scope: + * - Personal/org key: chats belonging to the caller's account. + * - Personal/org key with `account_id`: chats for that account (when the + * caller can access it). + * - Recoup admin: all chats (or a specific account when `account_id` is set). * * Optional query parameters: - * - account_id: Filter to a specific account (validated against org membership) - * - artist_account_id: Filter to chats for a specific artist (UUID) + * - `account_id`: target account override (validated against access). + * - `artist_account_id`: accepted for backward-compat, but not used as a + * filter (reserved for the artist-surface migration). * * @param request - The request object containing query parameters * @returns A NextResponse with chats data @@ -25,31 +33,31 @@ export async function getChatsHandler(request: NextRequest): Promise { + if (!row.session) return []; + return [ + { + id: row.id, + title: row.title, + accountId: row.session.account_id, + sessionId: row.session_id, + updatedAt: row.updated_at, + }, + ]; + }); + return NextResponse.json( - { - status: "success", - chats, - }, - { - status: 200, - headers: getCorsHeaders(), - }, + { status: "success", chats }, + { status: 200, headers: getCorsHeaders() }, ); } catch (error) { console.error("[ERROR] getChatsHandler:", error); @@ -58,10 +66,7 @@ export async function getChatsHandler(request: NextRequest): Promise { - // Parse query parameters first +): Promise { const { searchParams } = new URL(request.url); - const queryParams = { + const queryResult = getChatsQuerySchema.safeParse({ account_id: searchParams.get("account_id") ?? undefined, artist_account_id: searchParams.get("artist_account_id") ?? undefined, - }; - - const queryResult = getChatsQuerySchema.safeParse(queryParams); + }); if (!queryResult.success) { const firstError = queryResult.error.issues[0]; return NextResponse.json( - { - status: "error", - error: firstError.message, - }, + { status: "error", error: firstError.message }, { status: 400, headers: getCorsHeaders() }, ); } - const { account_id: target_account_id, artist_account_id: artist_id } = queryResult.data; + const { account_id: targetAccountId } = queryResult.data; - // Use validateAuthContext for authentication const authResult = await validateAuthContext(request); if (authResult instanceof NextResponse) { return authResult; } + const { accountId, orgId } = authResult; - const { accountId: account_id } = authResult; - - // Use shared function to build params - const { params, error } = await buildGetChatsParams({ - account_id, - target_account_id, - artist_id, - }); + if (targetAccountId) { + const hasAccess = await canAccessAccount({ + targetAccountId, + currentAccountId: accountId, + }); + if (!hasAccess) { + return NextResponse.json( + { status: "error", error: "Access denied to specified account_id" }, + { status: 403, headers: getCorsHeaders() }, + ); + } + return { accountIds: [targetAccountId] }; + } - if (error) { - return NextResponse.json( - { - status: "error", - error, - }, - { status: 403, headers: getCorsHeaders() }, - ); + // Recoup admin → all chats. + if (orgId === RECOUP_ORG_ID) { + return { accountIds: undefined }; } - return params; + return { accountIds: [accountId] }; } diff --git a/lib/mcp/tools/chats/__tests__/registerGetChatsTool.test.ts b/lib/mcp/tools/chats/__tests__/registerGetChatsTool.test.ts index 4cceb5de3..04fc64198 100644 --- a/lib/mcp/tools/chats/__tests__/registerGetChatsTool.test.ts +++ b/lib/mcp/tools/chats/__tests__/registerGetChatsTool.test.ts @@ -5,27 +5,30 @@ import type { ServerRequest, ServerNotification } from "@modelcontextprotocol/sd import { registerGetChatsTool } from "../registerGetChatsTool"; -const mockSelectRooms = vi.fn(); +const mockSelectChatsWithSessions = vi.fn(); const mockCanAccessAccount = vi.fn(); -vi.mock("@/lib/supabase/rooms/selectRooms", () => ({ - selectRooms: (...args: unknown[]) => mockSelectRooms(...args), +vi.mock("@/lib/supabase/chats/selectChatsWithSessions", () => ({ + selectChatsWithSessions: (...args: unknown[]) => mockSelectChatsWithSessions(...args), })); vi.mock("@/lib/organizations/canAccessAccount", () => ({ canAccessAccount: (...args: unknown[]) => mockCanAccessAccount(...args), })); +vi.mock("@/lib/const", () => ({ + RECOUP_ORG_ID: "recoup-org-id", +})); + type ServerRequestHandlerExtra = RequestHandlerExtra; /** * Creates a mock extra object with optional authInfo. - * - * @param authInfo - Optional auth info object containing account ID. - * @param authInfo.accountId - The account ID for authentication. - * @returns A mock ServerRequestHandlerExtra object. */ -function createMockExtra(authInfo?: { accountId?: string }): ServerRequestHandlerExtra { +function createMockExtra(authInfo?: { + accountId?: string; + orgId?: string | null; +}): ServerRequestHandlerExtra { return { authInfo: authInfo ? { @@ -34,6 +37,7 @@ function createMockExtra(authInfo?: { accountId?: string }): ServerRequestHandle clientId: authInfo.accountId, extra: { accountId: authInfo.accountId, + orgId: authInfo.orgId ?? null, }, } : undefined, @@ -48,7 +52,7 @@ describe("registerGetChatsTool", () => { vi.clearAllMocks(); mockServer = { - registerTool: vi.fn((name, config, handler) => { + registerTool: vi.fn((_name, _config, handler) => { registeredHandler = handler; }), } as unknown as McpServer; @@ -60,21 +64,18 @@ describe("registerGetChatsTool", () => { expect(mockServer.registerTool).toHaveBeenCalledWith( "get_chats", expect.objectContaining({ - description: "Get chat conversations for accounts.", + description: expect.stringContaining("chat"), }), expect.any(Function), ); }); it("returns empty chats array when no records exist", async () => { - mockSelectRooms.mockResolvedValue([]); + mockSelectChatsWithSessions.mockResolvedValue([]); const result = await registeredHandler({}, createMockExtra({ accountId: "account-123" })); - expect(mockSelectRooms).toHaveBeenCalledWith({ - account_ids: ["account-123"], - artist_id: undefined, - }); + expect(mockSelectChatsWithSessions).toHaveBeenCalledWith({ accountIds: ["account-123"] }); expect(result).toEqual({ content: [ { @@ -85,14 +86,18 @@ describe("registerGetChatsTool", () => { }); }); - it("returns chats array with records when they exist", async () => { - mockSelectRooms.mockResolvedValue([ + it("returns chats projected to the new wire shape", async () => { + mockSelectChatsWithSessions.mockResolvedValue([ { id: "chat-456", - account_id: "account-123", - artist_id: null, - topic: "Test Chat", + title: "Test Chat", + session_id: "sess-1", updated_at: "2024-01-01T00:00:00Z", + created_at: "2024-01-01T00:00:00Z", + active_stream_id: null, + last_assistant_message_at: null, + model_id: null, + session: { id: "sess-1", account_id: "account-123" }, }, ]); @@ -102,7 +107,7 @@ describe("registerGetChatsTool", () => { content: [ { type: "text", - text: expect.stringContaining('"chats":['), + text: expect.stringContaining('"sessionId":"sess-1"'), }, ], }); @@ -110,7 +115,7 @@ describe("registerGetChatsTool", () => { content: [ { type: "text", - text: expect.stringContaining('"id":"chat-456"'), + text: expect.stringContaining('"accountId":"account-123"'), }, ], }); @@ -118,15 +123,7 @@ describe("registerGetChatsTool", () => { it("allows account_id override with access", async () => { mockCanAccessAccount.mockResolvedValue(true); - mockSelectRooms.mockResolvedValue([ - { - id: "chat-456", - account_id: "target-account-789", - artist_id: null, - topic: "Test Chat", - updated_at: "2024-01-01T00:00:00Z", - }, - ]); + mockSelectChatsWithSessions.mockResolvedValue([]); await registeredHandler( { account_id: "target-account-789" }, @@ -137,9 +134,8 @@ describe("registerGetChatsTool", () => { targetAccountId: "target-account-789", currentAccountId: "org-account-id", }); - expect(mockSelectRooms).toHaveBeenCalledWith({ - account_ids: ["target-account-789"], - artist_id: undefined, + expect(mockSelectChatsWithSessions).toHaveBeenCalledWith({ + accountIds: ["target-account-789"], }); }); @@ -174,25 +170,30 @@ describe("registerGetChatsTool", () => { }); }); - it("filters by artist_account_id when provided", async () => { - const artistChats = [ - { id: "chat-1", account_id: "account-123", artist_id: "artist-456", topic: "Artist Chat" }, - ]; - mockSelectRooms.mockResolvedValue(artistChats); + it("accepts artist_account_id but does not filter by it", async () => { + mockSelectChatsWithSessions.mockResolvedValue([]); await registeredHandler( { artist_account_id: "artist-456" }, createMockExtra({ accountId: "account-123" }), ); - expect(mockSelectRooms).toHaveBeenCalledWith({ - account_ids: ["account-123"], - artist_id: "artist-456", - }); + expect(mockSelectChatsWithSessions).toHaveBeenCalledWith({ accountIds: ["account-123"] }); + }); + + it("passes undefined accountIds for Recoup admin (all chats)", async () => { + mockSelectChatsWithSessions.mockResolvedValue([]); + + await registeredHandler( + {}, + createMockExtra({ accountId: "recoup-org-id", orgId: "recoup-org-id" }), + ); + + expect(mockSelectChatsWithSessions).toHaveBeenCalledWith({ accountIds: undefined }); }); - it("returns error when selectRooms fails", async () => { - mockSelectRooms.mockResolvedValue(null); + it("returns error when selectChatsWithSessions fails", async () => { + mockSelectChatsWithSessions.mockResolvedValue(null); const result = await registeredHandler({}, createMockExtra({ accountId: "account-123" })); diff --git a/lib/mcp/tools/chats/registerGetChatsTool.ts b/lib/mcp/tools/chats/registerGetChatsTool.ts index 7f999b4eb..e8333cd97 100644 --- a/lib/mcp/tools/chats/registerGetChatsTool.ts +++ b/lib/mcp/tools/chats/registerGetChatsTool.ts @@ -3,25 +3,32 @@ import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/proto import type { ServerRequest, ServerNotification } from "@modelcontextprotocol/sdk/types.js"; import { z } from "zod"; import type { McpAuthInfo } from "@/lib/mcp/verifyApiKey"; -import { selectRooms } from "@/lib/supabase/rooms/selectRooms"; import { getToolResultSuccess } from "@/lib/mcp/getToolResultSuccess"; import { getToolResultError } from "@/lib/mcp/getToolResultError"; -import { buildGetChatsParams } from "@/lib/chats/buildGetChatsParams"; +import { canAccessAccount } from "@/lib/organizations/canAccessAccount"; +import { selectChatsWithSessions } from "@/lib/supabase/chats/selectChatsWithSessions"; +import { RECOUP_ORG_ID } from "@/lib/const"; const getChatsSchema = z.object({ account_id: z.string().optional().describe("The account ID to filter chats for."), - artist_account_id: z.string().optional().describe("The artist account ID to filter chats for."), + artist_account_id: z + .string() + .optional() + .describe( + "Deprecated: accepted for backward compatibility but no longer filters results. " + + "Reserved for the upcoming artist-surface migration.", + ), }); export type GetChatsArgs = z.infer; /** * Registers the "get_chats" tool on the MCP server. - * Retrieves chat conversations (rooms) for accounts. * - * For personal keys: Returns chats for the key owner's account. - * For org keys: Returns chats for all accounts in the organization. - * For Recoup admin key: Returns ALL chat records. + * Returns chats joined with their owning session so each row carries + * `sessionId` and the owning `accountId`. Scope mirrors GET /api/chats: + * personal/org → caller's account; Recoup admin → all; or a specific + * account when `account_id` is supplied and the caller can access it. * * @param server - The MCP server instance to register the tool on. */ @@ -33,10 +40,11 @@ export function registerGetChatsTool(server: McpServer): void { inputSchema: getChatsSchema, }, async (args: GetChatsArgs, extra: RequestHandlerExtra) => { - const { account_id, artist_account_id } = args; + const { account_id: targetAccountId } = args; const authInfo = extra.authInfo as McpAuthInfo | undefined; const accountId = authInfo?.extra?.accountId; + const orgId = authInfo?.extra?.orgId ?? null; if (!accountId) { return getToolResultError( @@ -44,22 +52,40 @@ export function registerGetChatsTool(server: McpServer): void { ); } - const { params, error } = await buildGetChatsParams({ - account_id: accountId, - target_account_id: account_id, - artist_id: artist_account_id, - }); - - if (error) { - return getToolResultError(error); + let accountIds: string[] | undefined; + if (targetAccountId) { + const hasAccess = await canAccessAccount({ + targetAccountId, + currentAccountId: accountId, + }); + if (!hasAccess) { + return getToolResultError("Access denied to specified account_id"); + } + accountIds = [targetAccountId]; + } else if (orgId === RECOUP_ORG_ID) { + accountIds = undefined; + } else { + accountIds = [accountId]; } - const chats = await selectRooms(params); - - if (chats === null) { + const rows = await selectChatsWithSessions({ accountIds }); + if (rows === null) { return getToolResultError("Failed to retrieve chats"); } + const chats = rows.flatMap(row => { + if (!row.session) return []; + return [ + { + id: row.id, + title: row.title, + accountId: row.session.account_id, + sessionId: row.session_id, + updatedAt: row.updated_at, + }, + ]; + }); + return getToolResultSuccess({ chats }); }, ); diff --git a/lib/supabase/chats/__tests__/selectChatsWithSessions.test.ts b/lib/supabase/chats/__tests__/selectChatsWithSessions.test.ts new file mode 100644 index 000000000..4532f0c66 --- /dev/null +++ b/lib/supabase/chats/__tests__/selectChatsWithSessions.test.ts @@ -0,0 +1,97 @@ +import { describe, it, expect, vi, beforeEach } from "vitest"; +import { selectChatsWithSessions } from "@/lib/supabase/chats/selectChatsWithSessions"; + +const fromMock = vi.fn(); +const selectMock = vi.fn(); +const inMock = vi.fn(); +const orderMock = vi.fn(); + +vi.mock("@/lib/supabase/serverClient", () => ({ + default: { + from: (...args: unknown[]) => fromMock(...args), + }, +})); + +beforeEach(() => { + vi.clearAllMocks(); + // Default chain: from().select().in().order() -> resolves to { data, error } + const builder = { + select: selectMock, + in: inMock, + order: orderMock, + }; + fromMock.mockReturnValue(builder); + selectMock.mockReturnValue(builder); + inMock.mockReturnValue(builder); + orderMock.mockResolvedValue({ data: [], error: null }); +}); + +describe("selectChatsWithSessions", () => { + it("queries chats joined with sessions, filtered by account_ids, ordered by updated_at desc", async () => { + const rows = [ + { + id: "chat-1", + title: "Hello", + session_id: "sess-1", + updated_at: "2024-01-02T00:00:00Z", + session: { id: "sess-1", account_id: "acc-1" }, + }, + ]; + orderMock.mockResolvedValueOnce({ data: rows, error: null }); + + const result = await selectChatsWithSessions({ accountIds: ["acc-1", "acc-2"] }); + + expect(fromMock).toHaveBeenCalledWith("chats"); + expect(selectMock).toHaveBeenCalledTimes(1); + const selectArg = selectMock.mock.calls[0]?.[0]; + expect(typeof selectArg).toBe("string"); + expect(String(selectArg)).toContain("session:sessions!inner"); + expect(String(selectArg)).toContain("account_id"); + + expect(inMock).toHaveBeenCalledWith("session.account_id", ["acc-1", "acc-2"]); + expect(orderMock).toHaveBeenCalledWith("updated_at", { ascending: false }); + expect(result).toEqual(rows); + }); + + it("returns [] without calling .in() when accountIds is undefined (admin: all)", async () => { + const rows = [ + { + id: "chat-1", + title: "Admin", + session_id: "sess-1", + updated_at: "2024-01-02T00:00:00Z", + session: { id: "sess-1", account_id: "acc-1" }, + }, + ]; + orderMock.mockResolvedValueOnce({ data: rows, error: null }); + + const result = await selectChatsWithSessions({}); + + expect(inMock).not.toHaveBeenCalled(); + expect(orderMock).toHaveBeenCalledWith("updated_at", { ascending: false }); + expect(result).toEqual(rows); + }); + + it("short-circuits to [] when accountIds is an empty array", async () => { + const result = await selectChatsWithSessions({ accountIds: [] }); + + expect(result).toEqual([]); + expect(fromMock).not.toHaveBeenCalled(); + }); + + it("returns null on supabase error", async () => { + orderMock.mockResolvedValueOnce({ data: null, error: { message: "boom" } }); + + const result = await selectChatsWithSessions({ accountIds: ["acc-1"] }); + + expect(result).toBeNull(); + }); + + it("returns [] when supabase returns no data and no error", async () => { + orderMock.mockResolvedValueOnce({ data: null, error: null }); + + const result = await selectChatsWithSessions({ accountIds: ["acc-1"] }); + + expect(result).toEqual([]); + }); +}); diff --git a/lib/supabase/chats/selectChatsWithSessions.ts b/lib/supabase/chats/selectChatsWithSessions.ts new file mode 100644 index 000000000..b08a45071 --- /dev/null +++ b/lib/supabase/chats/selectChatsWithSessions.ts @@ -0,0 +1,58 @@ +import supabase from "@/lib/supabase/serverClient"; +import type { Tables } from "@/types/database.types"; + +/** + * Chat row joined with its owning session. The embedded `session` carries the + * owning `account_id`, which callers project to `accountId` on the wire. + */ +export type ChatWithSession = Tables<"chats"> & { + session: Pick, "id" | "account_id"> | null; +}; + +export interface SelectChatsWithSessionsParams { + /** + * Owning account IDs to filter by (via `sessions.account_id`). + * - `undefined` returns chats across all accounts (admin scope). + * - `[]` short-circuits to an empty result. + */ + accountIds?: string[]; +} + +const SELECT = ` + *, + session:sessions!inner ( id, account_id ) +` as const; + +/** + * Reads chats joined to their owning session, optionally scoped to a set of + * account IDs through `sessions.account_id`. Ordered by `chats.updated_at` + * descending so newest activity surfaces first. + * + * Returns `null` when Supabase reports an error so callers can distinguish a + * transient failure from an empty result. + * + * @param params - Optional filter parameters + * @returns Matching rows, `[]` when no rows match, or `null` on DB error. + */ +export async function selectChatsWithSessions( + params: SelectChatsWithSessionsParams = {}, +): Promise { + const { accountIds } = params; + + if (accountIds !== undefined && accountIds.length === 0) { + return []; + } + + let query = supabase.from("chats").select(SELECT); + if (accountIds !== undefined) { + query = query.in("session.account_id", accountIds); + } + const { data, error } = await query.order("updated_at", { ascending: false }); + + if (error) { + console.error("[selectChatsWithSessions] error:", error); + return null; + } + + return (data ?? []) as ChatWithSession[]; +} From 1b38a3b79e1104844a2f0f8ca3a545d20c215a8f Mon Sep 17 00:00:00 2001 From: Arpit Gupta Date: Fri, 29 May 2026 21:23:57 +0530 Subject: [PATCH 2/8] refactor(api): drop explicit Tables<> type from selectChatsWithSessions The typed supabase-js client infers the join row shape from .from("chats").select("*, session:sessions!inner(id, account_id)") directly. The ChatWithSession alias built from Tables<"chats"> & Pick, ...> plus the trailing `as ChatWithSession[]` cast were just paying tax to reach a shape the SDK was already giving us. Let inference carry it through to the handler. Co-Authored-By: Claude Opus 4.7 (1M context) --- lib/supabase/chats/selectChatsWithSessions.ts | 20 +++++-------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/lib/supabase/chats/selectChatsWithSessions.ts b/lib/supabase/chats/selectChatsWithSessions.ts index b08a45071..36f326f98 100644 --- a/lib/supabase/chats/selectChatsWithSessions.ts +++ b/lib/supabase/chats/selectChatsWithSessions.ts @@ -1,13 +1,4 @@ import supabase from "@/lib/supabase/serverClient"; -import type { Tables } from "@/types/database.types"; - -/** - * Chat row joined with its owning session. The embedded `session` carries the - * owning `account_id`, which callers project to `accountId` on the wire. - */ -export type ChatWithSession = Tables<"chats"> & { - session: Pick, "id" | "account_id"> | null; -}; export interface SelectChatsWithSessionsParams { /** @@ -29,14 +20,13 @@ const SELECT = ` * descending so newest activity surfaces first. * * Returns `null` when Supabase reports an error so callers can distinguish a - * transient failure from an empty result. - * - * @param params - Optional filter parameters - * @returns Matching rows, `[]` when no rows match, or `null` on DB error. + * transient failure from an empty result. Row shape is inferred from the + * typed supabase-js client — both `chats.*` and the embedded `session` + * projection surface to callers without an explicit type alias. */ export async function selectChatsWithSessions( params: SelectChatsWithSessionsParams = {}, -): Promise { +) { const { accountIds } = params; if (accountIds !== undefined && accountIds.length === 0) { @@ -54,5 +44,5 @@ export async function selectChatsWithSessions( return null; } - return (data ?? []) as ChatWithSession[]; + return data ?? []; } From edcfd59981e90995ce7c9a046e2d309e89645e46 Mon Sep 17 00:00:00 2001 From: Arpit Gupta Date: Fri, 29 May 2026 21:34:28 +0530 Subject: [PATCH 3/8] refactor(api): describe artist_account_id as dormant, not deprecated The artist filter on GET /api/chats / get_chats is staying. It just has no rows to match until sessions.artist_id is populated. Reword the MCP tool schema, route handler JSDoc, and validator comment so callers know the filter is first-class and will start working once the database column lands. Co-Authored-By: Claude Opus 4.7 (1M context) --- lib/chats/getChatsHandler.ts | 5 +++-- lib/chats/validateGetChatsRequest.ts | 8 ++++---- lib/mcp/tools/chats/registerGetChatsTool.ts | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/chats/getChatsHandler.ts b/lib/chats/getChatsHandler.ts index 58e87f252..e1972c250 100644 --- a/lib/chats/getChatsHandler.ts +++ b/lib/chats/getChatsHandler.ts @@ -20,8 +20,9 @@ import { selectChatsWithSessions } from "@/lib/supabase/chats/selectChatsWithSes * * Optional query parameters: * - `account_id`: target account override (validated against access). - * - `artist_account_id`: accepted for backward-compat, but not used as a - * filter (reserved for the artist-surface migration). + * - `artist_account_id`: filter chats to a specific artist. Currently + * a no-op — the filter starts matching rows once the artist column + * is populated on sessions. * * @param request - The request object containing query parameters * @returns A NextResponse with chats data diff --git a/lib/chats/validateGetChatsRequest.ts b/lib/chats/validateGetChatsRequest.ts index 76d60ec41..e5cc45cec 100644 --- a/lib/chats/validateGetChatsRequest.ts +++ b/lib/chats/validateGetChatsRequest.ts @@ -8,10 +8,10 @@ import { RECOUP_ORG_ID } from "@/lib/const"; const getChatsQuerySchema = z.object({ account_id: z.string().uuid("account_id must be a valid UUID").optional(), - // `artist_account_id` is parsed for backward-compat with existing clients - // (so we don't 400) but intentionally not used as a filter — the chat - // listing surface no longer threads artist scope. Reserved for the - // artist-surface migration once `sessions.artist_id` lands. + // `artist_account_id` is parsed and validated, but does not yet filter + // — `sessions.artist_id` isn't populated, so the filter has nothing to + // match. The schema stays so the filter starts working transparently + // once the artist column lands. artist_account_id: z.string().uuid("artist_account_id must be a valid UUID").optional(), }); diff --git a/lib/mcp/tools/chats/registerGetChatsTool.ts b/lib/mcp/tools/chats/registerGetChatsTool.ts index e8333cd97..2833f33a7 100644 --- a/lib/mcp/tools/chats/registerGetChatsTool.ts +++ b/lib/mcp/tools/chats/registerGetChatsTool.ts @@ -15,8 +15,8 @@ const getChatsSchema = z.object({ .string() .optional() .describe( - "Deprecated: accepted for backward compatibility but no longer filters results. " + - "Reserved for the upcoming artist-surface migration.", + "Filter chats to those for the specified artist. Currently has no effect — " + + "the filter starts matching rows once the artist column is populated on sessions.", ), }); From cb56b2d2876a6b5982a080850577f5a88f62d520 Mon Sep 17 00:00:00 2001 From: Sweets Sweetman Date: Fri, 29 May 2026 15:23:23 -0500 Subject: [PATCH 4/8] chore(ci): prettier-format selectChatsWithSessions.ts --- lib/supabase/chats/selectChatsWithSessions.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/supabase/chats/selectChatsWithSessions.ts b/lib/supabase/chats/selectChatsWithSessions.ts index 36f326f98..4f68c9e5a 100644 --- a/lib/supabase/chats/selectChatsWithSessions.ts +++ b/lib/supabase/chats/selectChatsWithSessions.ts @@ -24,9 +24,7 @@ const SELECT = ` * typed supabase-js client — both `chats.*` and the embedded `session` * projection surface to callers without an explicit type alias. */ -export async function selectChatsWithSessions( - params: SelectChatsWithSessionsParams = {}, -) { +export async function selectChatsWithSessions(params: SelectChatsWithSessionsParams = {}) { const { accountIds } = params; if (accountIds !== undefined && accountIds.length === 0) { From 97b9e4390ee2c4f9e50b4407c6d51d928a3620a0 Mon Sep 17 00:00:00 2001 From: Sweets Sweetman Date: Sat, 30 May 2026 21:46:47 -0500 Subject: [PATCH 5/8] chore(types): regenerate types/database.types.ts from current supabase CLI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `pnpm update-types` produces this exact output today. The previously committed file was hand-edited (per api#628) which drifted from the CLI's current style (semicolons vs trailing-comma multi-line). No schema deltas — purely formatting normalization plus a few JSON-path keys the newer CLI infers on JSONB columns. Going forward this file should always be CLI-generated, never hand-edited, so future regens are no-ops. Co-Authored-By: Claude Opus 4.7 (1M context) --- types/database.types.ts | 7055 ++++++++++++++++++++------------------- 1 file changed, 3538 insertions(+), 3517 deletions(-) diff --git a/types/database.types.ts b/types/database.types.ts index 191472132..fc58d7c24 100644 --- a/types/database.types.ts +++ b/types/database.types.ts @@ -1,4192 +1,4198 @@ -export type Json = string | number | boolean | null | { [key: string]: Json | undefined } | Json[]; +export type Json = + | string + | number + | boolean + | null + | { [key: string]: Json | undefined } + | Json[] export type Database = { // Allows to automatically instantiate createClient with right options // instead of createClient(URL, KEY) __InternalSupabase: { - PostgrestVersion: "12.2.3 (519615d)"; - }; + PostgrestVersion: "12.2.3 (519615d)" + } public: { Tables: { account_api_keys: { Row: { - account: string | null; - created_at: string; - id: string; - key_hash: string | null; - last_used: string | null; - name: string; - }; + account: string | null + created_at: string + id: string + key_hash: string | null + last_used: string | null + name: string + } Insert: { - account?: string | null; - created_at?: string; - id?: string; - key_hash?: string | null; - last_used?: string | null; - name: string; - }; + account?: string | null + created_at?: string + id?: string + key_hash?: string | null + last_used?: string | null + name: string + } Update: { - account?: string | null; - created_at?: string; - id?: string; - key_hash?: string | null; - last_used?: string | null; - name?: string; - }; + account?: string | null + created_at?: string + id?: string + key_hash?: string | null + last_used?: string | null + name?: string + } Relationships: [ { - foreignKeyName: "account_api_keys_account_fkey"; - columns: ["account"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "account_api_keys_account_fkey" + columns: ["account"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, - ]; - }; + ] + } account_artist_ids: { Row: { - account_id: string | null; - artist_id: string | null; - id: string; - pinned: boolean; - updated_at: string | null; - }; + account_id: string | null + artist_id: string | null + id: string + pinned: boolean + updated_at: string | null + } Insert: { - account_id?: string | null; - artist_id?: string | null; - id?: string; - pinned?: boolean; - updated_at?: string | null; - }; + account_id?: string | null + artist_id?: string | null + id?: string + pinned?: boolean + updated_at?: string | null + } Update: { - account_id?: string | null; - artist_id?: string | null; - id?: string; - pinned?: boolean; - updated_at?: string | null; - }; + account_id?: string | null + artist_id?: string | null + id?: string + pinned?: boolean + updated_at?: string | null + } Relationships: [ { - foreignKeyName: "account_artist_ids_account_id_fkey"; - columns: ["account_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "account_artist_ids_account_id_fkey" + columns: ["account_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, { - foreignKeyName: "account_artist_ids_artist_id_fkey"; - columns: ["artist_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "account_artist_ids_artist_id_fkey" + columns: ["artist_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, - ]; - }; + ] + } account_catalogs: { Row: { - account: string; - catalog: string; - created_at: string; - id: string; - updated_at: string; - }; + account: string + catalog: string + created_at: string + id: string + updated_at: string + } Insert: { - account: string; - catalog: string; - created_at?: string; - id?: string; - updated_at?: string; - }; + account: string + catalog: string + created_at?: string + id?: string + updated_at?: string + } Update: { - account?: string; - catalog?: string; - created_at?: string; - id?: string; - updated_at?: string; - }; + account?: string + catalog?: string + created_at?: string + id?: string + updated_at?: string + } Relationships: [ { - foreignKeyName: "account_catalogs_account_fkey"; - columns: ["account"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "account_catalogs_account_fkey" + columns: ["account"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, { - foreignKeyName: "account_catalogs_catalog_fkey"; - columns: ["catalog"]; - isOneToOne: false; - referencedRelation: "catalogs"; - referencedColumns: ["id"]; + foreignKeyName: "account_catalogs_catalog_fkey" + columns: ["catalog"] + isOneToOne: false + referencedRelation: "catalogs" + referencedColumns: ["id"] }, - ]; - }; + ] + } account_emails: { Row: { - account_id: string | null; - email: string | null; - id: string; - updated_at: string; - }; + account_id: string | null + email: string | null + id: string + updated_at: string + } Insert: { - account_id?: string | null; - email?: string | null; - id?: string; - updated_at?: string; - }; + account_id?: string | null + email?: string | null + id?: string + updated_at?: string + } Update: { - account_id?: string | null; - email?: string | null; - id?: string; - updated_at?: string; - }; + account_id?: string | null + email?: string | null + id?: string + updated_at?: string + } Relationships: [ { - foreignKeyName: "account_emails_account_id_fkey"; - columns: ["account_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "account_emails_account_id_fkey" + columns: ["account_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, - ]; - }; + ] + } account_info: { Row: { - account_id: string | null; - company_name: string | null; - id: string; - image: string | null; - instruction: string | null; - job_title: string | null; - knowledges: Json | null; - label: string | null; - organization: string | null; - role_type: string | null; - updated_at: string; - }; + account_id: string | null + company_name: string | null + id: string + image: string | null + instruction: string | null + job_title: string | null + knowledges: Json | null + label: string | null + organization: string | null + role_type: string | null + updated_at: string + } Insert: { - account_id?: string | null; - company_name?: string | null; - id?: string; - image?: string | null; - instruction?: string | null; - job_title?: string | null; - knowledges?: Json | null; - label?: string | null; - organization?: string | null; - role_type?: string | null; - updated_at?: string; - }; + account_id?: string | null + company_name?: string | null + id?: string + image?: string | null + instruction?: string | null + job_title?: string | null + knowledges?: Json | null + label?: string | null + organization?: string | null + role_type?: string | null + updated_at?: string + } Update: { - account_id?: string | null; - company_name?: string | null; - id?: string; - image?: string | null; - instruction?: string | null; - job_title?: string | null; - knowledges?: Json | null; - label?: string | null; - organization?: string | null; - role_type?: string | null; - updated_at?: string; - }; + account_id?: string | null + company_name?: string | null + id?: string + image?: string | null + instruction?: string | null + job_title?: string | null + knowledges?: Json | null + label?: string | null + organization?: string | null + role_type?: string | null + updated_at?: string + } Relationships: [ { - foreignKeyName: "account_info_account_id_fkey"; - columns: ["account_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "account_info_account_id_fkey" + columns: ["account_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, - ]; - }; + ] + } account_organization_ids: { Row: { - account_id: string | null; - id: string; - organization_id: string | null; - updated_at: string | null; - }; + account_id: string | null + id: string + organization_id: string | null + updated_at: string | null + } Insert: { - account_id?: string | null; - id?: string; - organization_id?: string | null; - updated_at?: string | null; - }; + account_id?: string | null + id?: string + organization_id?: string | null + updated_at?: string | null + } Update: { - account_id?: string | null; - id?: string; - organization_id?: string | null; - updated_at?: string | null; - }; + account_id?: string | null + id?: string + organization_id?: string | null + updated_at?: string | null + } Relationships: [ { - foreignKeyName: "account_organization_ids_account_id_fkey"; - columns: ["account_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "account_organization_ids_account_id_fkey" + columns: ["account_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, { - foreignKeyName: "account_organization_ids_organization_id_fkey"; - columns: ["organization_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "account_organization_ids_organization_id_fkey" + columns: ["organization_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, - ]; - }; + ] + } account_phone_numbers: { Row: { - account_id: string; - id: string; - phone_number: string; - updated_at: string | null; - }; + account_id: string + id: string + phone_number: string + updated_at: string | null + } Insert: { - account_id: string; - id?: string; - phone_number: string; - updated_at?: string | null; - }; + account_id: string + id?: string + phone_number: string + updated_at?: string | null + } Update: { - account_id?: string; - id?: string; - phone_number?: string; - updated_at?: string | null; - }; + account_id?: string + id?: string + phone_number?: string + updated_at?: string | null + } Relationships: [ { - foreignKeyName: "account_phone_numbers_account_id_fkey"; - columns: ["account_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "account_phone_numbers_account_id_fkey" + columns: ["account_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, - ]; - }; + ] + } account_sandboxes: { Row: { - account_id: string; - created_at: string; - id: string; - sandbox_id: string; - }; + account_id: string + created_at: string + id: string + sandbox_id: string + } Insert: { - account_id: string; - created_at?: string; - id?: string; - sandbox_id: string; - }; + account_id: string + created_at?: string + id?: string + sandbox_id: string + } Update: { - account_id?: string; - created_at?: string; - id?: string; - sandbox_id?: string; - }; + account_id?: string + created_at?: string + id?: string + sandbox_id?: string + } Relationships: [ { - foreignKeyName: "account_sandboxes_account_id_fkey"; - columns: ["account_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "account_sandboxes_account_id_fkey" + columns: ["account_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, - ]; - }; + ] + } account_snapshots: { Row: { - account_id: string; - created_at: string | null; - expires_at: string | null; - github_repo: string | null; - snapshot_id: string | null; - }; + account_id: string + created_at: string | null + expires_at: string | null + github_repo: string | null + snapshot_id: string | null + } Insert: { - account_id: string; - created_at?: string | null; - expires_at?: string | null; - github_repo?: string | null; - snapshot_id?: string | null; - }; + account_id: string + created_at?: string | null + expires_at?: string | null + github_repo?: string | null + snapshot_id?: string | null + } Update: { - account_id?: string; - created_at?: string | null; - expires_at?: string | null; - github_repo?: string | null; - snapshot_id?: string | null; - }; + account_id?: string + created_at?: string | null + expires_at?: string | null + github_repo?: string | null + snapshot_id?: string | null + } Relationships: [ { - foreignKeyName: "account_snapshots_account_id_fkey"; - columns: ["account_id"]; - isOneToOne: true; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "account_snapshots_account_id_fkey" + columns: ["account_id"] + isOneToOne: true + referencedRelation: "accounts" + referencedColumns: ["id"] }, - ]; - }; + ] + } account_socials: { Row: { - account_id: string | null; - id: string; - social_id: string; - }; + account_id: string | null + id: string + social_id: string + } Insert: { - account_id?: string | null; - id?: string; - social_id?: string; - }; + account_id?: string | null + id?: string + social_id?: string + } Update: { - account_id?: string | null; - id?: string; - social_id?: string; - }; + account_id?: string | null + id?: string + social_id?: string + } Relationships: [ { - foreignKeyName: "account_socials_account_id_fkey"; - columns: ["account_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "account_socials_account_id_fkey" + columns: ["account_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, { - foreignKeyName: "account_socials_social_id_fkey"; - columns: ["social_id"]; - isOneToOne: false; - referencedRelation: "socials"; - referencedColumns: ["id"]; + foreignKeyName: "account_socials_social_id_fkey" + columns: ["social_id"] + isOneToOne: false + referencedRelation: "socials" + referencedColumns: ["id"] }, - ]; - }; + ] + } account_wallets: { Row: { - account_id: string; - id: string; - updated_at: string | null; - wallet: string; - }; + account_id: string + id: string + updated_at: string | null + wallet: string + } Insert: { - account_id: string; - id?: string; - updated_at?: string | null; - wallet: string; - }; + account_id: string + id?: string + updated_at?: string | null + wallet: string + } Update: { - account_id?: string; - id?: string; - updated_at?: string | null; - wallet?: string; - }; + account_id?: string + id?: string + updated_at?: string | null + wallet?: string + } Relationships: [ { - foreignKeyName: "account_wallets_account_id_fkey"; - columns: ["account_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "account_wallets_account_id_fkey" + columns: ["account_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, - ]; - }; + ] + } account_workspace_ids: { Row: { - account_id: string | null; - id: string; - updated_at: string | null; - workspace_id: string | null; - }; + account_id: string | null + id: string + updated_at: string | null + workspace_id: string | null + } Insert: { - account_id?: string | null; - id?: string; - updated_at?: string | null; - workspace_id?: string | null; - }; + account_id?: string | null + id?: string + updated_at?: string | null + workspace_id?: string | null + } Update: { - account_id?: string | null; - id?: string; - updated_at?: string | null; - workspace_id?: string | null; - }; + account_id?: string | null + id?: string + updated_at?: string | null + workspace_id?: string | null + } Relationships: [ { - foreignKeyName: "account_workspace_ids_account_id_fkey"; - columns: ["account_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "account_workspace_ids_account_id_fkey" + columns: ["account_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, { - foreignKeyName: "account_workspace_ids_workspace_id_fkey"; - columns: ["workspace_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "account_workspace_ids_workspace_id_fkey" + columns: ["workspace_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, - ]; - }; + ] + } accounts: { Row: { - id: string; - name: string | null; - timestamp: number | null; - }; + id: string + name: string | null + timestamp: number | null + } Insert: { - id?: string; - name?: string | null; - timestamp?: number | null; - }; + id?: string + name?: string | null + timestamp?: number | null + } Update: { - id?: string; - name?: string | null; - timestamp?: number | null; - }; - Relationships: []; - }; + id?: string + name?: string | null + timestamp?: number | null + } + Relationships: [] + } accounts_memberships: { Row: { - account_id: string; - account_role: string; - created_at: string; - created_by: string | null; - updated_at: string; - updated_by: string | null; - user_id: string; - }; + account_id: string + account_role: string + created_at: string + created_by: string | null + updated_at: string + updated_by: string | null + user_id: string + } Insert: { - account_id: string; - account_role: string; - created_at?: string; - created_by?: string | null; - updated_at?: string; - updated_by?: string | null; - user_id: string; - }; + account_id: string + account_role: string + created_at?: string + created_by?: string | null + updated_at?: string + updated_by?: string | null + user_id: string + } Update: { - account_id?: string; - account_role?: string; - created_at?: string; - created_by?: string | null; - updated_at?: string; - updated_by?: string | null; - user_id?: string; - }; + account_id?: string + account_role?: string + created_at?: string + created_by?: string | null + updated_at?: string + updated_by?: string | null + user_id?: string + } Relationships: [ { - foreignKeyName: "accounts_memberships_account_role_fkey"; - columns: ["account_role"]; - isOneToOne: false; - referencedRelation: "roles"; - referencedColumns: ["name"]; + foreignKeyName: "accounts_memberships_account_role_fkey" + columns: ["account_role"] + isOneToOne: false + referencedRelation: "roles" + referencedColumns: ["name"] }, - ]; - }; + ] + } admin_expenses: { Row: { - amount: number; - category: string; - created_at: string | null; - created_by: string | null; - id: string; - is_active: boolean | null; - item_name: string; - updated_at: string | null; - }; + amount: number + category: string + created_at: string | null + created_by: string | null + id: string + is_active: boolean | null + item_name: string + updated_at: string | null + } Insert: { - amount?: number; - category: string; - created_at?: string | null; - created_by?: string | null; - id?: string; - is_active?: boolean | null; - item_name: string; - updated_at?: string | null; - }; + amount?: number + category: string + created_at?: string | null + created_by?: string | null + id?: string + is_active?: boolean | null + item_name: string + updated_at?: string | null + } Update: { - amount?: number; - category?: string; - created_at?: string | null; - created_by?: string | null; - id?: string; - is_active?: boolean | null; - item_name?: string; - updated_at?: string | null; - }; - Relationships: []; - }; + amount?: number + category?: string + created_at?: string | null + created_by?: string | null + id?: string + is_active?: boolean | null + item_name?: string + updated_at?: string | null + } + Relationships: [] + } admin_user_profiles: { Row: { - company: string | null; - context_notes: string | null; - created_at: string | null; - email: string; - id: string; - job_title: string | null; - last_contact_date: string | null; - meeting_notes: string | null; - observations: string | null; - opportunities: string | null; - pain_points: string | null; - sentiment: string | null; - tags: string[] | null; - updated_at: string | null; - }; + company: string | null + context_notes: string | null + created_at: string | null + email: string + id: string + job_title: string | null + last_contact_date: string | null + meeting_notes: string | null + observations: string | null + opportunities: string | null + pain_points: string | null + sentiment: string | null + tags: string[] | null + updated_at: string | null + } Insert: { - company?: string | null; - context_notes?: string | null; - created_at?: string | null; - email: string; - id?: string; - job_title?: string | null; - last_contact_date?: string | null; - meeting_notes?: string | null; - observations?: string | null; - opportunities?: string | null; - pain_points?: string | null; - sentiment?: string | null; - tags?: string[] | null; - updated_at?: string | null; - }; + company?: string | null + context_notes?: string | null + created_at?: string | null + email: string + id?: string + job_title?: string | null + last_contact_date?: string | null + meeting_notes?: string | null + observations?: string | null + opportunities?: string | null + pain_points?: string | null + sentiment?: string | null + tags?: string[] | null + updated_at?: string | null + } Update: { - company?: string | null; - context_notes?: string | null; - created_at?: string | null; - email?: string; - id?: string; - job_title?: string | null; - last_contact_date?: string | null; - meeting_notes?: string | null; - observations?: string | null; - opportunities?: string | null; - pain_points?: string | null; - sentiment?: string | null; - tags?: string[] | null; - updated_at?: string | null; - }; - Relationships: []; - }; + company?: string | null + context_notes?: string | null + created_at?: string | null + email?: string + id?: string + job_title?: string | null + last_contact_date?: string | null + meeting_notes?: string | null + observations?: string | null + opportunities?: string | null + pain_points?: string | null + sentiment?: string | null + tags?: string[] | null + updated_at?: string | null + } + Relationships: [] + } agent_status: { Row: { - agent_id: string; - id: string; - progress: number | null; - social_id: string; - status: number | null; - updated_at: string; - }; + agent_id: string + id: string + progress: number | null + social_id: string + status: number | null + updated_at: string + } Insert: { - agent_id?: string; - id?: string; - progress?: number | null; - social_id: string; - status?: number | null; - updated_at?: string; - }; + agent_id?: string + id?: string + progress?: number | null + social_id: string + status?: number | null + updated_at?: string + } Update: { - agent_id?: string; - id?: string; - progress?: number | null; - social_id?: string; - status?: number | null; - updated_at?: string; - }; + agent_id?: string + id?: string + progress?: number | null + social_id?: string + status?: number | null + updated_at?: string + } Relationships: [ { - foreignKeyName: "agent_status_agent_id_fkey"; - columns: ["agent_id"]; - isOneToOne: false; - referencedRelation: "agents"; - referencedColumns: ["id"]; + foreignKeyName: "agent_status_agent_id_fkey" + columns: ["agent_id"] + isOneToOne: false + referencedRelation: "agents" + referencedColumns: ["id"] }, { - foreignKeyName: "agent_status_social_id_fkey"; - columns: ["social_id"]; - isOneToOne: false; - referencedRelation: "socials"; - referencedColumns: ["id"]; + foreignKeyName: "agent_status_social_id_fkey" + columns: ["social_id"] + isOneToOne: false + referencedRelation: "socials" + referencedColumns: ["id"] }, - ]; - }; + ] + } agent_template_favorites: { Row: { - created_at: string | null; - template_id: string; - user_id: string; - }; + created_at: string | null + template_id: string + user_id: string + } Insert: { - created_at?: string | null; - template_id: string; - user_id: string; - }; + created_at?: string | null + template_id: string + user_id: string + } Update: { - created_at?: string | null; - template_id?: string; - user_id?: string; - }; + created_at?: string | null + template_id?: string + user_id?: string + } Relationships: [ { - foreignKeyName: "agent_template_favorites_template_id_fkey"; - columns: ["template_id"]; - isOneToOne: false; - referencedRelation: "agent_templates"; - referencedColumns: ["id"]; + foreignKeyName: "agent_template_favorites_template_id_fkey" + columns: ["template_id"] + isOneToOne: false + referencedRelation: "agent_templates" + referencedColumns: ["id"] }, { - foreignKeyName: "agent_template_favorites_user_id_fkey"; - columns: ["user_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "agent_template_favorites_user_id_fkey" + columns: ["user_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, - ]; - }; + ] + } agent_template_shares: { Row: { - created_at: string | null; - template_id: string; - user_id: string; - }; + created_at: string | null + template_id: string + user_id: string + } Insert: { - created_at?: string | null; - template_id: string; - user_id: string; - }; + created_at?: string | null + template_id: string + user_id: string + } Update: { - created_at?: string | null; - template_id?: string; - user_id?: string; - }; + created_at?: string | null + template_id?: string + user_id?: string + } Relationships: [ { - foreignKeyName: "agent_template_shares_template_id_fkey"; - columns: ["template_id"]; - isOneToOne: false; - referencedRelation: "agent_templates"; - referencedColumns: ["id"]; + foreignKeyName: "agent_template_shares_template_id_fkey" + columns: ["template_id"] + isOneToOne: false + referencedRelation: "agent_templates" + referencedColumns: ["id"] }, { - foreignKeyName: "agent_template_shares_user_id_fkey"; - columns: ["user_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "agent_template_shares_user_id_fkey" + columns: ["user_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, - ]; - }; + ] + } agent_templates: { Row: { - created_at: string; - creator: string | null; - description: string; - favorites_count: number; - id: string; - is_private: boolean; - prompt: string; - tags: string[]; - title: string; - updated_at: string | null; - }; + created_at: string + creator: string | null + description: string + favorites_count: number + id: string + is_private: boolean + prompt: string + tags: string[] + title: string + updated_at: string | null + } Insert: { - created_at?: string; - creator?: string | null; - description: string; - favorites_count?: number; - id?: string; - is_private?: boolean; - prompt: string; - tags?: string[]; - title: string; - updated_at?: string | null; - }; + created_at?: string + creator?: string | null + description: string + favorites_count?: number + id?: string + is_private?: boolean + prompt: string + tags?: string[] + title: string + updated_at?: string | null + } Update: { - created_at?: string; - creator?: string | null; - description?: string; - favorites_count?: number; - id?: string; - is_private?: boolean; - prompt?: string; - tags?: string[]; - title?: string; - updated_at?: string | null; - }; + created_at?: string + creator?: string | null + description?: string + favorites_count?: number + id?: string + is_private?: boolean + prompt?: string + tags?: string[] + title?: string + updated_at?: string | null + } Relationships: [ { - foreignKeyName: "agent_templates_creator_fkey"; - columns: ["creator"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "agent_templates_creator_fkey" + columns: ["creator"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, - ]; - }; + ] + } agents: { Row: { - id: string; - updated_at: string; - }; + id: string + updated_at: string + } Insert: { - id?: string; - updated_at?: string; - }; + id?: string + updated_at?: string + } Update: { - id?: string; - updated_at?: string; - }; - Relationships: []; - }; + id?: string + updated_at?: string + } + Relationships: [] + } app_store_link_clicked: { Row: { - clientId: string | null; - id: string | null; - timestamp: number | null; - }; + clientId: string | null + id: string | null + timestamp: number | null + } Insert: { - clientId?: string | null; - id?: string | null; - timestamp?: number | null; - }; + clientId?: string | null + id?: string | null + timestamp?: number | null + } Update: { - clientId?: string | null; - id?: string | null; - timestamp?: number | null; - }; - Relationships: []; - }; + clientId?: string | null + id?: string | null + timestamp?: number | null + } + Relationships: [] + } apple_login_button_clicked: { Row: { - campaignId: string | null; - clientId: string | null; - fanId: string | null; - game: string | null; - id: string | null; - timestamp: number | null; - }; + campaignId: string | null + clientId: string | null + fanId: string | null + game: string | null + id: string | null + timestamp: number | null + } Insert: { - campaignId?: string | null; - clientId?: string | null; - fanId?: string | null; - game?: string | null; - id?: string | null; - timestamp?: number | null; - }; + campaignId?: string | null + clientId?: string | null + fanId?: string | null + game?: string | null + id?: string | null + timestamp?: number | null + } Update: { - campaignId?: string | null; - clientId?: string | null; - fanId?: string | null; - game?: string | null; - id?: string | null; - timestamp?: number | null; - }; + campaignId?: string | null + clientId?: string | null + fanId?: string | null + game?: string | null + id?: string | null + timestamp?: number | null + } Relationships: [ { - foreignKeyName: "apple_login_button_clicked_campaignId_fkey"; - columns: ["campaignId"]; - isOneToOne: false; - referencedRelation: "campaigns"; - referencedColumns: ["id"]; + foreignKeyName: "apple_login_button_clicked_campaignId_fkey" + columns: ["campaignId"] + isOneToOne: false + referencedRelation: "campaigns" + referencedColumns: ["id"] }, - ]; - }; + ] + } apple_music: { Row: { - fanId: string | null; - game: string | null; - id: string | null; - syncid: string | null; - syncId: string | null; - timestamp: number | null; - }; + fanId: string | null + game: string | null + id: string | null + syncid: string | null + syncId: string | null + timestamp: number | null + } Insert: { - fanId?: string | null; - game?: string | null; - id?: string | null; - syncid?: string | null; - syncId?: string | null; - timestamp?: number | null; - }; + fanId?: string | null + game?: string | null + id?: string | null + syncid?: string | null + syncId?: string | null + timestamp?: number | null + } Update: { - fanId?: string | null; - game?: string | null; - id?: string | null; - syncid?: string | null; - syncId?: string | null; - timestamp?: number | null; - }; - Relationships: []; - }; + fanId?: string | null + game?: string | null + id?: string | null + syncid?: string | null + syncId?: string | null + timestamp?: number | null + } + Relationships: [] + } apple_play_button_clicked: { Row: { - appleId: string | null; - campaignId: string | null; - clientId: string | null; - fanId: string | null; - game: string | null; - id: string; - timestamp: number | null; - }; + appleId: string | null + campaignId: string | null + clientId: string | null + fanId: string | null + game: string | null + id: string + timestamp: number | null + } Insert: { - appleId?: string | null; - campaignId?: string | null; - clientId?: string | null; - fanId?: string | null; - game?: string | null; - id?: string; - timestamp?: number | null; - }; + appleId?: string | null + campaignId?: string | null + clientId?: string | null + fanId?: string | null + game?: string | null + id?: string + timestamp?: number | null + } Update: { - appleId?: string | null; - campaignId?: string | null; - clientId?: string | null; - fanId?: string | null; - game?: string | null; - id?: string; - timestamp?: number | null; - }; + appleId?: string | null + campaignId?: string | null + clientId?: string | null + fanId?: string | null + game?: string | null + id?: string + timestamp?: number | null + } Relationships: [ { - foreignKeyName: "apple_play_button_clicked_campaignId_fkey"; - columns: ["campaignId"]; - isOneToOne: false; - referencedRelation: "campaigns"; - referencedColumns: ["id"]; + foreignKeyName: "apple_play_button_clicked_campaignId_fkey" + columns: ["campaignId"] + isOneToOne: false + referencedRelation: "campaigns" + referencedColumns: ["id"] }, - ]; - }; + ] + } artist_fan_segment: { Row: { - artist_social_id: string | null; - fan_social_id: string | null; - id: string; - segment_name: string | null; - updated_at: string; - }; + artist_social_id: string | null + fan_social_id: string | null + id: string + segment_name: string | null + updated_at: string + } Insert: { - artist_social_id?: string | null; - fan_social_id?: string | null; - id?: string; - segment_name?: string | null; - updated_at?: string; - }; + artist_social_id?: string | null + fan_social_id?: string | null + id?: string + segment_name?: string | null + updated_at?: string + } Update: { - artist_social_id?: string | null; - fan_social_id?: string | null; - id?: string; - segment_name?: string | null; - updated_at?: string; - }; + artist_social_id?: string | null + fan_social_id?: string | null + id?: string + segment_name?: string | null + updated_at?: string + } Relationships: [ { - foreignKeyName: "artist_fan_segment_artist_social_id_fkey"; - columns: ["artist_social_id"]; - isOneToOne: false; - referencedRelation: "socials"; - referencedColumns: ["id"]; + foreignKeyName: "artist_fan_segment_artist_social_id_fkey" + columns: ["artist_social_id"] + isOneToOne: false + referencedRelation: "socials" + referencedColumns: ["id"] }, { - foreignKeyName: "artist_fan_segment_fan_social_id_fkey"; - columns: ["fan_social_id"]; - isOneToOne: false; - referencedRelation: "socials"; - referencedColumns: ["id"]; + foreignKeyName: "artist_fan_segment_fan_social_id_fkey" + columns: ["fan_social_id"] + isOneToOne: false + referencedRelation: "socials" + referencedColumns: ["id"] }, - ]; - }; + ] + } artist_organization_ids: { Row: { - artist_id: string; - created_at: string | null; - id: string; - organization_id: string; - updated_at: string | null; - }; + artist_id: string + created_at: string | null + id: string + organization_id: string + updated_at: string | null + } Insert: { - artist_id: string; - created_at?: string | null; - id?: string; - organization_id: string; - updated_at?: string | null; - }; + artist_id: string + created_at?: string | null + id?: string + organization_id: string + updated_at?: string | null + } Update: { - artist_id?: string; - created_at?: string | null; - id?: string; - organization_id?: string; - updated_at?: string | null; - }; + artist_id?: string + created_at?: string | null + id?: string + organization_id?: string + updated_at?: string | null + } Relationships: [ { - foreignKeyName: "artist_organization_ids_artist_id_fkey"; - columns: ["artist_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "artist_organization_ids_artist_id_fkey" + columns: ["artist_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, { - foreignKeyName: "artist_organization_ids_organization_id_fkey"; - columns: ["organization_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "artist_organization_ids_organization_id_fkey" + columns: ["organization_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, - ]; - }; + ] + } artist_segments: { Row: { - artist_account_id: string; - id: string; - segment_id: string; - updated_at: string | null; - }; + artist_account_id: string + id: string + segment_id: string + updated_at: string | null + } Insert: { - artist_account_id: string; - id?: string; - segment_id: string; - updated_at?: string | null; - }; + artist_account_id: string + id?: string + segment_id: string + updated_at?: string | null + } Update: { - artist_account_id?: string; - id?: string; - segment_id?: string; - updated_at?: string | null; - }; + artist_account_id?: string + id?: string + segment_id?: string + updated_at?: string | null + } Relationships: [ { - foreignKeyName: "artist_segments_artist_account_id_fkey"; - columns: ["artist_account_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "artist_segments_artist_account_id_fkey" + columns: ["artist_account_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, { - foreignKeyName: "artist_segments_segment_id_fkey"; - columns: ["segment_id"]; - isOneToOne: false; - referencedRelation: "segments"; - referencedColumns: ["id"]; + foreignKeyName: "artist_segments_segment_id_fkey" + columns: ["segment_id"] + isOneToOne: false + referencedRelation: "segments" + referencedColumns: ["id"] }, - ]; - }; + ] + } billing_customers: { Row: { - account_id: string; - customer_id: string; - email: string | null; - id: number; - provider: Database["public"]["Enums"]["billing_provider"]; - }; + account_id: string + customer_id: string + email: string | null + id: number + provider: Database["public"]["Enums"]["billing_provider"] + } Insert: { - account_id: string; - customer_id: string; - email?: string | null; - id?: number; - provider: Database["public"]["Enums"]["billing_provider"]; - }; + account_id: string + customer_id: string + email?: string | null + id?: number + provider: Database["public"]["Enums"]["billing_provider"] + } Update: { - account_id?: string; - customer_id?: string; - email?: string | null; - id?: number; - provider?: Database["public"]["Enums"]["billing_provider"]; - }; - Relationships: []; - }; + account_id?: string + customer_id?: string + email?: string | null + id?: number + provider?: Database["public"]["Enums"]["billing_provider"] + } + Relationships: [] + } campaigns: { Row: { - artist_id: string | null; - clientId: string | null; - id: string; - timestamp: number | null; - }; + artist_id: string | null + clientId: string | null + id: string + timestamp: number | null + } Insert: { - artist_id?: string | null; - clientId?: string | null; - id?: string; - timestamp?: number | null; - }; + artist_id?: string | null + clientId?: string | null + id?: string + timestamp?: number | null + } Update: { - artist_id?: string | null; - clientId?: string | null; - id?: string; - timestamp?: number | null; - }; + artist_id?: string | null + clientId?: string | null + id?: string + timestamp?: number | null + } Relationships: [ { - foreignKeyName: "campaigns_artist_id_fkey"; - columns: ["artist_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "campaigns_artist_id_fkey" + columns: ["artist_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, - ]; - }; + ] + } catalog_songs: { Row: { - catalog: string; - created_at: string; - id: string; - song: string; - updated_at: string; - }; + catalog: string + created_at: string + id: string + song: string + updated_at: string + } Insert: { - catalog: string; - created_at?: string; - id?: string; - song: string; - updated_at?: string; - }; + catalog: string + created_at?: string + id?: string + song: string + updated_at?: string + } Update: { - catalog?: string; - created_at?: string; - id?: string; - song?: string; - updated_at?: string; - }; + catalog?: string + created_at?: string + id?: string + song?: string + updated_at?: string + } Relationships: [ { - foreignKeyName: "catalog_songs_catalog_fkey"; - columns: ["catalog"]; - isOneToOne: false; - referencedRelation: "catalogs"; - referencedColumns: ["id"]; + foreignKeyName: "catalog_songs_catalog_fkey" + columns: ["catalog"] + isOneToOne: false + referencedRelation: "catalogs" + referencedColumns: ["id"] }, { - foreignKeyName: "catalog_songs_song_fkey"; - columns: ["song"]; - isOneToOne: false; - referencedRelation: "songs"; - referencedColumns: ["isrc"]; + foreignKeyName: "catalog_songs_song_fkey" + columns: ["song"] + isOneToOne: false + referencedRelation: "songs" + referencedColumns: ["isrc"] }, - ]; - }; + ] + } catalogs: { Row: { - created_at: string; - id: string; - name: string; - updated_at: string; - }; + created_at: string + id: string + name: string + updated_at: string + } Insert: { - created_at?: string; - id?: string; - name: string; - updated_at?: string; - }; + created_at?: string + id?: string + name: string + updated_at?: string + } Update: { - created_at?: string; - id?: string; - name?: string; - updated_at?: string; - }; - Relationships: []; - }; + created_at?: string + id?: string + name?: string + updated_at?: string + } + Relationships: [] + } chat_messages: { Row: { - chat_id: string; - created_at: string; - id: string; - parts: Json; - role: string; - }; + chat_id: string + created_at: string + id: string + parts: Json + role: string + } Insert: { - chat_id: string; - created_at?: string; - id: string; - parts: Json; - role: string; - }; + chat_id: string + created_at?: string + id: string + parts: Json + role: string + } Update: { - chat_id?: string; - created_at?: string; - id?: string; - parts?: Json; - role?: string; - }; + chat_id?: string + created_at?: string + id?: string + parts?: Json + role?: string + } Relationships: [ { - foreignKeyName: "chat_messages_chat_id_fkey"; - columns: ["chat_id"]; - isOneToOne: false; - referencedRelation: "chats"; - referencedColumns: ["id"]; + foreignKeyName: "chat_messages_chat_id_fkey" + columns: ["chat_id"] + isOneToOne: false + referencedRelation: "chats" + referencedColumns: ["id"] }, - ]; - }; + ] + } chat_reads: { Row: { - account_id: string; - chat_id: string; - created_at: string; - last_read_at: string; - updated_at: string; - }; + account_id: string + chat_id: string + created_at: string + last_read_at: string + updated_at: string + } Insert: { - account_id: string; - chat_id: string; - created_at?: string; - last_read_at?: string; - updated_at?: string; - }; + account_id: string + chat_id: string + created_at?: string + last_read_at?: string + updated_at?: string + } Update: { - account_id?: string; - chat_id?: string; - created_at?: string; - last_read_at?: string; - updated_at?: string; - }; + account_id?: string + chat_id?: string + created_at?: string + last_read_at?: string + updated_at?: string + } Relationships: [ { - foreignKeyName: "chat_reads_account_id_fkey"; - columns: ["account_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "chat_reads_account_id_fkey" + columns: ["account_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, { - foreignKeyName: "chat_reads_chat_id_fkey"; - columns: ["chat_id"]; - isOneToOne: false; - referencedRelation: "chats"; - referencedColumns: ["id"]; + foreignKeyName: "chat_reads_chat_id_fkey" + columns: ["chat_id"] + isOneToOne: false + referencedRelation: "chats" + referencedColumns: ["id"] }, - ]; - }; + ] + } chats: { Row: { - active_stream_id: string | null; - created_at: string; - id: string; - last_assistant_message_at: string | null; - model_id: string | null; - session_id: string; - title: string; - updated_at: string; - }; + active_stream_id: string | null + created_at: string + id: string + last_assistant_message_at: string | null + model_id: string | null + session_id: string + title: string + updated_at: string + } Insert: { - active_stream_id?: string | null; - created_at?: string; - id: string; - last_assistant_message_at?: string | null; - model_id?: string | null; - session_id: string; - title: string; - updated_at?: string; - }; + active_stream_id?: string | null + created_at?: string + id: string + last_assistant_message_at?: string | null + model_id?: string | null + session_id: string + title: string + updated_at?: string + } Update: { - active_stream_id?: string | null; - created_at?: string; - id?: string; - last_assistant_message_at?: string | null; - model_id?: string | null; - session_id?: string; - title?: string; - updated_at?: string; - }; + active_stream_id?: string | null + created_at?: string + id?: string + last_assistant_message_at?: string | null + model_id?: string | null + session_id?: string + title?: string + updated_at?: string + } Relationships: [ { - foreignKeyName: "chats_session_id_fkey"; - columns: ["session_id"]; - isOneToOne: false; - referencedRelation: "sessions"; - referencedColumns: ["id"]; + foreignKeyName: "chats_session_id_fkey" + columns: ["session_id"] + isOneToOne: false + referencedRelation: "sessions" + referencedColumns: ["id"] }, - ]; - }; + ] + } config: { Row: { - billing_provider: Database["public"]["Enums"]["billing_provider"]; - enable_account_billing: boolean; - enable_team_account_billing: boolean; - enable_team_accounts: boolean; - }; + billing_provider: Database["public"]["Enums"]["billing_provider"] + enable_account_billing: boolean + enable_team_account_billing: boolean + enable_team_accounts: boolean + } Insert: { - billing_provider?: Database["public"]["Enums"]["billing_provider"]; - enable_account_billing?: boolean; - enable_team_account_billing?: boolean; - enable_team_accounts?: boolean; - }; + billing_provider?: Database["public"]["Enums"]["billing_provider"] + enable_account_billing?: boolean + enable_team_account_billing?: boolean + enable_team_accounts?: boolean + } Update: { - billing_provider?: Database["public"]["Enums"]["billing_provider"]; - enable_account_billing?: boolean; - enable_team_account_billing?: boolean; - enable_team_accounts?: boolean; - }; - Relationships: []; - }; + billing_provider?: Database["public"]["Enums"]["billing_provider"] + enable_account_billing?: boolean + enable_team_account_billing?: boolean + enable_team_accounts?: boolean + } + Relationships: [] + } cookie_players: { Row: { - game: string | null; - id: string | null; - timestamp: number | null; - uniquePlayerID: string | null; - }; + game: string | null + id: string | null + timestamp: number | null + uniquePlayerID: string | null + } Insert: { - game?: string | null; - id?: string | null; - timestamp?: number | null; - uniquePlayerID?: string | null; - }; + game?: string | null + id?: string | null + timestamp?: number | null + uniquePlayerID?: string | null + } Update: { - game?: string | null; - id?: string | null; - timestamp?: number | null; - uniquePlayerID?: string | null; - }; - Relationships: []; - }; + game?: string | null + id?: string | null + timestamp?: number | null + uniquePlayerID?: string | null + } + Relationships: [] + } credits_usage: { Row: { - account_id: string; - id: number; - remaining_credits: number; - timestamp: string | null; - }; + account_id: string + id: number + remaining_credits: number + timestamp: string | null + } Insert: { - account_id: string; - id?: number; - remaining_credits?: number; - timestamp?: string | null; - }; + account_id: string + id?: number + remaining_credits?: number + timestamp?: string | null + } Update: { - account_id?: string; - id?: number; - remaining_credits?: number; - timestamp?: string | null; - }; + account_id?: string + id?: number + remaining_credits?: number + timestamp?: string | null + } Relationships: [ { - foreignKeyName: "credits_usage_account_id_fkey"; - columns: ["account_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "credits_usage_account_id_fkey" + columns: ["account_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, - ]; - }; + ] + } cta_redirect: { Row: { - clientId: string; - id: number; - timestamp: string | null; - url: string | null; - }; + clientId: string + id: number + timestamp: string | null + url: string | null + } Insert: { - clientId: string; - id?: number; - timestamp?: string | null; - url?: string | null; - }; + clientId: string + id?: number + timestamp?: string | null + url?: string | null + } Update: { - clientId?: string; - id?: number; - timestamp?: string | null; - url?: string | null; - }; - Relationships: []; - }; + clientId?: string + id?: number + timestamp?: string | null + url?: string | null + } + Relationships: [] + } error_logs: { Row: { - account_id: string | null; - created_at: string; - error_message: string | null; - error_timestamp: string | null; - error_type: string | null; - id: string; - last_message: string | null; - raw_message: string; - room_id: string | null; - stack_trace: string | null; - telegram_message_id: number | null; - tool_name: string | null; - }; + account_id: string | null + created_at: string + error_message: string | null + error_timestamp: string | null + error_type: string | null + id: string + last_message: string | null + raw_message: string + room_id: string | null + stack_trace: string | null + telegram_message_id: number | null + tool_name: string | null + } Insert: { - account_id?: string | null; - created_at?: string; - error_message?: string | null; - error_timestamp?: string | null; - error_type?: string | null; - id?: string; - last_message?: string | null; - raw_message: string; - room_id?: string | null; - stack_trace?: string | null; - telegram_message_id?: number | null; - tool_name?: string | null; - }; + account_id?: string | null + created_at?: string + error_message?: string | null + error_timestamp?: string | null + error_type?: string | null + id?: string + last_message?: string | null + raw_message: string + room_id?: string | null + stack_trace?: string | null + telegram_message_id?: number | null + tool_name?: string | null + } Update: { - account_id?: string | null; - created_at?: string; - error_message?: string | null; - error_timestamp?: string | null; - error_type?: string | null; - id?: string; - last_message?: string | null; - raw_message?: string; - room_id?: string | null; - stack_trace?: string | null; - telegram_message_id?: number | null; - tool_name?: string | null; - }; + account_id?: string | null + created_at?: string + error_message?: string | null + error_timestamp?: string | null + error_type?: string | null + id?: string + last_message?: string | null + raw_message?: string + room_id?: string | null + stack_trace?: string | null + telegram_message_id?: number | null + tool_name?: string | null + } Relationships: [ { - foreignKeyName: "error_logs_account_id_fkey"; - columns: ["account_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "error_logs_account_id_fkey" + columns: ["account_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, { - foreignKeyName: "error_logs_room_id_fkey"; - columns: ["room_id"]; - isOneToOne: false; - referencedRelation: "rooms"; - referencedColumns: ["id"]; + foreignKeyName: "error_logs_room_id_fkey" + columns: ["room_id"] + isOneToOne: false + referencedRelation: "rooms" + referencedColumns: ["id"] }, - ]; - }; + ] + } fan_segments: { Row: { - fan_social_id: string; - id: string; - segment_id: string; - updated_at: string | null; - }; + fan_social_id: string + id: string + segment_id: string + updated_at: string | null + } Insert: { - fan_social_id: string; - id?: string; - segment_id: string; - updated_at?: string | null; - }; + fan_social_id: string + id?: string + segment_id: string + updated_at?: string | null + } Update: { - fan_social_id?: string; - id?: string; - segment_id?: string; - updated_at?: string | null; - }; + fan_social_id?: string + id?: string + segment_id?: string + updated_at?: string | null + } Relationships: [ { - foreignKeyName: "fan_segments_fan_social_id_fkey"; - columns: ["fan_social_id"]; - isOneToOne: false; - referencedRelation: "socials"; - referencedColumns: ["id"]; + foreignKeyName: "fan_segments_fan_social_id_fkey" + columns: ["fan_social_id"] + isOneToOne: false + referencedRelation: "socials" + referencedColumns: ["id"] }, { - foreignKeyName: "fan_segments_segment_id_fkey"; - columns: ["segment_id"]; - isOneToOne: false; - referencedRelation: "segments"; - referencedColumns: ["id"]; + foreignKeyName: "fan_segments_segment_id_fkey" + columns: ["segment_id"] + isOneToOne: false + referencedRelation: "segments" + referencedColumns: ["id"] }, - ]; - }; + ] + } fans: { Row: { - account_status: string | null; - apple_token: string | null; - campaign_id: string | null; - campaign_interaction_count: number | null; - campaignId: string | null; - city: string | null; - click_through_rate: number | null; - clientId: string | null; - consent_given: boolean | null; - country: string | null; - custom_tags: Json | null; - discord_username: string | null; - display_name: string | null; - email: string | null; - email_open_rate: number | null; - engagement_level: string | null; - episodes: Json | null; - explicit_content_filter_enabled: boolean | null; - explicit_content_filter_locked: boolean | null; - "explicit_content.filter_enabled": boolean | null; - "explicit_content.filter_locked": boolean | null; - external_urls_spotify: string | null; - "external_urls.spotify": string | null; - facebook_profile_url: string | null; - first_stream_date: string | null; - followedArtists: Json | null; - followers_total: number | null; - "followers.href": string | null; - "followers.total": number | null; - gamification_points: number | null; - genres: Json | null; - heavyRotations: Json | null; - href: string | null; - id: string; - images: Json | null; - instagram_handle: string | null; - last_campaign_interaction: string | null; - last_login: string | null; - last_purchase_date: string | null; - last_stream_date: string | null; - linkedin_profile_url: string | null; - os_type: string | null; - playlist: Json | null; - preferences: Json | null; - preferred_artists: Json | null; - preferred_device: string | null; - product: string | null; - recentlyPlayed: Json | null; - recommendations: Json | null; - recommended_events: Json | null; - reddit_username: string | null; - saved_podcasts: Json | null; - savedAlbums: Json | null; - savedAudioBooks: Json | null; - savedShows: Json | null; - savedTracks: Json | null; - social_shares: number | null; - spotify_token: string | null; - subscription_tier: string | null; - testField: string | null; - tiktok_handle: string | null; - time_zone: string | null; - timestamp: string | null; - top_artists_long_term: Json | null; - top_artists_medium_term: Json | null; - top_tracks_long_term: Json | null; - top_tracks_medium_term: Json | null; - top_tracks_short_term: Json | null; - topArtists: Json | null; - topTracks: Json | null; - total_spent: number | null; - total_streams: number | null; - twitter_handle: string | null; - type: string | null; - uri: string | null; - youtube_channel_url: string | null; - }; + account_status: string | null + apple_token: string | null + campaign_id: string | null + campaign_interaction_count: number | null + campaignId: string | null + city: string | null + click_through_rate: number | null + clientId: string | null + consent_given: boolean | null + country: string | null + custom_tags: Json | null + discord_username: string | null + display_name: string | null + email: string | null + email_open_rate: number | null + engagement_level: string | null + episodes: Json | null + explicit_content_filter_enabled: boolean | null + explicit_content_filter_locked: boolean | null + "explicit_content.filter_enabled": boolean | null + "explicit_content.filter_locked": boolean | null + external_urls_spotify: string | null + "external_urls.spotify": string | null + facebook_profile_url: string | null + first_stream_date: string | null + followedArtists: Json | null + followers_total: number | null + "followers.href": string | null + "followers.total": number | null + gamification_points: number | null + genres: Json | null + heavyRotations: Json | null + href: string | null + id: string + images: Json | null + instagram_handle: string | null + last_campaign_interaction: string | null + last_login: string | null + last_purchase_date: string | null + last_stream_date: string | null + linkedin_profile_url: string | null + os_type: string | null + playlist: Json | null + preferences: Json | null + preferred_artists: Json | null + preferred_device: string | null + product: string | null + recentlyPlayed: Json | null + recommendations: Json | null + recommended_events: Json | null + reddit_username: string | null + saved_podcasts: Json | null + savedAlbums: Json | null + savedAudioBooks: Json | null + savedShows: Json | null + savedTracks: Json | null + social_shares: number | null + spotify_token: string | null + subscription_tier: string | null + testField: string | null + tiktok_handle: string | null + time_zone: string | null + timestamp: string | null + top_artists_long_term: Json | null + top_artists_medium_term: Json | null + top_tracks_long_term: Json | null + top_tracks_medium_term: Json | null + top_tracks_short_term: Json | null + topArtists: Json | null + topTracks: Json | null + total_spent: number | null + total_streams: number | null + twitter_handle: string | null + type: string | null + uri: string | null + youtube_channel_url: string | null + } Insert: { - account_status?: string | null; - apple_token?: string | null; - campaign_id?: string | null; - campaign_interaction_count?: number | null; - campaignId?: string | null; - city?: string | null; - click_through_rate?: number | null; - clientId?: string | null; - consent_given?: boolean | null; - country?: string | null; - custom_tags?: Json | null; - discord_username?: string | null; - display_name?: string | null; - email?: string | null; - email_open_rate?: number | null; - engagement_level?: string | null; - episodes?: Json | null; - explicit_content_filter_enabled?: boolean | null; - explicit_content_filter_locked?: boolean | null; - "explicit_content.filter_enabled"?: boolean | null; - "explicit_content.filter_locked"?: boolean | null; - external_urls_spotify?: string | null; - "external_urls.spotify"?: string | null; - facebook_profile_url?: string | null; - first_stream_date?: string | null; - followedArtists?: Json | null; - followers_total?: number | null; - "followers.href"?: string | null; - "followers.total"?: number | null; - gamification_points?: number | null; - genres?: Json | null; - heavyRotations?: Json | null; - href?: string | null; - id?: string; - images?: Json | null; - instagram_handle?: string | null; - last_campaign_interaction?: string | null; - last_login?: string | null; - last_purchase_date?: string | null; - last_stream_date?: string | null; - linkedin_profile_url?: string | null; - os_type?: string | null; - playlist?: Json | null; - preferences?: Json | null; - preferred_artists?: Json | null; - preferred_device?: string | null; - product?: string | null; - recentlyPlayed?: Json | null; - recommendations?: Json | null; - recommended_events?: Json | null; - reddit_username?: string | null; - saved_podcasts?: Json | null; - savedAlbums?: Json | null; - savedAudioBooks?: Json | null; - savedShows?: Json | null; - savedTracks?: Json | null; - social_shares?: number | null; - spotify_token?: string | null; - subscription_tier?: string | null; - testField?: string | null; - tiktok_handle?: string | null; - time_zone?: string | null; - timestamp?: string | null; - top_artists_long_term?: Json | null; - top_artists_medium_term?: Json | null; - top_tracks_long_term?: Json | null; - top_tracks_medium_term?: Json | null; - top_tracks_short_term?: Json | null; - topArtists?: Json | null; - topTracks?: Json | null; - total_spent?: number | null; - total_streams?: number | null; - twitter_handle?: string | null; - type?: string | null; - uri?: string | null; - youtube_channel_url?: string | null; - }; + account_status?: string | null + apple_token?: string | null + campaign_id?: string | null + campaign_interaction_count?: number | null + campaignId?: string | null + city?: string | null + click_through_rate?: number | null + clientId?: string | null + consent_given?: boolean | null + country?: string | null + custom_tags?: Json | null + discord_username?: string | null + display_name?: string | null + email?: string | null + email_open_rate?: number | null + engagement_level?: string | null + episodes?: Json | null + explicit_content_filter_enabled?: boolean | null + explicit_content_filter_locked?: boolean | null + "explicit_content.filter_enabled"?: boolean | null + "explicit_content.filter_locked"?: boolean | null + external_urls_spotify?: string | null + "external_urls.spotify"?: string | null + facebook_profile_url?: string | null + first_stream_date?: string | null + followedArtists?: Json | null + followers_total?: number | null + "followers.href"?: string | null + "followers.total"?: number | null + gamification_points?: number | null + genres?: Json | null + heavyRotations?: Json | null + href?: string | null + id?: string + images?: Json | null + instagram_handle?: string | null + last_campaign_interaction?: string | null + last_login?: string | null + last_purchase_date?: string | null + last_stream_date?: string | null + linkedin_profile_url?: string | null + os_type?: string | null + playlist?: Json | null + preferences?: Json | null + preferred_artists?: Json | null + preferred_device?: string | null + product?: string | null + recentlyPlayed?: Json | null + recommendations?: Json | null + recommended_events?: Json | null + reddit_username?: string | null + saved_podcasts?: Json | null + savedAlbums?: Json | null + savedAudioBooks?: Json | null + savedShows?: Json | null + savedTracks?: Json | null + social_shares?: number | null + spotify_token?: string | null + subscription_tier?: string | null + testField?: string | null + tiktok_handle?: string | null + time_zone?: string | null + timestamp?: string | null + top_artists_long_term?: Json | null + top_artists_medium_term?: Json | null + top_tracks_long_term?: Json | null + top_tracks_medium_term?: Json | null + top_tracks_short_term?: Json | null + topArtists?: Json | null + topTracks?: Json | null + total_spent?: number | null + total_streams?: number | null + twitter_handle?: string | null + type?: string | null + uri?: string | null + youtube_channel_url?: string | null + } Update: { - account_status?: string | null; - apple_token?: string | null; - campaign_id?: string | null; - campaign_interaction_count?: number | null; - campaignId?: string | null; - city?: string | null; - click_through_rate?: number | null; - clientId?: string | null; - consent_given?: boolean | null; - country?: string | null; - custom_tags?: Json | null; - discord_username?: string | null; - display_name?: string | null; - email?: string | null; - email_open_rate?: number | null; - engagement_level?: string | null; - episodes?: Json | null; - explicit_content_filter_enabled?: boolean | null; - explicit_content_filter_locked?: boolean | null; - "explicit_content.filter_enabled"?: boolean | null; - "explicit_content.filter_locked"?: boolean | null; - external_urls_spotify?: string | null; - "external_urls.spotify"?: string | null; - facebook_profile_url?: string | null; - first_stream_date?: string | null; - followedArtists?: Json | null; - followers_total?: number | null; - "followers.href"?: string | null; - "followers.total"?: number | null; - gamification_points?: number | null; - genres?: Json | null; - heavyRotations?: Json | null; - href?: string | null; - id?: string; - images?: Json | null; - instagram_handle?: string | null; - last_campaign_interaction?: string | null; - last_login?: string | null; - last_purchase_date?: string | null; - last_stream_date?: string | null; - linkedin_profile_url?: string | null; - os_type?: string | null; - playlist?: Json | null; - preferences?: Json | null; - preferred_artists?: Json | null; - preferred_device?: string | null; - product?: string | null; - recentlyPlayed?: Json | null; - recommendations?: Json | null; - recommended_events?: Json | null; - reddit_username?: string | null; - saved_podcasts?: Json | null; - savedAlbums?: Json | null; - savedAudioBooks?: Json | null; - savedShows?: Json | null; - savedTracks?: Json | null; - social_shares?: number | null; - spotify_token?: string | null; - subscription_tier?: string | null; - testField?: string | null; - tiktok_handle?: string | null; - time_zone?: string | null; - timestamp?: string | null; - top_artists_long_term?: Json | null; - top_artists_medium_term?: Json | null; - top_tracks_long_term?: Json | null; - top_tracks_medium_term?: Json | null; - top_tracks_short_term?: Json | null; - topArtists?: Json | null; - topTracks?: Json | null; - total_spent?: number | null; - total_streams?: number | null; - twitter_handle?: string | null; - type?: string | null; - uri?: string | null; - youtube_channel_url?: string | null; - }; + account_status?: string | null + apple_token?: string | null + campaign_id?: string | null + campaign_interaction_count?: number | null + campaignId?: string | null + city?: string | null + click_through_rate?: number | null + clientId?: string | null + consent_given?: boolean | null + country?: string | null + custom_tags?: Json | null + discord_username?: string | null + display_name?: string | null + email?: string | null + email_open_rate?: number | null + engagement_level?: string | null + episodes?: Json | null + explicit_content_filter_enabled?: boolean | null + explicit_content_filter_locked?: boolean | null + "explicit_content.filter_enabled"?: boolean | null + "explicit_content.filter_locked"?: boolean | null + external_urls_spotify?: string | null + "external_urls.spotify"?: string | null + facebook_profile_url?: string | null + first_stream_date?: string | null + followedArtists?: Json | null + followers_total?: number | null + "followers.href"?: string | null + "followers.total"?: number | null + gamification_points?: number | null + genres?: Json | null + heavyRotations?: Json | null + href?: string | null + id?: string + images?: Json | null + instagram_handle?: string | null + last_campaign_interaction?: string | null + last_login?: string | null + last_purchase_date?: string | null + last_stream_date?: string | null + linkedin_profile_url?: string | null + os_type?: string | null + playlist?: Json | null + preferences?: Json | null + preferred_artists?: Json | null + preferred_device?: string | null + product?: string | null + recentlyPlayed?: Json | null + recommendations?: Json | null + recommended_events?: Json | null + reddit_username?: string | null + saved_podcasts?: Json | null + savedAlbums?: Json | null + savedAudioBooks?: Json | null + savedShows?: Json | null + savedTracks?: Json | null + social_shares?: number | null + spotify_token?: string | null + subscription_tier?: string | null + testField?: string | null + tiktok_handle?: string | null + time_zone?: string | null + timestamp?: string | null + top_artists_long_term?: Json | null + top_artists_medium_term?: Json | null + top_tracks_long_term?: Json | null + top_tracks_medium_term?: Json | null + top_tracks_short_term?: Json | null + topArtists?: Json | null + topTracks?: Json | null + total_spent?: number | null + total_streams?: number | null + twitter_handle?: string | null + type?: string | null + uri?: string | null + youtube_channel_url?: string | null + } Relationships: [ { - foreignKeyName: "fans_campaignId_fkey"; - columns: ["campaignId"]; - isOneToOne: false; - referencedRelation: "campaigns"; - referencedColumns: ["id"]; + foreignKeyName: "fans_campaignId_fkey" + columns: ["campaignId"] + isOneToOne: false + referencedRelation: "campaigns" + referencedColumns: ["id"] }, - ]; - }; + ] + } files: { Row: { - artist_account_id: string; - created_at: string; - description: string | null; - file_name: string; - id: string; - is_directory: boolean; - mime_type: string | null; - owner_account_id: string; - size_bytes: number | null; - storage_key: string; - tags: string[] | null; - updated_at: string; - }; + artist_account_id: string + created_at: string + description: string | null + file_name: string + id: string + is_directory: boolean + mime_type: string | null + owner_account_id: string + size_bytes: number | null + storage_key: string + tags: string[] | null + updated_at: string + } Insert: { - artist_account_id: string; - created_at?: string; - description?: string | null; - file_name: string; - id?: string; - is_directory?: boolean; - mime_type?: string | null; - owner_account_id: string; - size_bytes?: number | null; - storage_key: string; - tags?: string[] | null; - updated_at?: string; - }; + artist_account_id: string + created_at?: string + description?: string | null + file_name: string + id?: string + is_directory?: boolean + mime_type?: string | null + owner_account_id: string + size_bytes?: number | null + storage_key: string + tags?: string[] | null + updated_at?: string + } Update: { - artist_account_id?: string; - created_at?: string; - description?: string | null; - file_name?: string; - id?: string; - is_directory?: boolean; - mime_type?: string | null; - owner_account_id?: string; - size_bytes?: number | null; - storage_key?: string; - tags?: string[] | null; - updated_at?: string; - }; + artist_account_id?: string + created_at?: string + description?: string | null + file_name?: string + id?: string + is_directory?: boolean + mime_type?: string | null + owner_account_id?: string + size_bytes?: number | null + storage_key?: string + tags?: string[] | null + updated_at?: string + } Relationships: [ { - foreignKeyName: "files_artist_account_id_fkey"; - columns: ["artist_account_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "files_artist_account_id_fkey" + columns: ["artist_account_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, { - foreignKeyName: "files_owner_account_id_fkey"; - columns: ["owner_account_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "files_owner_account_id_fkey" + columns: ["owner_account_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, - ]; - }; + ] + } follows: { Row: { - game: string | null; - id: string | null; - timestamp: number | null; - }; + game: string | null + id: string | null + timestamp: number | null + } Insert: { - game?: string | null; - id?: string | null; - timestamp?: number | null; - }; + game?: string | null + id?: string | null + timestamp?: number | null + } Update: { - game?: string | null; - id?: string | null; - timestamp?: number | null; - }; - Relationships: []; - }; + game?: string | null + id?: string | null + timestamp?: number | null + } + Relationships: [] + } founder_dashboard_chart_annotations: { Row: { - chart_type: string | null; - created_at: string | null; - event_date: string; - event_description: string | null; - id: string; - }; + chart_type: string | null + created_at: string | null + event_date: string + event_description: string | null + id: string + } Insert: { - chart_type?: string | null; - created_at?: string | null; - event_date: string; - event_description?: string | null; - id?: string; - }; + chart_type?: string | null + created_at?: string | null + event_date: string + event_description?: string | null + id?: string + } Update: { - chart_type?: string | null; - created_at?: string | null; - event_date?: string; - event_description?: string | null; - id?: string; - }; - Relationships: []; - }; + chart_type?: string | null + created_at?: string | null + event_date?: string + event_description?: string | null + id?: string + } + Relationships: [] + } funnel_analytics: { Row: { - artist_id: string | null; - handle: string | null; - id: string; - pilot_id: string | null; - status: number | null; - type: Database["public"]["Enums"]["social_type"] | null; - updated_at: string; - }; + artist_id: string | null + handle: string | null + id: string + pilot_id: string | null + status: number | null + type: Database["public"]["Enums"]["social_type"] | null + updated_at: string + } Insert: { - artist_id?: string | null; - handle?: string | null; - id?: string; - pilot_id?: string | null; - status?: number | null; - type?: Database["public"]["Enums"]["social_type"] | null; - updated_at?: string; - }; + artist_id?: string | null + handle?: string | null + id?: string + pilot_id?: string | null + status?: number | null + type?: Database["public"]["Enums"]["social_type"] | null + updated_at?: string + } Update: { - artist_id?: string | null; - handle?: string | null; - id?: string; - pilot_id?: string | null; - status?: number | null; - type?: Database["public"]["Enums"]["social_type"] | null; - updated_at?: string; - }; + artist_id?: string | null + handle?: string | null + id?: string + pilot_id?: string | null + status?: number | null + type?: Database["public"]["Enums"]["social_type"] | null + updated_at?: string + } Relationships: [ { - foreignKeyName: "funnel_analytics_artist_id_fkey"; - columns: ["artist_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "funnel_analytics_artist_id_fkey" + columns: ["artist_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, - ]; - }; + ] + } funnel_analytics_accounts: { Row: { - account_id: string | null; - analysis_id: string | null; - created_at: string; - id: string; - updated_at: string | null; - }; + account_id: string | null + analysis_id: string | null + created_at: string + id: string + updated_at: string | null + } Insert: { - account_id?: string | null; - analysis_id?: string | null; - created_at?: string; - id?: string; - updated_at?: string | null; - }; + account_id?: string | null + analysis_id?: string | null + created_at?: string + id?: string + updated_at?: string | null + } Update: { - account_id?: string | null; - analysis_id?: string | null; - created_at?: string; - id?: string; - updated_at?: string | null; - }; + account_id?: string | null + analysis_id?: string | null + created_at?: string + id?: string + updated_at?: string | null + } Relationships: [ { - foreignKeyName: "account_funnel_analytics_account_id_fkey"; - columns: ["account_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "account_funnel_analytics_account_id_fkey" + columns: ["account_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, { - foreignKeyName: "account_funnel_analytics_analysis_id_fkey"; - columns: ["analysis_id"]; - isOneToOne: false; - referencedRelation: "funnel_analytics"; - referencedColumns: ["id"]; + foreignKeyName: "account_funnel_analytics_analysis_id_fkey" + columns: ["analysis_id"] + isOneToOne: false + referencedRelation: "funnel_analytics" + referencedColumns: ["id"] }, - ]; - }; + ] + } funnel_analytics_segments: { Row: { - analysis_id: string | null; - created_at: string; - icon: string | null; - id: string; - name: string | null; - size: number | null; - }; + analysis_id: string | null + created_at: string + icon: string | null + id: string + name: string | null + size: number | null + } Insert: { - analysis_id?: string | null; - created_at?: string; - icon?: string | null; - id?: string; - name?: string | null; - size?: number | null; - }; + analysis_id?: string | null + created_at?: string + icon?: string | null + id?: string + name?: string | null + size?: number | null + } Update: { - analysis_id?: string | null; - created_at?: string; - icon?: string | null; - id?: string; - name?: string | null; - size?: number | null; - }; + analysis_id?: string | null + created_at?: string + icon?: string | null + id?: string + name?: string | null + size?: number | null + } Relationships: [ { - foreignKeyName: "funnel_analytics_segments_analysis_id_fkey"; - columns: ["analysis_id"]; - isOneToOne: false; - referencedRelation: "funnel_analytics"; - referencedColumns: ["id"]; + foreignKeyName: "funnel_analytics_segments_analysis_id_fkey" + columns: ["analysis_id"] + isOneToOne: false + referencedRelation: "funnel_analytics" + referencedColumns: ["id"] }, - ]; - }; + ] + } funnel_reports: { Row: { - id: string; - next_steps: string | null; - report: string | null; - stack_unique_id: string | null; - timestamp: string; - type: Database["public"]["Enums"]["social_type"] | null; - }; + id: string + next_steps: string | null + report: string | null + stack_unique_id: string | null + timestamp: string + type: Database["public"]["Enums"]["social_type"] | null + } Insert: { - id?: string; - next_steps?: string | null; - report?: string | null; - stack_unique_id?: string | null; - timestamp?: string; - type?: Database["public"]["Enums"]["social_type"] | null; - }; + id?: string + next_steps?: string | null + report?: string | null + stack_unique_id?: string | null + timestamp?: string + type?: Database["public"]["Enums"]["social_type"] | null + } Update: { - id?: string; - next_steps?: string | null; - report?: string | null; - stack_unique_id?: string | null; - timestamp?: string; - type?: Database["public"]["Enums"]["social_type"] | null; - }; - Relationships: []; - }; + id?: string + next_steps?: string | null + report?: string | null + stack_unique_id?: string | null + timestamp?: string + type?: Database["public"]["Enums"]["social_type"] | null + } + Relationships: [] + } game_start: { Row: { - clientId: string | null; - fanId: Json | null; - game: string | null; - id: string | null; - timestamp: number | null; - }; + clientId: string | null + fanId: Json | null + game: string | null + id: string | null + timestamp: number | null + } Insert: { - clientId?: string | null; - fanId?: Json | null; - game?: string | null; - id?: string | null; - timestamp?: number | null; - }; + clientId?: string | null + fanId?: Json | null + game?: string | null + id?: string | null + timestamp?: number | null + } Update: { - clientId?: string | null; - fanId?: Json | null; - game?: string | null; - id?: string | null; - timestamp?: number | null; - }; - Relationships: []; - }; + clientId?: string | null + fanId?: Json | null + game?: string | null + id?: string | null + timestamp?: number | null + } + Relationships: [] + } invitations: { Row: { - account_id: string; - created_at: string; - email: string; - expires_at: string; - id: number; - invite_token: string; - invited_by: string; - role: string; - updated_at: string; - }; + account_id: string + created_at: string + email: string + expires_at: string + id: number + invite_token: string + invited_by: string + role: string + updated_at: string + } Insert: { - account_id: string; - created_at?: string; - email: string; - expires_at?: string; - id?: number; - invite_token: string; - invited_by: string; - role: string; - updated_at?: string; - }; + account_id: string + created_at?: string + email: string + expires_at?: string + id?: number + invite_token: string + invited_by: string + role: string + updated_at?: string + } Update: { - account_id?: string; - created_at?: string; - email?: string; - expires_at?: string; - id?: number; - invite_token?: string; - invited_by?: string; - role?: string; - updated_at?: string; - }; + account_id?: string + created_at?: string + email?: string + expires_at?: string + id?: number + invite_token?: string + invited_by?: string + role?: string + updated_at?: string + } Relationships: [ { - foreignKeyName: "invitations_role_fkey"; - columns: ["role"]; - isOneToOne: false; - referencedRelation: "roles"; - referencedColumns: ["name"]; + foreignKeyName: "invitations_role_fkey" + columns: ["role"] + isOneToOne: false + referencedRelation: "roles" + referencedColumns: ["name"] }, - ]; - }; + ] + } ios_redirect: { Row: { - clientId: string | null; - fanId: string | null; - id: string | null; - timestamp: number | null; - }; + clientId: string | null + fanId: string | null + id: string | null + timestamp: number | null + } Insert: { - clientId?: string | null; - fanId?: string | null; - id?: string | null; - timestamp?: number | null; - }; + clientId?: string | null + fanId?: string | null + id?: string | null + timestamp?: number | null + } Update: { - clientId?: string | null; - fanId?: string | null; - id?: string | null; - timestamp?: number | null; - }; - Relationships: []; - }; + clientId?: string | null + fanId?: string | null + id?: string | null + timestamp?: number | null + } + Relationships: [] + } leaderboard: { Row: { - id: string | null; - Name: string | null; - Number: string | null; - Score: string | null; - Spotify: string | null; - "Time._nanoseconds": string | null; - "Time._seconds": string | null; - }; + id: string | null + Name: string | null + Number: string | null + Score: string | null + Spotify: string | null + "Time._nanoseconds": string | null + "Time._seconds": string | null + } Insert: { - id?: string | null; - Name?: string | null; - Number?: string | null; - Score?: string | null; - Spotify?: string | null; - "Time._nanoseconds"?: string | null; - "Time._seconds"?: string | null; - }; + id?: string | null + Name?: string | null + Number?: string | null + Score?: string | null + Spotify?: string | null + "Time._nanoseconds"?: string | null + "Time._seconds"?: string | null + } Update: { - id?: string | null; - Name?: string | null; - Number?: string | null; - Score?: string | null; - Spotify?: string | null; - "Time._nanoseconds"?: string | null; - "Time._seconds"?: string | null; - }; - Relationships: []; - }; + id?: string | null + Name?: string | null + Number?: string | null + Score?: string | null + Spotify?: string | null + "Time._nanoseconds"?: string | null + "Time._seconds"?: string | null + } + Relationships: [] + } leaderboard_boogie: { Row: { - clientId: string | null; - displayName: string | null; - fanId: string | null; - gameType: string | null; - id: string | null; - score: number | null; - timestamp: string | null; - }; + clientId: string | null + displayName: string | null + fanId: string | null + gameType: string | null + id: string | null + score: number | null + timestamp: string | null + } Insert: { - clientId?: string | null; - displayName?: string | null; - fanId?: string | null; - gameType?: string | null; - id?: string | null; - score?: number | null; - timestamp?: string | null; - }; + clientId?: string | null + displayName?: string | null + fanId?: string | null + gameType?: string | null + id?: string | null + score?: number | null + timestamp?: string | null + } Update: { - clientId?: string | null; - displayName?: string | null; - fanId?: string | null; - gameType?: string | null; - id?: string | null; - score?: number | null; - timestamp?: string | null; - }; - Relationships: []; - }; + clientId?: string | null + displayName?: string | null + fanId?: string | null + gameType?: string | null + id?: string | null + score?: number | null + timestamp?: string | null + } + Relationships: [] + } leaderboard_luh_tyler_3d: { Row: { - FanId: string | null; - id: string | null; - Score: string | null; - ScorePerTime: string | null; - Time: string | null; - timestamp: string | null; - UserName: string | null; - }; + FanId: string | null + id: string | null + Score: string | null + ScorePerTime: string | null + Time: string | null + timestamp: string | null + UserName: string | null + } Insert: { - FanId?: string | null; - id?: string | null; - Score?: string | null; - ScorePerTime?: string | null; - Time?: string | null; - timestamp?: string | null; - UserName?: string | null; - }; + FanId?: string | null + id?: string | null + Score?: string | null + ScorePerTime?: string | null + Time?: string | null + timestamp?: string | null + UserName?: string | null + } Update: { - FanId?: string | null; - id?: string | null; - Score?: string | null; - ScorePerTime?: string | null; - Time?: string | null; - timestamp?: string | null; - UserName?: string | null; - }; - Relationships: []; - }; + FanId?: string | null + id?: string | null + Score?: string | null + ScorePerTime?: string | null + Time?: string | null + timestamp?: string | null + UserName?: string | null + } + Relationships: [] + } leaderboard_luv: { Row: { - f: string | null; - id: string | null; - }; + f: string | null + id: string | null + } Insert: { - f?: string | null; - id?: string | null; - }; + f?: string | null + id?: string | null + } Update: { - f?: string | null; - id?: string | null; - }; - Relationships: []; - }; + f?: string | null + id?: string | null + } + Relationships: [] + } memories: { Row: { - content: Json; - id: string; - room_id: string | null; - updated_at: string; - }; + content: Json + id: string + room_id: string | null + updated_at: string + } Insert: { - content: Json; - id?: string; - room_id?: string | null; - updated_at?: string; - }; + content: Json + id?: string + room_id?: string | null + updated_at?: string + } Update: { - content?: Json; - id?: string; - room_id?: string | null; - updated_at?: string; - }; + content?: Json + id?: string + room_id?: string | null + updated_at?: string + } Relationships: [ { - foreignKeyName: "memories_room_id_fkey"; - columns: ["room_id"]; - isOneToOne: false; - referencedRelation: "rooms"; - referencedColumns: ["id"]; + foreignKeyName: "memories_room_id_fkey" + columns: ["room_id"] + isOneToOne: false + referencedRelation: "rooms" + referencedColumns: ["id"] }, - ]; - }; + ] + } memory_emails: { Row: { - created_at: string; - email_id: string; - id: string; - memory: string; - message_id: string; - }; + created_at: string + email_id: string + id: string + memory: string + message_id: string + } Insert: { - created_at?: string; - email_id: string; - id?: string; - memory: string; - message_id: string; - }; + created_at?: string + email_id: string + id?: string + memory: string + message_id: string + } Update: { - created_at?: string; - email_id?: string; - id?: string; - memory?: string; - message_id?: string; - }; + created_at?: string + email_id?: string + id?: string + memory?: string + message_id?: string + } Relationships: [ { - foreignKeyName: "memory_emails_memory_fkey"; - columns: ["memory"]; - isOneToOne: false; - referencedRelation: "memories"; - referencedColumns: ["id"]; + foreignKeyName: "memory_emails_memory_fkey" + columns: ["memory"] + isOneToOne: false + referencedRelation: "memories" + referencedColumns: ["id"] }, - ]; - }; + ] + } notifications: { Row: { - account_id: string; - body: string; - channel: Database["public"]["Enums"]["notification_channel"]; - created_at: string; - dismissed: boolean; - expires_at: string | null; - id: number; - link: string | null; - type: Database["public"]["Enums"]["notification_type"]; - }; + account_id: string + body: string + channel: Database["public"]["Enums"]["notification_channel"] + created_at: string + dismissed: boolean + expires_at: string | null + id: number + link: string | null + type: Database["public"]["Enums"]["notification_type"] + } Insert: { - account_id: string; - body: string; - channel?: Database["public"]["Enums"]["notification_channel"]; - created_at?: string; - dismissed?: boolean; - expires_at?: string | null; - id?: never; - link?: string | null; - type?: Database["public"]["Enums"]["notification_type"]; - }; + account_id: string + body: string + channel?: Database["public"]["Enums"]["notification_channel"] + created_at?: string + dismissed?: boolean + expires_at?: string | null + id?: never + link?: string | null + type?: Database["public"]["Enums"]["notification_type"] + } Update: { - account_id?: string; - body?: string; - channel?: Database["public"]["Enums"]["notification_channel"]; - created_at?: string; - dismissed?: boolean; - expires_at?: string | null; - id?: never; - link?: string | null; - type?: Database["public"]["Enums"]["notification_type"]; - }; - Relationships: []; - }; + account_id?: string + body?: string + channel?: Database["public"]["Enums"]["notification_channel"] + created_at?: string + dismissed?: boolean + expires_at?: string | null + id?: never + link?: string | null + type?: Database["public"]["Enums"]["notification_type"] + } + Relationships: [] + } order_items: { Row: { - created_at: string; - id: string; - order_id: string; - price_amount: number | null; - product_id: string; - quantity: number; - updated_at: string; - variant_id: string; - }; + created_at: string + id: string + order_id: string + price_amount: number | null + product_id: string + quantity: number + updated_at: string + variant_id: string + } Insert: { - created_at?: string; - id: string; - order_id: string; - price_amount?: number | null; - product_id: string; - quantity?: number; - updated_at?: string; - variant_id: string; - }; + created_at?: string + id: string + order_id: string + price_amount?: number | null + product_id: string + quantity?: number + updated_at?: string + variant_id: string + } Update: { - created_at?: string; - id?: string; - order_id?: string; - price_amount?: number | null; - product_id?: string; - quantity?: number; - updated_at?: string; - variant_id?: string; - }; + created_at?: string + id?: string + order_id?: string + price_amount?: number | null + product_id?: string + quantity?: number + updated_at?: string + variant_id?: string + } Relationships: [ { - foreignKeyName: "order_items_order_id_fkey"; - columns: ["order_id"]; - isOneToOne: false; - referencedRelation: "orders"; - referencedColumns: ["id"]; + foreignKeyName: "order_items_order_id_fkey" + columns: ["order_id"] + isOneToOne: false + referencedRelation: "orders" + referencedColumns: ["id"] }, - ]; - }; + ] + } orders: { Row: { - account_id: string; - billing_customer_id: number; - billing_provider: Database["public"]["Enums"]["billing_provider"]; - created_at: string; - currency: string; - id: string; - status: Database["public"]["Enums"]["payment_status"]; - total_amount: number; - updated_at: string; - }; + account_id: string + billing_customer_id: number + billing_provider: Database["public"]["Enums"]["billing_provider"] + created_at: string + currency: string + id: string + status: Database["public"]["Enums"]["payment_status"] + total_amount: number + updated_at: string + } Insert: { - account_id: string; - billing_customer_id: number; - billing_provider: Database["public"]["Enums"]["billing_provider"]; - created_at?: string; - currency: string; - id: string; - status: Database["public"]["Enums"]["payment_status"]; - total_amount: number; - updated_at?: string; - }; + account_id: string + billing_customer_id: number + billing_provider: Database["public"]["Enums"]["billing_provider"] + created_at?: string + currency: string + id: string + status: Database["public"]["Enums"]["payment_status"] + total_amount: number + updated_at?: string + } Update: { - account_id?: string; - billing_customer_id?: number; - billing_provider?: Database["public"]["Enums"]["billing_provider"]; - created_at?: string; - currency?: string; - id?: string; - status?: Database["public"]["Enums"]["payment_status"]; - total_amount?: number; - updated_at?: string; - }; + account_id?: string + billing_customer_id?: number + billing_provider?: Database["public"]["Enums"]["billing_provider"] + created_at?: string + currency?: string + id?: string + status?: Database["public"]["Enums"]["payment_status"] + total_amount?: number + updated_at?: string + } Relationships: [ { - foreignKeyName: "orders_billing_customer_id_fkey"; - columns: ["billing_customer_id"]; - isOneToOne: false; - referencedRelation: "billing_customers"; - referencedColumns: ["id"]; + foreignKeyName: "orders_billing_customer_id_fkey" + columns: ["billing_customer_id"] + isOneToOne: false + referencedRelation: "billing_customers" + referencedColumns: ["id"] }, - ]; - }; + ] + } organization_domains: { Row: { - created_at: string | null; - domain: string; - id: string; - organization_id: string; - }; + created_at: string | null + domain: string + id: string + organization_id: string + } Insert: { - created_at?: string | null; - domain: string; - id?: string; - organization_id: string; - }; + created_at?: string | null + domain: string + id?: string + organization_id: string + } Update: { - created_at?: string | null; - domain?: string; - id?: string; - organization_id?: string; - }; + created_at?: string | null + domain?: string + id?: string + organization_id?: string + } Relationships: [ { - foreignKeyName: "organization_domains_organization_id_fkey"; - columns: ["organization_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "organization_domains_organization_id_fkey" + columns: ["organization_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, - ]; - }; + ] + } plans: { Row: { - name: string; - tokens_quota: number; - variant_id: string; - }; + name: string + tokens_quota: number + variant_id: string + } Insert: { - name: string; - tokens_quota: number; - variant_id: string; - }; + name: string + tokens_quota: number + variant_id: string + } Update: { - name?: string; - tokens_quota?: number; - variant_id?: string; - }; - Relationships: []; - }; + name?: string + tokens_quota?: number + variant_id?: string + } + Relationships: [] + } popup_open: { Row: { - campaignId: string | null; - clientId: string | null; - fanId: string | null; - game: string | null; - id: string | null; - timestamp: string | null; - }; + campaignId: string | null + clientId: string | null + fanId: string | null + game: string | null + id: string | null + timestamp: string | null + } Insert: { - campaignId?: string | null; - clientId?: string | null; - fanId?: string | null; - game?: string | null; - id?: string | null; - timestamp?: string | null; - }; + campaignId?: string | null + clientId?: string | null + fanId?: string | null + game?: string | null + id?: string | null + timestamp?: string | null + } Update: { - campaignId?: string | null; - clientId?: string | null; - fanId?: string | null; - game?: string | null; - id?: string | null; - timestamp?: string | null; - }; - Relationships: []; - }; + campaignId?: string | null + clientId?: string | null + fanId?: string | null + game?: string | null + id?: string | null + timestamp?: string | null + } + Relationships: [] + } post_comments: { Row: { - comment: string | null; - commented_at: string; - id: string; - post_id: string | null; - social_id: string | null; - }; + comment: string | null + commented_at: string + id: string + post_id: string | null + social_id: string | null + } Insert: { - comment?: string | null; - commented_at: string; - id?: string; - post_id?: string | null; - social_id?: string | null; - }; + comment?: string | null + commented_at: string + id?: string + post_id?: string | null + social_id?: string | null + } Update: { - comment?: string | null; - commented_at?: string; - id?: string; - post_id?: string | null; - social_id?: string | null; - }; + comment?: string | null + commented_at?: string + id?: string + post_id?: string | null + social_id?: string | null + } Relationships: [ { - foreignKeyName: "post_comments_post_id_fkey"; - columns: ["post_id"]; - isOneToOne: false; - referencedRelation: "posts"; - referencedColumns: ["id"]; + foreignKeyName: "post_comments_post_id_fkey" + columns: ["post_id"] + isOneToOne: false + referencedRelation: "posts" + referencedColumns: ["id"] }, { - foreignKeyName: "post_comments_social_id_fkey"; - columns: ["social_id"]; - isOneToOne: false; - referencedRelation: "socials"; - referencedColumns: ["id"]; + foreignKeyName: "post_comments_social_id_fkey" + columns: ["social_id"] + isOneToOne: false + referencedRelation: "socials" + referencedColumns: ["id"] }, - ]; - }; + ] + } posts: { Row: { - id: string; - post_url: string; - updated_at: string; - }; + id: string + post_url: string + updated_at: string + } Insert: { - id?: string; - post_url: string; - updated_at?: string; - }; + id?: string + post_url: string + updated_at?: string + } Update: { - id?: string; - post_url?: string; - updated_at?: string; - }; - Relationships: []; - }; + id?: string + post_url?: string + updated_at?: string + } + Relationships: [] + } presave: { Row: { - accessToken: string | null; - fanId: string | null; - "fanId.error.code": string | null; - "fanId.error.name": string | null; - id: string | null; - presaveId: string | null; - presaveReleaseDate: string | null; - refreshToken: string | null; - timestamp: number | null; - }; + accessToken: string | null + fanId: string | null + "fanId.error.code": string | null + "fanId.error.name": string | null + id: string | null + presaveId: string | null + presaveReleaseDate: string | null + refreshToken: string | null + timestamp: number | null + } Insert: { - accessToken?: string | null; - fanId?: string | null; - "fanId.error.code"?: string | null; - "fanId.error.name"?: string | null; - id?: string | null; - presaveId?: string | null; - presaveReleaseDate?: string | null; - refreshToken?: string | null; - timestamp?: number | null; - }; + accessToken?: string | null + fanId?: string | null + "fanId.error.code"?: string | null + "fanId.error.name"?: string | null + id?: string | null + presaveId?: string | null + presaveReleaseDate?: string | null + refreshToken?: string | null + timestamp?: number | null + } Update: { - accessToken?: string | null; - fanId?: string | null; - "fanId.error.code"?: string | null; - "fanId.error.name"?: string | null; - id?: string | null; - presaveId?: string | null; - presaveReleaseDate?: string | null; - refreshToken?: string | null; - timestamp?: number | null; - }; - Relationships: []; - }; + accessToken?: string | null + fanId?: string | null + "fanId.error.code"?: string | null + "fanId.error.name"?: string | null + id?: string | null + presaveId?: string | null + presaveReleaseDate?: string | null + refreshToken?: string | null + timestamp?: number | null + } + Relationships: [] + } pulse_accounts: { Row: { - account_id: string; - active: boolean; - id: string; - }; + account_id: string + active: boolean + id: string + } Insert: { - account_id: string; - active?: boolean; - id?: string; - }; + account_id: string + active?: boolean + id?: string + } Update: { - account_id?: string; - active?: boolean; - id?: string; - }; + account_id?: string + active?: boolean + id?: string + } Relationships: [ { - foreignKeyName: "pulse_accounts_account_id_fkey"; - columns: ["account_id"]; - isOneToOne: true; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "pulse_accounts_account_id_fkey" + columns: ["account_id"] + isOneToOne: true + referencedRelation: "accounts" + referencedColumns: ["id"] }, - ]; - }; + ] + } role_permissions: { Row: { - id: number; - permission: Database["public"]["Enums"]["app_permissions"]; - role: string; - }; + id: number + permission: Database["public"]["Enums"]["app_permissions"] + role: string + } Insert: { - id?: number; - permission: Database["public"]["Enums"]["app_permissions"]; - role: string; - }; + id?: number + permission: Database["public"]["Enums"]["app_permissions"] + role: string + } Update: { - id?: number; - permission?: Database["public"]["Enums"]["app_permissions"]; - role?: string; - }; + id?: number + permission?: Database["public"]["Enums"]["app_permissions"] + role?: string + } Relationships: [ { - foreignKeyName: "role_permissions_role_fkey"; - columns: ["role"]; - isOneToOne: false; - referencedRelation: "roles"; - referencedColumns: ["name"]; + foreignKeyName: "role_permissions_role_fkey" + columns: ["role"] + isOneToOne: false + referencedRelation: "roles" + referencedColumns: ["name"] }, - ]; - }; + ] + } roles: { Row: { - hierarchy_level: number; - name: string; - }; + hierarchy_level: number + name: string + } Insert: { - hierarchy_level: number; - name: string; - }; + hierarchy_level: number + name: string + } Update: { - hierarchy_level?: number; - name?: string; - }; - Relationships: []; - }; + hierarchy_level?: number + name?: string + } + Relationships: [] + } room_reports: { Row: { - id: string; - report_id: string; - room_id: string | null; - }; + id: string + report_id: string + room_id: string | null + } Insert: { - id?: string; - report_id?: string; - room_id?: string | null; - }; + id?: string + report_id?: string + room_id?: string | null + } Update: { - id?: string; - report_id?: string; - room_id?: string | null; - }; + id?: string + report_id?: string + room_id?: string | null + } Relationships: [ { - foreignKeyName: "room_reports_report_id_fkey"; - columns: ["report_id"]; - isOneToOne: false; - referencedRelation: "segment_reports"; - referencedColumns: ["id"]; + foreignKeyName: "room_reports_report_id_fkey" + columns: ["report_id"] + isOneToOne: false + referencedRelation: "segment_reports" + referencedColumns: ["id"] }, { - foreignKeyName: "room_reports_room_id_fkey"; - columns: ["room_id"]; - isOneToOne: false; - referencedRelation: "rooms"; - referencedColumns: ["id"]; + foreignKeyName: "room_reports_room_id_fkey" + columns: ["room_id"] + isOneToOne: false + referencedRelation: "rooms" + referencedColumns: ["id"] }, - ]; - }; + ] + } rooms: { Row: { - account_id: string | null; - artist_id: string | null; - id: string; - topic: string | null; - updated_at: string; - }; + account_id: string | null + artist_id: string | null + id: string + topic: string | null + updated_at: string + } Insert: { - account_id?: string | null; - artist_id?: string | null; - id?: string; - topic?: string | null; - updated_at?: string; - }; + account_id?: string | null + artist_id?: string | null + id?: string + topic?: string | null + updated_at?: string + } Update: { - account_id?: string | null; - artist_id?: string | null; - id?: string; - topic?: string | null; - updated_at?: string; - }; + account_id?: string | null + artist_id?: string | null + id?: string + topic?: string | null + updated_at?: string + } Relationships: [ { - foreignKeyName: "rooms_artist_id_fkey"; - columns: ["artist_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "rooms_artist_id_fkey" + columns: ["artist_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, - ]; - }; + ] + } sales_pipeline_customers: { Row: { - activity_count: number | null; - assigned_to: string | null; - company_size: string | null; - competitors: string[] | null; - contact_email: string | null; - contact_name: string | null; - contact_phone: string | null; - contacts: Json | null; - conversion_stage: string | null; - conversion_target_date: string | null; - created_at: string | null; - current_artists: number; - current_mrr: number; - custom_fields: Json | null; - days_in_stage: number | null; - domain: string | null; - email: string | null; - engagement_health: string | null; - expected_close_date: string | null; - external_ids: Json | null; - id: string; - industry: string | null; - internal_owner: string | null; - last_activity_date: string | null; - last_activity_type: string | null; - last_contact_date: string; - logo_url: string | null; - lost_reason: string | null; - name: string; - next_action: string | null; - next_activity_date: string | null; - next_activity_type: string | null; - notes: string | null; - order_index: number | null; - organization: string | null; - potential_artists: number; - potential_mrr: number; - priority: string | null; - probability: number | null; - recoupable_user_id: string | null; - source: string | null; - stage: string; - stage_entered_at: string | null; - tags: string[] | null; - todos: Json | null; - trial_end_date: string | null; - trial_start_date: string | null; - type: string | null; - updated_at: string | null; - use_case_type: string | null; - website: string | null; - weighted_mrr: number | null; - win_reason: string | null; - }; + activity_count: number | null + assigned_to: string | null + company_size: string | null + competitors: string[] | null + contact_email: string | null + contact_name: string | null + contact_phone: string | null + contacts: Json | null + conversion_stage: string | null + conversion_target_date: string | null + created_at: string | null + current_artists: number + current_mrr: number + custom_fields: Json | null + days_in_stage: number | null + domain: string | null + email: string | null + engagement_health: string | null + expected_close_date: string | null + external_ids: Json | null + id: string + industry: string | null + internal_owner: string | null + last_activity_date: string | null + last_activity_type: string | null + last_contact_date: string + logo_url: string | null + lost_reason: string | null + name: string + next_action: string | null + next_activity_date: string | null + next_activity_type: string | null + notes: string | null + order_index: number | null + organization: string | null + potential_artists: number + potential_mrr: number + priority: string | null + probability: number | null + recoupable_user_id: string | null + source: string | null + stage: string + stage_entered_at: string | null + tags: string[] | null + todos: Json | null + trial_end_date: string | null + trial_start_date: string | null + type: string | null + updated_at: string | null + use_case_type: string | null + website: string | null + weighted_mrr: number | null + win_reason: string | null + } Insert: { - activity_count?: number | null; - assigned_to?: string | null; - company_size?: string | null; - competitors?: string[] | null; - contact_email?: string | null; - contact_name?: string | null; - contact_phone?: string | null; - contacts?: Json | null; - conversion_stage?: string | null; - conversion_target_date?: string | null; - created_at?: string | null; - current_artists?: number; - current_mrr?: number; - custom_fields?: Json | null; - days_in_stage?: number | null; - domain?: string | null; - email?: string | null; - engagement_health?: string | null; - expected_close_date?: string | null; - external_ids?: Json | null; - id?: string; - industry?: string | null; - internal_owner?: string | null; - last_activity_date?: string | null; - last_activity_type?: string | null; - last_contact_date?: string; - logo_url?: string | null; - lost_reason?: string | null; - name: string; - next_action?: string | null; - next_activity_date?: string | null; - next_activity_type?: string | null; - notes?: string | null; - order_index?: number | null; - organization?: string | null; - potential_artists?: number; - potential_mrr?: number; - priority?: string | null; - probability?: number | null; - recoupable_user_id?: string | null; - source?: string | null; - stage: string; - stage_entered_at?: string | null; - tags?: string[] | null; - todos?: Json | null; - trial_end_date?: string | null; - trial_start_date?: string | null; - type?: string | null; - updated_at?: string | null; - use_case_type?: string | null; - website?: string | null; - weighted_mrr?: number | null; - win_reason?: string | null; - }; + activity_count?: number | null + assigned_to?: string | null + company_size?: string | null + competitors?: string[] | null + contact_email?: string | null + contact_name?: string | null + contact_phone?: string | null + contacts?: Json | null + conversion_stage?: string | null + conversion_target_date?: string | null + created_at?: string | null + current_artists?: number + current_mrr?: number + custom_fields?: Json | null + days_in_stage?: number | null + domain?: string | null + email?: string | null + engagement_health?: string | null + expected_close_date?: string | null + external_ids?: Json | null + id?: string + industry?: string | null + internal_owner?: string | null + last_activity_date?: string | null + last_activity_type?: string | null + last_contact_date?: string + logo_url?: string | null + lost_reason?: string | null + name: string + next_action?: string | null + next_activity_date?: string | null + next_activity_type?: string | null + notes?: string | null + order_index?: number | null + organization?: string | null + potential_artists?: number + potential_mrr?: number + priority?: string | null + probability?: number | null + recoupable_user_id?: string | null + source?: string | null + stage: string + stage_entered_at?: string | null + tags?: string[] | null + todos?: Json | null + trial_end_date?: string | null + trial_start_date?: string | null + type?: string | null + updated_at?: string | null + use_case_type?: string | null + website?: string | null + weighted_mrr?: number | null + win_reason?: string | null + } Update: { - activity_count?: number | null; - assigned_to?: string | null; - company_size?: string | null; - competitors?: string[] | null; - contact_email?: string | null; - contact_name?: string | null; - contact_phone?: string | null; - contacts?: Json | null; - conversion_stage?: string | null; - conversion_target_date?: string | null; - created_at?: string | null; - current_artists?: number; - current_mrr?: number; - custom_fields?: Json | null; - days_in_stage?: number | null; - domain?: string | null; - email?: string | null; - engagement_health?: string | null; - expected_close_date?: string | null; - external_ids?: Json | null; - id?: string; - industry?: string | null; - internal_owner?: string | null; - last_activity_date?: string | null; - last_activity_type?: string | null; - last_contact_date?: string; - logo_url?: string | null; - lost_reason?: string | null; - name?: string; - next_action?: string | null; - next_activity_date?: string | null; - next_activity_type?: string | null; - notes?: string | null; - order_index?: number | null; - organization?: string | null; - potential_artists?: number; - potential_mrr?: number; - priority?: string | null; - probability?: number | null; - recoupable_user_id?: string | null; - source?: string | null; - stage?: string; - stage_entered_at?: string | null; - tags?: string[] | null; - todos?: Json | null; - trial_end_date?: string | null; - trial_start_date?: string | null; - type?: string | null; - updated_at?: string | null; - use_case_type?: string | null; - website?: string | null; - weighted_mrr?: number | null; - win_reason?: string | null; - }; - Relationships: []; - }; + activity_count?: number | null + assigned_to?: string | null + company_size?: string | null + competitors?: string[] | null + contact_email?: string | null + contact_name?: string | null + contact_phone?: string | null + contacts?: Json | null + conversion_stage?: string | null + conversion_target_date?: string | null + created_at?: string | null + current_artists?: number + current_mrr?: number + custom_fields?: Json | null + days_in_stage?: number | null + domain?: string | null + email?: string | null + engagement_health?: string | null + expected_close_date?: string | null + external_ids?: Json | null + id?: string + industry?: string | null + internal_owner?: string | null + last_activity_date?: string | null + last_activity_type?: string | null + last_contact_date?: string + logo_url?: string | null + lost_reason?: string | null + name?: string + next_action?: string | null + next_activity_date?: string | null + next_activity_type?: string | null + notes?: string | null + order_index?: number | null + organization?: string | null + potential_artists?: number + potential_mrr?: number + priority?: string | null + probability?: number | null + recoupable_user_id?: string | null + source?: string | null + stage?: string + stage_entered_at?: string | null + tags?: string[] | null + todos?: Json | null + trial_end_date?: string | null + trial_start_date?: string | null + type?: string | null + updated_at?: string | null + use_case_type?: string | null + website?: string | null + weighted_mrr?: number | null + win_reason?: string | null + } + Relationships: [] + } save_track: { Row: { - game: string | null; - id: string | null; - timestamp: string | null; - }; + game: string | null + id: string | null + timestamp: string | null + } Insert: { - game?: string | null; - id?: string | null; - timestamp?: string | null; - }; + game?: string | null + id?: string | null + timestamp?: string | null + } Update: { - game?: string | null; - id?: string | null; - timestamp?: string | null; - }; - Relationships: []; - }; + game?: string | null + id?: string | null + timestamp?: string | null + } + Relationships: [] + } scheduled_actions: { Row: { - account_id: string; - artist_account_id: string; - created_at: string | null; - enabled: boolean | null; - id: string; - last_run: string | null; - model: string | null; - next_run: string | null; - prompt: string; - schedule: string; - title: string; - trigger_schedule_id: string | null; - updated_at: string | null; - }; + account_id: string + artist_account_id: string + created_at: string | null + enabled: boolean | null + id: string + last_run: string | null + model: string | null + next_run: string | null + prompt: string + schedule: string + title: string + trigger_schedule_id: string | null + updated_at: string | null + } Insert: { - account_id: string; - artist_account_id: string; - created_at?: string | null; - enabled?: boolean | null; - id?: string; - last_run?: string | null; - model?: string | null; - next_run?: string | null; - prompt: string; - schedule: string; - title: string; - trigger_schedule_id?: string | null; - updated_at?: string | null; - }; + account_id: string + artist_account_id: string + created_at?: string | null + enabled?: boolean | null + id?: string + last_run?: string | null + model?: string | null + next_run?: string | null + prompt: string + schedule: string + title: string + trigger_schedule_id?: string | null + updated_at?: string | null + } Update: { - account_id?: string; - artist_account_id?: string; - created_at?: string | null; - enabled?: boolean | null; - id?: string; - last_run?: string | null; - model?: string | null; - next_run?: string | null; - prompt?: string; - schedule?: string; - title?: string; - trigger_schedule_id?: string | null; - updated_at?: string | null; - }; + account_id?: string + artist_account_id?: string + created_at?: string | null + enabled?: boolean | null + id?: string + last_run?: string | null + model?: string | null + next_run?: string | null + prompt?: string + schedule?: string + title?: string + trigger_schedule_id?: string | null + updated_at?: string | null + } Relationships: [ { - foreignKeyName: "scheduled_actions_account_id_fkey"; - columns: ["account_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "scheduled_actions_account_id_fkey" + columns: ["account_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, { - foreignKeyName: "scheduled_actions_artist_account_id_fkey"; - columns: ["artist_account_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "scheduled_actions_artist_account_id_fkey" + columns: ["artist_account_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, - ]; - }; + ] + } segment_reports: { Row: { - artist_id: string | null; - id: string; - next_steps: string | null; - report: string | null; - updated_at: string | null; - }; + artist_id: string | null + id: string + next_steps: string | null + report: string | null + updated_at: string | null + } Insert: { - artist_id?: string | null; - id?: string; - next_steps?: string | null; - report?: string | null; - updated_at?: string | null; - }; + artist_id?: string | null + id?: string + next_steps?: string | null + report?: string | null + updated_at?: string | null + } Update: { - artist_id?: string | null; - id?: string; - next_steps?: string | null; - report?: string | null; - updated_at?: string | null; - }; + artist_id?: string | null + id?: string + next_steps?: string | null + report?: string | null + updated_at?: string | null + } Relationships: [ { - foreignKeyName: "segment_reports_artist_id_fkey"; - columns: ["artist_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "segment_reports_artist_id_fkey" + columns: ["artist_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, - ]; - }; + ] + } segment_rooms: { Row: { - id: string; - room_id: string; - segment_id: string; - updated_at: string; - }; + id: string + room_id: string + segment_id: string + updated_at: string + } Insert: { - id?: string; - room_id: string; - segment_id: string; - updated_at?: string; - }; + id?: string + room_id: string + segment_id: string + updated_at?: string + } Update: { - id?: string; - room_id?: string; - segment_id?: string; - updated_at?: string; - }; + id?: string + room_id?: string + segment_id?: string + updated_at?: string + } Relationships: [ { - foreignKeyName: "segment_rooms_room_id_fkey"; - columns: ["room_id"]; - isOneToOne: false; - referencedRelation: "rooms"; - referencedColumns: ["id"]; + foreignKeyName: "segment_rooms_room_id_fkey" + columns: ["room_id"] + isOneToOne: false + referencedRelation: "rooms" + referencedColumns: ["id"] }, { - foreignKeyName: "segment_rooms_segment_id_fkey"; - columns: ["segment_id"]; - isOneToOne: false; - referencedRelation: "segments"; - referencedColumns: ["id"]; + foreignKeyName: "segment_rooms_segment_id_fkey" + columns: ["segment_id"] + isOneToOne: false + referencedRelation: "segments" + referencedColumns: ["id"] }, - ]; - }; + ] + } segments: { Row: { - id: string; - name: string; - updated_at: string | null; - }; + id: string + name: string + updated_at: string | null + } Insert: { - id?: string; - name: string; - updated_at?: string | null; - }; + id?: string + name: string + updated_at?: string | null + } Update: { - id?: string; - name?: string; - updated_at?: string | null; - }; - Relationships: []; - }; + id?: string + name?: string + updated_at?: string | null + } + Relationships: [] + } sessions: { Row: { - account_id: string; - artist_id: string | null; - branch: string | null; - cached_diff: Json | null; - cached_diff_updated_at: string | null; - clone_url: string | null; - created_at: string; - global_skill_refs: Json; - hibernate_after: string | null; - id: string; - is_new_branch: boolean; - last_activity_at: string | null; - lifecycle_error: string | null; - lifecycle_run_id: string | null; - lifecycle_state: string | null; - lifecycle_version: number; - lines_added: number | null; - lines_removed: number | null; - repo_name: string | null; - repo_owner: string | null; - sandbox_expires_at: string | null; - sandbox_state: Json | null; - snapshot_created_at: string | null; - snapshot_size_bytes: number | null; - snapshot_url: string | null; - status: string; - title: string; - updated_at: string; - }; + account_id: string + artist_id: string | null + branch: string | null + cached_diff: Json | null + cached_diff_updated_at: string | null + clone_url: string | null + created_at: string + global_skill_refs: Json + hibernate_after: string | null + id: string + is_new_branch: boolean + last_activity_at: string | null + lifecycle_error: string | null + lifecycle_run_id: string | null + lifecycle_state: string | null + lifecycle_version: number + lines_added: number | null + lines_removed: number | null + repo_name: string | null + repo_owner: string | null + sandbox_expires_at: string | null + sandbox_state: Json | null + snapshot_created_at: string | null + snapshot_size_bytes: number | null + snapshot_url: string | null + status: string + title: string + updated_at: string + } Insert: { - account_id: string; - artist_id?: string | null; - branch?: string | null; - cached_diff?: Json | null; - cached_diff_updated_at?: string | null; - clone_url?: string | null; - created_at?: string; - global_skill_refs?: Json; - hibernate_after?: string | null; - id: string; - is_new_branch?: boolean; - last_activity_at?: string | null; - lifecycle_error?: string | null; - lifecycle_run_id?: string | null; - lifecycle_state?: string | null; - lifecycle_version?: number; - lines_added?: number | null; - lines_removed?: number | null; - repo_name?: string | null; - repo_owner?: string | null; - sandbox_expires_at?: string | null; - sandbox_state?: Json | null; - snapshot_created_at?: string | null; - snapshot_size_bytes?: number | null; - snapshot_url?: string | null; - status?: string; - title: string; - updated_at?: string; - }; + account_id: string + artist_id?: string | null + branch?: string | null + cached_diff?: Json | null + cached_diff_updated_at?: string | null + clone_url?: string | null + created_at?: string + global_skill_refs?: Json + hibernate_after?: string | null + id: string + is_new_branch?: boolean + last_activity_at?: string | null + lifecycle_error?: string | null + lifecycle_run_id?: string | null + lifecycle_state?: string | null + lifecycle_version?: number + lines_added?: number | null + lines_removed?: number | null + repo_name?: string | null + repo_owner?: string | null + sandbox_expires_at?: string | null + sandbox_state?: Json | null + snapshot_created_at?: string | null + snapshot_size_bytes?: number | null + snapshot_url?: string | null + status?: string + title: string + updated_at?: string + } Update: { - account_id?: string; - artist_id?: string | null; - branch?: string | null; - cached_diff?: Json | null; - cached_diff_updated_at?: string | null; - clone_url?: string | null; - created_at?: string; - global_skill_refs?: Json; - hibernate_after?: string | null; - id?: string; - is_new_branch?: boolean; - last_activity_at?: string | null; - lifecycle_error?: string | null; - lifecycle_run_id?: string | null; - lifecycle_state?: string | null; - lifecycle_version?: number; - lines_added?: number | null; - lines_removed?: number | null; - repo_name?: string | null; - repo_owner?: string | null; - sandbox_expires_at?: string | null; - sandbox_state?: Json | null; - snapshot_created_at?: string | null; - snapshot_size_bytes?: number | null; - snapshot_url?: string | null; - status?: string; - title?: string; - updated_at?: string; - }; + account_id?: string + artist_id?: string | null + branch?: string | null + cached_diff?: Json | null + cached_diff_updated_at?: string | null + clone_url?: string | null + created_at?: string + global_skill_refs?: Json + hibernate_after?: string | null + id?: string + is_new_branch?: boolean + last_activity_at?: string | null + lifecycle_error?: string | null + lifecycle_run_id?: string | null + lifecycle_state?: string | null + lifecycle_version?: number + lines_added?: number | null + lines_removed?: number | null + repo_name?: string | null + repo_owner?: string | null + sandbox_expires_at?: string | null + sandbox_state?: Json | null + snapshot_created_at?: string | null + snapshot_size_bytes?: number | null + snapshot_url?: string | null + status?: string + title?: string + updated_at?: string + } Relationships: [ { - foreignKeyName: "sessions_account_id_fkey"; - columns: ["account_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "sessions_account_id_fkey" + columns: ["account_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, { - foreignKeyName: "sessions_artist_id_fkey"; - columns: ["artist_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "sessions_artist_id_fkey" + columns: ["artist_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, - ]; - }; + ] + } social_fans: { Row: { - artist_social_id: string; - created_at: string; - fan_social_id: string; - id: string; - latest_engagement: string | null; - latest_engagement_id: string | null; - updated_at: string; - }; + artist_social_id: string + created_at: string + fan_social_id: string + id: string + latest_engagement: string | null + latest_engagement_id: string | null + updated_at: string + } Insert: { - artist_social_id: string; - created_at?: string; - fan_social_id: string; - id?: string; - latest_engagement?: string | null; - latest_engagement_id?: string | null; - updated_at?: string; - }; + artist_social_id: string + created_at?: string + fan_social_id: string + id?: string + latest_engagement?: string | null + latest_engagement_id?: string | null + updated_at?: string + } Update: { - artist_social_id?: string; - created_at?: string; - fan_social_id?: string; - id?: string; - latest_engagement?: string | null; - latest_engagement_id?: string | null; - updated_at?: string; - }; + artist_social_id?: string + created_at?: string + fan_social_id?: string + id?: string + latest_engagement?: string | null + latest_engagement_id?: string | null + updated_at?: string + } Relationships: [ { - foreignKeyName: "social_fans_artist_social_id_fkey"; - columns: ["artist_social_id"]; - isOneToOne: false; - referencedRelation: "socials"; - referencedColumns: ["id"]; + foreignKeyName: "social_fans_artist_social_id_fkey" + columns: ["artist_social_id"] + isOneToOne: false + referencedRelation: "socials" + referencedColumns: ["id"] }, { - foreignKeyName: "social_fans_fan_social_id_fkey"; - columns: ["fan_social_id"]; - isOneToOne: false; - referencedRelation: "socials"; - referencedColumns: ["id"]; + foreignKeyName: "social_fans_fan_social_id_fkey" + columns: ["fan_social_id"] + isOneToOne: false + referencedRelation: "socials" + referencedColumns: ["id"] }, { - foreignKeyName: "social_fans_latest_engagement_id_fkey"; - columns: ["latest_engagement_id"]; - isOneToOne: false; - referencedRelation: "post_comments"; - referencedColumns: ["id"]; + foreignKeyName: "social_fans_latest_engagement_id_fkey" + columns: ["latest_engagement_id"] + isOneToOne: false + referencedRelation: "post_comments" + referencedColumns: ["id"] }, - ]; - }; + ] + } social_posts: { Row: { - id: string; - post_id: string | null; - social_id: string | null; - updated_at: string | null; - }; + id: string + post_id: string | null + social_id: string | null + updated_at: string | null + } Insert: { - id?: string; - post_id?: string | null; - social_id?: string | null; - updated_at?: string | null; - }; + id?: string + post_id?: string | null + social_id?: string | null + updated_at?: string | null + } Update: { - id?: string; - post_id?: string | null; - social_id?: string | null; - updated_at?: string | null; - }; + id?: string + post_id?: string | null + social_id?: string | null + updated_at?: string | null + } Relationships: [ { - foreignKeyName: "social_posts_post_id_fkey"; - columns: ["post_id"]; - isOneToOne: false; - referencedRelation: "posts"; - referencedColumns: ["id"]; + foreignKeyName: "social_posts_post_id_fkey" + columns: ["post_id"] + isOneToOne: false + referencedRelation: "posts" + referencedColumns: ["id"] }, { - foreignKeyName: "social_posts_social_id_fkey"; - columns: ["social_id"]; - isOneToOne: false; - referencedRelation: "socials"; - referencedColumns: ["id"]; + foreignKeyName: "social_posts_social_id_fkey" + columns: ["social_id"] + isOneToOne: false + referencedRelation: "socials" + referencedColumns: ["id"] }, - ]; - }; + ] + } social_spotify_albums: { Row: { - album_id: string | null; - id: string; - social_id: string | null; - updated_at: string; - }; + album_id: string | null + id: string + social_id: string | null + updated_at: string + } Insert: { - album_id?: string | null; - id?: string; - social_id?: string | null; - updated_at?: string; - }; + album_id?: string | null + id?: string + social_id?: string | null + updated_at?: string + } Update: { - album_id?: string | null; - id?: string; - social_id?: string | null; - updated_at?: string; - }; + album_id?: string | null + id?: string + social_id?: string | null + updated_at?: string + } Relationships: [ { - foreignKeyName: "social_spotify_albums_album_id_fkey"; - columns: ["album_id"]; - isOneToOne: false; - referencedRelation: "spotify_albums"; - referencedColumns: ["id"]; + foreignKeyName: "social_spotify_albums_album_id_fkey" + columns: ["album_id"] + isOneToOne: false + referencedRelation: "spotify_albums" + referencedColumns: ["id"] }, { - foreignKeyName: "social_spotify_albums_social_id_fkey"; - columns: ["social_id"]; - isOneToOne: false; - referencedRelation: "socials"; - referencedColumns: ["id"]; + foreignKeyName: "social_spotify_albums_social_id_fkey" + columns: ["social_id"] + isOneToOne: false + referencedRelation: "socials" + referencedColumns: ["id"] }, - ]; - }; + ] + } social_spotify_tracks: { Row: { - id: string; - social_id: string; - track_id: string | null; - updated_at: string | null; - }; + id: string + social_id: string + track_id: string | null + updated_at: string | null + } Insert: { - id?: string; - social_id?: string; - track_id?: string | null; - updated_at?: string | null; - }; + id?: string + social_id?: string + track_id?: string | null + updated_at?: string | null + } Update: { - id?: string; - social_id?: string; - track_id?: string | null; - updated_at?: string | null; - }; + id?: string + social_id?: string + track_id?: string | null + updated_at?: string | null + } Relationships: [ { - foreignKeyName: "social_spotify_tracks_social_id_fkey"; - columns: ["social_id"]; - isOneToOne: false; - referencedRelation: "socials"; - referencedColumns: ["id"]; + foreignKeyName: "social_spotify_tracks_social_id_fkey" + columns: ["social_id"] + isOneToOne: false + referencedRelation: "socials" + referencedColumns: ["id"] }, { - foreignKeyName: "social_spotify_tracks_track_id_fkey"; - columns: ["track_id"]; - isOneToOne: false; - referencedRelation: "spotify_tracks"; - referencedColumns: ["id"]; + foreignKeyName: "social_spotify_tracks_track_id_fkey" + columns: ["track_id"] + isOneToOne: false + referencedRelation: "spotify_tracks" + referencedColumns: ["id"] }, - ]; - }; + ] + } socials: { Row: { - avatar: string | null; - bio: string | null; - followerCount: number | null; - followingCount: number | null; - id: string; - profile_url: string; - region: string | null; - updated_at: string; - username: string; - }; + avatar: string | null + bio: string | null + followerCount: number | null + followingCount: number | null + id: string + profile_url: string + region: string | null + updated_at: string + username: string + } Insert: { - avatar?: string | null; - bio?: string | null; - followerCount?: number | null; - followingCount?: number | null; - id?: string; - profile_url: string; - region?: string | null; - updated_at?: string; - username: string; - }; + avatar?: string | null + bio?: string | null + followerCount?: number | null + followingCount?: number | null + id?: string + profile_url: string + region?: string | null + updated_at?: string + username: string + } Update: { - avatar?: string | null; - bio?: string | null; - followerCount?: number | null; - followingCount?: number | null; - id?: string; - profile_url?: string; - region?: string | null; - updated_at?: string; - username?: string; - }; - Relationships: []; - }; + avatar?: string | null + bio?: string | null + followerCount?: number | null + followingCount?: number | null + id?: string + profile_url?: string + region?: string | null + updated_at?: string + username?: string + } + Relationships: [] + } song_artists: { Row: { - artist: string; - created_at: string; - id: string; - song: string; - updated_at: string; - }; + artist: string + created_at: string + id: string + song: string + updated_at: string + } Insert: { - artist: string; - created_at?: string; - id?: string; - song: string; - updated_at?: string; - }; + artist: string + created_at?: string + id?: string + song: string + updated_at?: string + } Update: { - artist?: string; - created_at?: string; - id?: string; - song?: string; - updated_at?: string; - }; + artist?: string + created_at?: string + id?: string + song?: string + updated_at?: string + } Relationships: [ { - foreignKeyName: "song_artists_artist_fkey"; - columns: ["artist"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "song_artists_artist_fkey" + columns: ["artist"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, { - foreignKeyName: "song_artists_song_fkey"; - columns: ["song"]; - isOneToOne: false; - referencedRelation: "songs"; - referencedColumns: ["isrc"]; + foreignKeyName: "song_artists_song_fkey" + columns: ["song"] + isOneToOne: false + referencedRelation: "songs" + referencedColumns: ["isrc"] }, - ]; - }; + ] + } songs: { Row: { - album: string | null; - isrc: string; - name: string | null; - notes: string | null; - updated_at: string; - }; + album: string | null + isrc: string + name: string | null + notes: string | null + updated_at: string + } Insert: { - album?: string | null; - isrc: string; - name?: string | null; - notes?: string | null; - updated_at?: string; - }; + album?: string | null + isrc: string + name?: string | null + notes?: string | null + updated_at?: string + } Update: { - album?: string | null; - isrc?: string; - name?: string | null; - notes?: string | null; - updated_at?: string; - }; - Relationships: []; - }; + album?: string | null + isrc?: string + name?: string | null + notes?: string | null + updated_at?: string + } + Relationships: [] + } spotify: { Row: { - clientId: string | null; - country: string | null; - display_name: string | null; - email: string | null; - "explicit_content.filter_enabled": string | null; - "explicit_content.filter_locked": string | null; - "external_urls.spotify": Json | null; - fanId: string | null; - "fanId.country": string | null; - "fanId.display_name": string | null; - "fanId.email": string | null; - "fanId.explicit_content.filter_enabled": string | null; - "fanId.explicit_content.filter_locked": string | null; - "fanId.external_urls.spotify": string | null; - "fanId.followers.total": string | null; - "fanId.href": string | null; - "fanId.id": string | null; - "fanId.images": string | null; - "fanId.isNewFan": string | null; - "fanId.playlist": string | null; - "fanId.presavedData.clientId": string | null; - "fanId.presavedData.country": string | null; - "fanId.presavedData.display_name": string | null; - "fanId.presavedData.email": string | null; - "fanId.presavedData.explicit_content.filter_enabled": string | null; - "fanId.presavedData.explicit_content.filter_locked": string | null; - "fanId.presavedData.external_urls.spotify": string | null; - "fanId.presavedData.followers.total": string | null; - "fanId.presavedData.href": string | null; - "fanId.presavedData.id": string | null; - "fanId.presavedData.images": string | null; - "fanId.presavedData.playlist": string | null; - "fanId.presavedData.product": string | null; - "fanId.presavedData.recentlyPlayed": string | null; - "fanId.presavedData.timestamp": string | null; - "fanId.presavedData.type": string | null; - "fanId.presavedData.uri": string | null; - "fanId.product": string | null; - "fanId.timestamp": string | null; - "fanId.type": string | null; - "fanId.uri": string | null; - "followers.total": Json | null; - game: string | null; - href: string | null; - id: string | null; - images: Json | null; - playlist: Json | null; - product: string | null; - syncId: string | null; - timestamp: string | null; - type: string | null; - uri: string | null; - }; + clientId: string | null + country: string | null + display_name: string | null + email: string | null + "explicit_content.filter_enabled": string | null + "explicit_content.filter_locked": string | null + "external_urls.spotify": Json | null + fanId: string | null + "fanId.country": string | null + "fanId.display_name": string | null + "fanId.email": string | null + "fanId.explicit_content.filter_enabled": string | null + "fanId.explicit_content.filter_locked": string | null + "fanId.external_urls.spotify": string | null + "fanId.followers.total": string | null + "fanId.href": string | null + "fanId.id": string | null + "fanId.images": string | null + "fanId.isNewFan": string | null + "fanId.playlist": string | null + "fanId.presavedData.clientId": string | null + "fanId.presavedData.country": string | null + "fanId.presavedData.display_name": string | null + "fanId.presavedData.email": string | null + "fanId.presavedData.explicit_content.filter_enabled": string | null + "fanId.presavedData.explicit_content.filter_locked": string | null + "fanId.presavedData.external_urls.spotify": string | null + "fanId.presavedData.followers.total": string | null + "fanId.presavedData.href": string | null + "fanId.presavedData.id": string | null + "fanId.presavedData.images": string | null + "fanId.presavedData.playlist": string | null + "fanId.presavedData.product": string | null + "fanId.presavedData.recentlyPlayed": string | null + "fanId.presavedData.timestamp": string | null + "fanId.presavedData.type": string | null + "fanId.presavedData.uri": string | null + "fanId.product": string | null + "fanId.timestamp": string | null + "fanId.type": string | null + "fanId.uri": string | null + "followers.total": Json | null + game: string | null + href: string | null + id: string | null + images: Json | null + playlist: Json | null + product: string | null + syncId: string | null + timestamp: string | null + type: string | null + uri: string | null + } Insert: { - clientId?: string | null; - country?: string | null; - display_name?: string | null; - email?: string | null; - "explicit_content.filter_enabled"?: string | null; - "explicit_content.filter_locked"?: string | null; - "external_urls.spotify"?: Json | null; - fanId?: string | null; - "fanId.country"?: string | null; - "fanId.display_name"?: string | null; - "fanId.email"?: string | null; - "fanId.explicit_content.filter_enabled"?: string | null; - "fanId.explicit_content.filter_locked"?: string | null; - "fanId.external_urls.spotify"?: string | null; - "fanId.followers.total"?: string | null; - "fanId.href"?: string | null; - "fanId.id"?: string | null; - "fanId.images"?: string | null; - "fanId.isNewFan"?: string | null; - "fanId.playlist"?: string | null; - "fanId.presavedData.clientId"?: string | null; - "fanId.presavedData.country"?: string | null; - "fanId.presavedData.display_name"?: string | null; - "fanId.presavedData.email"?: string | null; - "fanId.presavedData.explicit_content.filter_enabled"?: string | null; - "fanId.presavedData.explicit_content.filter_locked"?: string | null; - "fanId.presavedData.external_urls.spotify"?: string | null; - "fanId.presavedData.followers.total"?: string | null; - "fanId.presavedData.href"?: string | null; - "fanId.presavedData.id"?: string | null; - "fanId.presavedData.images"?: string | null; - "fanId.presavedData.playlist"?: string | null; - "fanId.presavedData.product"?: string | null; - "fanId.presavedData.recentlyPlayed"?: string | null; - "fanId.presavedData.timestamp"?: string | null; - "fanId.presavedData.type"?: string | null; - "fanId.presavedData.uri"?: string | null; - "fanId.product"?: string | null; - "fanId.timestamp"?: string | null; - "fanId.type"?: string | null; - "fanId.uri"?: string | null; - "followers.total"?: Json | null; - game?: string | null; - href?: string | null; - id?: string | null; - images?: Json | null; - playlist?: Json | null; - product?: string | null; - syncId?: string | null; - timestamp?: string | null; - type?: string | null; - uri?: string | null; - }; + clientId?: string | null + country?: string | null + display_name?: string | null + email?: string | null + "explicit_content.filter_enabled"?: string | null + "explicit_content.filter_locked"?: string | null + "external_urls.spotify"?: Json | null + fanId?: string | null + "fanId.country"?: string | null + "fanId.display_name"?: string | null + "fanId.email"?: string | null + "fanId.explicit_content.filter_enabled"?: string | null + "fanId.explicit_content.filter_locked"?: string | null + "fanId.external_urls.spotify"?: string | null + "fanId.followers.total"?: string | null + "fanId.href"?: string | null + "fanId.id"?: string | null + "fanId.images"?: string | null + "fanId.isNewFan"?: string | null + "fanId.playlist"?: string | null + "fanId.presavedData.clientId"?: string | null + "fanId.presavedData.country"?: string | null + "fanId.presavedData.display_name"?: string | null + "fanId.presavedData.email"?: string | null + "fanId.presavedData.explicit_content.filter_enabled"?: string | null + "fanId.presavedData.explicit_content.filter_locked"?: string | null + "fanId.presavedData.external_urls.spotify"?: string | null + "fanId.presavedData.followers.total"?: string | null + "fanId.presavedData.href"?: string | null + "fanId.presavedData.id"?: string | null + "fanId.presavedData.images"?: string | null + "fanId.presavedData.playlist"?: string | null + "fanId.presavedData.product"?: string | null + "fanId.presavedData.recentlyPlayed"?: string | null + "fanId.presavedData.timestamp"?: string | null + "fanId.presavedData.type"?: string | null + "fanId.presavedData.uri"?: string | null + "fanId.product"?: string | null + "fanId.timestamp"?: string | null + "fanId.type"?: string | null + "fanId.uri"?: string | null + "followers.total"?: Json | null + game?: string | null + href?: string | null + id?: string | null + images?: Json | null + playlist?: Json | null + product?: string | null + syncId?: string | null + timestamp?: string | null + type?: string | null + uri?: string | null + } Update: { - clientId?: string | null; - country?: string | null; - display_name?: string | null; - email?: string | null; - "explicit_content.filter_enabled"?: string | null; - "explicit_content.filter_locked"?: string | null; - "external_urls.spotify"?: Json | null; - fanId?: string | null; - "fanId.country"?: string | null; - "fanId.display_name"?: string | null; - "fanId.email"?: string | null; - "fanId.explicit_content.filter_enabled"?: string | null; - "fanId.explicit_content.filter_locked"?: string | null; - "fanId.external_urls.spotify"?: string | null; - "fanId.followers.total"?: string | null; - "fanId.href"?: string | null; - "fanId.id"?: string | null; - "fanId.images"?: string | null; - "fanId.isNewFan"?: string | null; - "fanId.playlist"?: string | null; - "fanId.presavedData.clientId"?: string | null; - "fanId.presavedData.country"?: string | null; - "fanId.presavedData.display_name"?: string | null; - "fanId.presavedData.email"?: string | null; - "fanId.presavedData.explicit_content.filter_enabled"?: string | null; - "fanId.presavedData.explicit_content.filter_locked"?: string | null; - "fanId.presavedData.external_urls.spotify"?: string | null; - "fanId.presavedData.followers.total"?: string | null; - "fanId.presavedData.href"?: string | null; - "fanId.presavedData.id"?: string | null; - "fanId.presavedData.images"?: string | null; - "fanId.presavedData.playlist"?: string | null; - "fanId.presavedData.product"?: string | null; - "fanId.presavedData.recentlyPlayed"?: string | null; - "fanId.presavedData.timestamp"?: string | null; - "fanId.presavedData.type"?: string | null; - "fanId.presavedData.uri"?: string | null; - "fanId.product"?: string | null; - "fanId.timestamp"?: string | null; - "fanId.type"?: string | null; - "fanId.uri"?: string | null; - "followers.total"?: Json | null; - game?: string | null; - href?: string | null; - id?: string | null; - images?: Json | null; - playlist?: Json | null; - product?: string | null; - syncId?: string | null; - timestamp?: string | null; - type?: string | null; - uri?: string | null; - }; - Relationships: []; - }; + clientId?: string | null + country?: string | null + display_name?: string | null + email?: string | null + "explicit_content.filter_enabled"?: string | null + "explicit_content.filter_locked"?: string | null + "external_urls.spotify"?: Json | null + fanId?: string | null + "fanId.country"?: string | null + "fanId.display_name"?: string | null + "fanId.email"?: string | null + "fanId.explicit_content.filter_enabled"?: string | null + "fanId.explicit_content.filter_locked"?: string | null + "fanId.external_urls.spotify"?: string | null + "fanId.followers.total"?: string | null + "fanId.href"?: string | null + "fanId.id"?: string | null + "fanId.images"?: string | null + "fanId.isNewFan"?: string | null + "fanId.playlist"?: string | null + "fanId.presavedData.clientId"?: string | null + "fanId.presavedData.country"?: string | null + "fanId.presavedData.display_name"?: string | null + "fanId.presavedData.email"?: string | null + "fanId.presavedData.explicit_content.filter_enabled"?: string | null + "fanId.presavedData.explicit_content.filter_locked"?: string | null + "fanId.presavedData.external_urls.spotify"?: string | null + "fanId.presavedData.followers.total"?: string | null + "fanId.presavedData.href"?: string | null + "fanId.presavedData.id"?: string | null + "fanId.presavedData.images"?: string | null + "fanId.presavedData.playlist"?: string | null + "fanId.presavedData.product"?: string | null + "fanId.presavedData.recentlyPlayed"?: string | null + "fanId.presavedData.timestamp"?: string | null + "fanId.presavedData.type"?: string | null + "fanId.presavedData.uri"?: string | null + "fanId.product"?: string | null + "fanId.timestamp"?: string | null + "fanId.type"?: string | null + "fanId.uri"?: string | null + "followers.total"?: Json | null + game?: string | null + href?: string | null + id?: string | null + images?: Json | null + playlist?: Json | null + product?: string | null + syncId?: string | null + timestamp?: string | null + type?: string | null + uri?: string | null + } + Relationships: [] + } spotify_albums: { Row: { - id: string; - name: string | null; - release_date: string | null; - updated_at: string; - uri: string; - }; + id: string + name: string | null + release_date: string | null + updated_at: string + uri: string + } Insert: { - id?: string; - name?: string | null; - release_date?: string | null; - updated_at?: string; - uri: string; - }; + id?: string + name?: string | null + release_date?: string | null + updated_at?: string + uri: string + } Update: { - id?: string; - name?: string | null; - release_date?: string | null; - updated_at?: string; - uri?: string; - }; - Relationships: []; - }; + id?: string + name?: string | null + release_date?: string | null + updated_at?: string + uri?: string + } + Relationships: [] + } spotify_analytics_albums: { Row: { - analysis_id: string | null; - artist_name: string | null; - created_at: string; - id: string; - name: string | null; - release_date: number | null; - uri: string | null; - }; + analysis_id: string | null + artist_name: string | null + created_at: string + id: string + name: string | null + release_date: number | null + uri: string | null + } Insert: { - analysis_id?: string | null; - artist_name?: string | null; - created_at?: string; - id?: string; - name?: string | null; - release_date?: number | null; - uri?: string | null; - }; + analysis_id?: string | null + artist_name?: string | null + created_at?: string + id?: string + name?: string | null + release_date?: number | null + uri?: string | null + } Update: { - analysis_id?: string | null; - artist_name?: string | null; - created_at?: string; - id?: string; - name?: string | null; - release_date?: number | null; - uri?: string | null; - }; + analysis_id?: string | null + artist_name?: string | null + created_at?: string + id?: string + name?: string | null + release_date?: number | null + uri?: string | null + } Relationships: [ { - foreignKeyName: "spotify_analytics_albums_analysis_id_fkey"; - columns: ["analysis_id"]; - isOneToOne: false; - referencedRelation: "funnel_analytics"; - referencedColumns: ["id"]; + foreignKeyName: "spotify_analytics_albums_analysis_id_fkey" + columns: ["analysis_id"] + isOneToOne: false + referencedRelation: "funnel_analytics" + referencedColumns: ["id"] }, - ]; - }; + ] + } spotify_analytics_tracks: { Row: { - analysis_id: string | null; - artist_name: string | null; - created_at: string; - id: string; - name: string | null; - popularity: number | null; - uri: string | null; - }; + analysis_id: string | null + artist_name: string | null + created_at: string + id: string + name: string | null + popularity: number | null + uri: string | null + } Insert: { - analysis_id?: string | null; - artist_name?: string | null; - created_at?: string; - id?: string; - name?: string | null; - popularity?: number | null; - uri?: string | null; - }; + analysis_id?: string | null + artist_name?: string | null + created_at?: string + id?: string + name?: string | null + popularity?: number | null + uri?: string | null + } Update: { - analysis_id?: string | null; - artist_name?: string | null; - created_at?: string; - id?: string; - name?: string | null; - popularity?: number | null; - uri?: string | null; - }; + analysis_id?: string | null + artist_name?: string | null + created_at?: string + id?: string + name?: string | null + popularity?: number | null + uri?: string | null + } Relationships: [ { - foreignKeyName: "spotify_analytics_tracks_analysis_id_fkey"; - columns: ["analysis_id"]; - isOneToOne: false; - referencedRelation: "funnel_analytics"; - referencedColumns: ["id"]; + foreignKeyName: "spotify_analytics_tracks_analysis_id_fkey" + columns: ["analysis_id"] + isOneToOne: false + referencedRelation: "funnel_analytics" + referencedColumns: ["id"] }, - ]; - }; + ] + } spotify_login_button_clicked: { Row: { - campaignId: string | null; - clientId: string | null; - fanId: string | null; - game: string | null; - id: string | null; - timestamp: number | null; - }; + campaignId: string | null + clientId: string | null + fanId: string | null + game: string | null + id: string | null + timestamp: number | null + } Insert: { - campaignId?: string | null; - clientId?: string | null; - fanId?: string | null; - game?: string | null; - id?: string | null; - timestamp?: number | null; - }; + campaignId?: string | null + clientId?: string | null + fanId?: string | null + game?: string | null + id?: string | null + timestamp?: number | null + } Update: { - campaignId?: string | null; - clientId?: string | null; - fanId?: string | null; - game?: string | null; - id?: string | null; - timestamp?: number | null; - }; + campaignId?: string | null + clientId?: string | null + fanId?: string | null + game?: string | null + id?: string | null + timestamp?: number | null + } Relationships: [ { - foreignKeyName: "spotify_login_button_clicked_campaignId_fkey"; - columns: ["campaignId"]; - isOneToOne: false; - referencedRelation: "campaigns"; - referencedColumns: ["id"]; + foreignKeyName: "spotify_login_button_clicked_campaignId_fkey" + columns: ["campaignId"] + isOneToOne: false + referencedRelation: "campaigns" + referencedColumns: ["id"] }, - ]; - }; + ] + } spotify_play_button_clicked: { Row: { - campaignId: string | null; - clientId: string | null; - fanId: string | null; - game: string | null; - id: string; - isPremium: boolean | null; - timestamp: number | null; - }; + campaignId: string | null + clientId: string | null + fanId: string | null + game: string | null + id: string + isPremium: boolean | null + timestamp: number | null + } Insert: { - campaignId?: string | null; - clientId?: string | null; - fanId?: string | null; - game?: string | null; - id?: string; - isPremium?: boolean | null; - timestamp?: number | null; - }; + campaignId?: string | null + clientId?: string | null + fanId?: string | null + game?: string | null + id?: string + isPremium?: boolean | null + timestamp?: number | null + } Update: { - campaignId?: string | null; - clientId?: string | null; - fanId?: string | null; - game?: string | null; - id?: string; - isPremium?: boolean | null; - timestamp?: number | null; - }; + campaignId?: string | null + clientId?: string | null + fanId?: string | null + game?: string | null + id?: string + isPremium?: boolean | null + timestamp?: number | null + } Relationships: [ { - foreignKeyName: "spotify_play_button_clicked_campaignId_fkey"; - columns: ["campaignId"]; - isOneToOne: false; - referencedRelation: "campaigns"; - referencedColumns: ["id"]; + foreignKeyName: "spotify_play_button_clicked_campaignId_fkey" + columns: ["campaignId"] + isOneToOne: false + referencedRelation: "campaigns" + referencedColumns: ["id"] }, { - foreignKeyName: "spotify_play_button_clicked_fanId_fkey"; - columns: ["fanId"]; - isOneToOne: false; - referencedRelation: "fans"; - referencedColumns: ["id"]; + foreignKeyName: "spotify_play_button_clicked_fanId_fkey" + columns: ["fanId"] + isOneToOne: false + referencedRelation: "fans" + referencedColumns: ["id"] }, - ]; - }; + ] + } spotify_tracks: { Row: { - id: string; - name: string | null; - popularity: number | null; - updated_at: string; - uri: string; - }; + id: string + name: string | null + popularity: number | null + updated_at: string + uri: string + } Insert: { - id?: string; - name?: string | null; - popularity?: number | null; - updated_at?: string; - uri: string; - }; + id?: string + name?: string | null + popularity?: number | null + updated_at?: string + uri: string + } Update: { - id?: string; - name?: string | null; - popularity?: number | null; - updated_at?: string; - uri?: string; - }; - Relationships: []; - }; + id?: string + name?: string | null + popularity?: number | null + updated_at?: string + uri?: string + } + Relationships: [] + } subscription_items: { Row: { - created_at: string; - id: string; - interval: string; - interval_count: number; - price_amount: number | null; - product_id: string; - quantity: number; - subscription_id: string; - type: Database["public"]["Enums"]["subscription_item_type"]; - updated_at: string; - variant_id: string; - }; + created_at: string + id: string + interval: string + interval_count: number + price_amount: number | null + product_id: string + quantity: number + subscription_id: string + type: Database["public"]["Enums"]["subscription_item_type"] + updated_at: string + variant_id: string + } Insert: { - created_at?: string; - id: string; - interval: string; - interval_count: number; - price_amount?: number | null; - product_id: string; - quantity?: number; - subscription_id: string; - type: Database["public"]["Enums"]["subscription_item_type"]; - updated_at?: string; - variant_id: string; - }; + created_at?: string + id: string + interval: string + interval_count: number + price_amount?: number | null + product_id: string + quantity?: number + subscription_id: string + type: Database["public"]["Enums"]["subscription_item_type"] + updated_at?: string + variant_id: string + } Update: { - created_at?: string; - id?: string; - interval?: string; - interval_count?: number; - price_amount?: number | null; - product_id?: string; - quantity?: number; - subscription_id?: string; - type?: Database["public"]["Enums"]["subscription_item_type"]; - updated_at?: string; - variant_id?: string; - }; + created_at?: string + id?: string + interval?: string + interval_count?: number + price_amount?: number | null + product_id?: string + quantity?: number + subscription_id?: string + type?: Database["public"]["Enums"]["subscription_item_type"] + updated_at?: string + variant_id?: string + } Relationships: [ { - foreignKeyName: "subscription_items_subscription_id_fkey"; - columns: ["subscription_id"]; - isOneToOne: false; - referencedRelation: "subscriptions"; - referencedColumns: ["id"]; + foreignKeyName: "subscription_items_subscription_id_fkey" + columns: ["subscription_id"] + isOneToOne: false + referencedRelation: "subscriptions" + referencedColumns: ["id"] }, - ]; - }; + ] + } subscriptions: { Row: { - account_id: string; - active: boolean; - billing_customer_id: number; - billing_provider: Database["public"]["Enums"]["billing_provider"]; - cancel_at_period_end: boolean; - created_at: string; - currency: string; - id: string; - period_ends_at: string; - period_starts_at: string; - status: Database["public"]["Enums"]["subscription_status"]; - trial_ends_at: string | null; - trial_starts_at: string | null; - updated_at: string; - }; + account_id: string + active: boolean + billing_customer_id: number + billing_provider: Database["public"]["Enums"]["billing_provider"] + cancel_at_period_end: boolean + created_at: string + currency: string + id: string + period_ends_at: string + period_starts_at: string + status: Database["public"]["Enums"]["subscription_status"] + trial_ends_at: string | null + trial_starts_at: string | null + updated_at: string + } Insert: { - account_id: string; - active: boolean; - billing_customer_id: number; - billing_provider: Database["public"]["Enums"]["billing_provider"]; - cancel_at_period_end: boolean; - created_at?: string; - currency: string; - id: string; - period_ends_at: string; - period_starts_at: string; - status: Database["public"]["Enums"]["subscription_status"]; - trial_ends_at?: string | null; - trial_starts_at?: string | null; - updated_at?: string; - }; + account_id: string + active: boolean + billing_customer_id: number + billing_provider: Database["public"]["Enums"]["billing_provider"] + cancel_at_period_end: boolean + created_at?: string + currency: string + id: string + period_ends_at: string + period_starts_at: string + status: Database["public"]["Enums"]["subscription_status"] + trial_ends_at?: string | null + trial_starts_at?: string | null + updated_at?: string + } Update: { - account_id?: string; - active?: boolean; - billing_customer_id?: number; - billing_provider?: Database["public"]["Enums"]["billing_provider"]; - cancel_at_period_end?: boolean; - created_at?: string; - currency?: string; - id?: string; - period_ends_at?: string; - period_starts_at?: string; - status?: Database["public"]["Enums"]["subscription_status"]; - trial_ends_at?: string | null; - trial_starts_at?: string | null; - updated_at?: string; - }; + account_id?: string + active?: boolean + billing_customer_id?: number + billing_provider?: Database["public"]["Enums"]["billing_provider"] + cancel_at_period_end?: boolean + created_at?: string + currency?: string + id?: string + period_ends_at?: string + period_starts_at?: string + status?: Database["public"]["Enums"]["subscription_status"] + trial_ends_at?: string | null + trial_starts_at?: string | null + updated_at?: string + } Relationships: [ { - foreignKeyName: "subscriptions_billing_customer_id_fkey"; - columns: ["billing_customer_id"]; - isOneToOne: false; - referencedRelation: "billing_customers"; - referencedColumns: ["id"]; + foreignKeyName: "subscriptions_billing_customer_id_fkey" + columns: ["billing_customer_id"] + isOneToOne: false + referencedRelation: "billing_customers" + referencedColumns: ["id"] }, - ]; - }; + ] + } tasks: { Row: { - account_id: string; - created_at: string; - description: string | null; - done: boolean; - id: string; - title: string; - updated_at: string; - }; + account_id: string + created_at: string + description: string | null + done: boolean + id: string + title: string + updated_at: string + } Insert: { - account_id: string; - created_at?: string; - description?: string | null; - done?: boolean; - id?: string; - title: string; - updated_at?: string; - }; + account_id: string + created_at?: string + description?: string | null + done?: boolean + id?: string + title: string + updated_at?: string + } Update: { - account_id?: string; - created_at?: string; - description?: string | null; - done?: boolean; - id?: string; - title?: string; - updated_at?: string; - }; - Relationships: []; - }; + account_id?: string + created_at?: string + description?: string | null + done?: boolean + id?: string + title?: string + updated_at?: string + } + Relationships: [] + } test_emails: { Row: { - created_at: string; - email: string | null; - id: number; - }; + created_at: string + email: string | null + id: number + } Insert: { - created_at?: string; - email?: string | null; - id?: number; - }; + created_at?: string + email?: string | null + id?: number + } Update: { - created_at?: string; - email?: string | null; - id?: number; - }; - Relationships: []; - }; + created_at?: string + email?: string | null + id?: number + } + Relationships: [] + } usage_events: { Row: { - account_id: string; - agent_type: string; - cached_input_tokens: number; - created_at: string; - credits_deducted_cents: number; - id: string; - input_tokens: number; - model_id: string | null; - output_tokens: number; - provider: string | null; - source: string; - tool_call_count: number; - }; + account_id: string + agent_type: string + cached_input_tokens: number + created_at: string + credits_deducted_cents: number + id: string + input_tokens: number + model_id: string | null + output_tokens: number + provider: string | null + source: string + tool_call_count: number + } Insert: { - account_id: string; - agent_type?: string; - cached_input_tokens?: number; - created_at?: string; - credits_deducted_cents?: number; - id: string; - input_tokens?: number; - model_id?: string | null; - output_tokens?: number; - provider?: string | null; - source?: string; - tool_call_count?: number; - }; + account_id: string + agent_type?: string + cached_input_tokens?: number + created_at?: string + credits_deducted_cents?: number + id: string + input_tokens?: number + model_id?: string | null + output_tokens?: number + provider?: string | null + source?: string + tool_call_count?: number + } Update: { - account_id?: string; - agent_type?: string; - cached_input_tokens?: number; - created_at?: string; - credits_deducted_cents?: number; - id?: string; - input_tokens?: number; - model_id?: string | null; - output_tokens?: number; - provider?: string | null; - source?: string; - tool_call_count?: number; - }; + account_id?: string + agent_type?: string + cached_input_tokens?: number + created_at?: string + credits_deducted_cents?: number + id?: string + input_tokens?: number + model_id?: string | null + output_tokens?: number + provider?: string | null + source?: string + tool_call_count?: number + } Relationships: [ { - foreignKeyName: "usage_events_account_id_fkey"; - columns: ["account_id"]; - isOneToOne: false; - referencedRelation: "accounts"; - referencedColumns: ["id"]; + foreignKeyName: "usage_events_account_id_fkey" + columns: ["account_id"] + isOneToOne: false + referencedRelation: "accounts" + referencedColumns: ["id"] }, - ]; - }; + ] + } workflow_run_steps: { Row: { - created_at: string; - duration_ms: number; - finish_reason: string | null; - finished_at: string; - id: string; - raw_finish_reason: string | null; - started_at: string; - step_number: number; - workflow_run_id: string; - }; + created_at: string + duration_ms: number + finish_reason: string | null + finished_at: string + id: string + raw_finish_reason: string | null + started_at: string + step_number: number + workflow_run_id: string + } Insert: { - created_at?: string; - duration_ms: number; - finish_reason?: string | null; - finished_at: string; - id: string; - raw_finish_reason?: string | null; - started_at: string; - step_number: number; - workflow_run_id: string; - }; + created_at?: string + duration_ms: number + finish_reason?: string | null + finished_at: string + id: string + raw_finish_reason?: string | null + started_at: string + step_number: number + workflow_run_id: string + } Update: { - created_at?: string; - duration_ms?: number; - finish_reason?: string | null; - finished_at?: string; - id?: string; - raw_finish_reason?: string | null; - started_at?: string; - step_number?: number; - workflow_run_id?: string; - }; + created_at?: string + duration_ms?: number + finish_reason?: string | null + finished_at?: string + id?: string + raw_finish_reason?: string | null + started_at?: string + step_number?: number + workflow_run_id?: string + } Relationships: [ { - foreignKeyName: "workflow_run_steps_workflow_run_id_fkey"; - columns: ["workflow_run_id"]; - isOneToOne: false; - referencedRelation: "workflow_runs"; - referencedColumns: ["id"]; + foreignKeyName: "workflow_run_steps_workflow_run_id_fkey" + columns: ["workflow_run_id"] + isOneToOne: false + referencedRelation: "workflow_runs" + referencedColumns: ["id"] }, - ]; - }; + ] + } workflow_runs: { Row: { - chat_id: string; - created_at: string; - finished_at: string; - id: string; - model_id: string | null; - started_at: string; - status: string; - total_duration_ms: number; - }; + chat_id: string + created_at: string + finished_at: string + id: string + model_id: string | null + started_at: string + status: string + total_duration_ms: number + } Insert: { - chat_id: string; - created_at?: string; - finished_at: string; - id: string; - model_id?: string | null; - started_at: string; - status: string; - total_duration_ms: number; - }; + chat_id: string + created_at?: string + finished_at: string + id: string + model_id?: string | null + started_at: string + status: string + total_duration_ms: number + } Update: { - chat_id?: string; - created_at?: string; - finished_at?: string; - id?: string; - model_id?: string | null; - started_at?: string; - status?: string; - total_duration_ms?: number; - }; + chat_id?: string + created_at?: string + finished_at?: string + id?: string + model_id?: string | null + started_at?: string + status?: string + total_duration_ms?: number + } Relationships: [ { - foreignKeyName: "workflow_runs_chat_id_fkey"; - columns: ["chat_id"]; - isOneToOne: false; - referencedRelation: "chats"; - referencedColumns: ["id"]; + foreignKeyName: "workflow_runs_chat_id_fkey" + columns: ["chat_id"] + isOneToOne: false + referencedRelation: "chats" + referencedColumns: ["id"] }, - ]; - }; - }; + ] + } + } Views: { - [_ in never]: never; - }; + [_ in never]: never + } Functions: { accept_invitation: { - Args: { token: string; user_id: string }; - Returns: string; - }; + Args: { token: string; user_id: string } + Returns: string + } add_invitations_to_account: { Args: { - account_slug: string; - invitations: Database["public"]["CompositeTypes"]["invitation"][]; - }; - Returns: Database["public"]["Tables"]["invitations"]["Row"][]; - }; + account_slug: string + invitations: Database["public"]["CompositeTypes"]["invitation"][] + } + Returns: Database["public"]["Tables"]["invitations"]["Row"][] + } can_action_account_member: { - Args: { target_team_account_id: string; target_user_id: string }; - Returns: boolean; - }; + Args: { target_team_account_id: string; target_user_id: string } + Returns: boolean + } count_reports_by_day: { - Args: { end_date: string; start_date: string }; + Args: { end_date: string; start_date: string } Returns: { - count: number; - date_key: string; - }[]; - }; + count: number + date_key: string + }[] + } count_reports_by_month: { - Args: { end_date: string; start_date: string }; + Args: { end_date: string; start_date: string } Returns: { - count: number; - date_key: string; - }[]; - }; + count: number + date_key: string + }[] + } count_reports_by_week: { - Args: { end_date: string; start_date: string }; + Args: { end_date: string; start_date: string } Returns: { - count: number; - date_key: string; - }[]; - }; + count: number + date_key: string + }[] + } create_invitation: { - Args: { account_id: string; email: string; role: string }; + Args: { account_id: string; email: string; role: string } Returns: { - account_id: string; - created_at: string; - email: string; - expires_at: string; - id: number; - invite_token: string; - invited_by: string; - role: string; - updated_at: string; - }; + account_id: string + created_at: string + email: string + expires_at: string + id: number + invite_token: string + invited_by: string + role: string + updated_at: string + } SetofOptions: { - from: "*"; - to: "invitations"; - isOneToOne: true; - isSetofReturn: false; - }; - }; + from: "*" + to: "invitations" + isOneToOne: true + isSetofReturn: false + } + } deduct_credits: { - Args: { account_id: string; amount: number }; - Returns: undefined; - }; + Args: { account_id: string; amount: number } + Returns: undefined + } deduct_credits_with_audit: { Args: { - p_account_id: string; - p_amount: number; - p_event: Json; - p_event_id: string; - }; - Returns: undefined; - }; - extract_domain: { Args: { email: string }; Returns: string }; + p_account_id: string + p_amount: number + p_event: Json + p_event_id: string + } + Returns: undefined + } + extract_domain: { Args: { email: string }; Returns: string } get_account_invitations: { - Args: { account_slug: string }; + Args: { account_slug: string } Returns: { - account_id: string; - created_at: string; - email: string; - expires_at: string; - id: number; - invited_by: string; - inviter_email: string; - inviter_name: string; - role: string; - updated_at: string; - }[]; - }; + account_id: string + created_at: string + email: string + expires_at: string + id: number + invited_by: string + inviter_email: string + inviter_name: string + role: string + updated_at: string + }[] + } get_account_members: { - Args: { account_slug: string }; + Args: { account_slug: string } Returns: { - account_id: string; - created_at: string; - email: string; - id: string; - name: string; - picture_url: string; - primary_owner_user_id: string; - role: string; - role_hierarchy_level: number; - updated_at: string; - user_id: string; - }[]; - }; + account_id: string + created_at: string + email: string + id: string + name: string + picture_url: string + primary_owner_user_id: string + role: string + role_hierarchy_level: number + updated_at: string + user_id: string + }[] + } get_campaign: | { Args: { clientid: string }; Returns: Json } | { - Args: { artistid: string; campaignid: string; email: string }; - Returns: Json; - }; + Args: { artistid: string; campaignid: string; email: string } + Returns: Json + } get_campaign_fans: { - Args: { artistid: string; email: string }; - Returns: Json; - }; - get_config: { Args: never; Returns: Json }; + Args: { artistid: string; email: string } + Returns: Json + } + get_config: { Args: never; Returns: Json } get_fans_listening_top_songs: { - Args: { artistid: string; email: string }; - Returns: Json; - }; + Args: { artistid: string; email: string } + Returns: Json + } get_message_counts_by_user: | { - Args: { start_date: string }; + Args: { start_date: string } Returns: { - account_email: string; - message_count: number; - }[]; + account_email: string + message_count: number + }[] } | { - Args: { end_date: string; start_date: string }; + Args: { end_date: string; start_date: string } Returns: { - account_email: string; - message_count: number; - }[]; - }; + account_email: string + message_count: number + }[] + } get_rooms_created_by_user: { - Args: { start_date: string }; + Args: { start_date: string } Returns: { - account_email: string; - rooms_created: number; - }[]; - }; + account_email: string + rooms_created: number + }[] + } get_segment_reports_by_user: { - Args: { start_date: string }; + Args: { start_date: string } Returns: { - email: string; - segment_report_count: number; - }[]; - }; - get_upper_system_role: { Args: never; Returns: string }; + email: string + segment_report_count: number + }[] + } + get_upper_system_role: { Args: never; Returns: string } has_active_subscription: { - Args: { target_account_id: string }; - Returns: boolean; - }; - has_credits: { Args: { account_id: string }; Returns: boolean }; + Args: { target_account_id: string } + Returns: boolean + } + has_credits: { Args: { account_id: string }; Returns: boolean } has_more_elevated_role: { Args: { - role_name: string; - target_account_id: string; - target_user_id: string; - }; - Returns: boolean; - }; + role_name: string + target_account_id: string + target_user_id: string + } + Returns: boolean + } has_permission: { Args: { - account_id: string; - permission_name: Database["public"]["Enums"]["app_permissions"]; - user_id: string; - }; - Returns: boolean; - }; + account_id: string + permission_name: Database["public"]["Enums"]["app_permissions"] + user_id: string + } + Returns: boolean + } has_role_on_account: { - Args: { account_id: string; account_role?: string }; - Returns: boolean; - }; + Args: { account_id: string; account_role?: string } + Returns: boolean + } has_same_role_hierarchy_level: { Args: { - role_name: string; - target_account_id: string; - target_user_id: string; - }; - Returns: boolean; - }; - is_account_owner: { Args: { account_id: string }; Returns: boolean }; + role_name: string + target_account_id: string + target_user_id: string + } + Returns: boolean + } + is_account_owner: { Args: { account_id: string }; Returns: boolean } is_account_team_member: { - Args: { target_account_id: string }; - Returns: boolean; - }; - is_set: { Args: { field_name: string }; Returns: boolean }; + Args: { target_account_id: string } + Returns: boolean + } + is_set: { Args: { field_name: string }; Returns: boolean } is_team_member: { - Args: { account_id: string; user_id: string }; - Returns: boolean; - }; + Args: { account_id: string; user_id: string } + Returns: boolean + } team_account_workspace: { - Args: { account_slug: string }; + Args: { account_slug: string } Returns: { - id: string; - name: string; - permissions: Database["public"]["Enums"]["app_permissions"][]; - picture_url: string; - primary_owner_user_id: string; - role: string; - role_hierarchy_level: number; - slug: string; - subscription_status: Database["public"]["Enums"]["subscription_status"]; - }[]; - }; + id: string + name: string + permissions: Database["public"]["Enums"]["app_permissions"][] + picture_url: string + primary_owner_user_id: string + role: string + role_hierarchy_level: number + slug: string + subscription_status: Database["public"]["Enums"]["subscription_status"] + }[] + } transfer_team_account_ownership: { - Args: { new_owner_id: string; target_account_id: string }; - Returns: undefined; - }; + Args: { new_owner_id: string; target_account_id: string } + Returns: undefined + } upsert_order: { Args: { - billing_provider: Database["public"]["Enums"]["billing_provider"]; - currency: string; - line_items: Json; - status: Database["public"]["Enums"]["payment_status"]; - target_account_id: string; - target_customer_id: string; - target_order_id: string; - total_amount: number; - }; + billing_provider: Database["public"]["Enums"]["billing_provider"] + currency: string + line_items: Json + status: Database["public"]["Enums"]["payment_status"] + target_account_id: string + target_customer_id: string + target_order_id: string + total_amount: number + } Returns: { - account_id: string; - billing_customer_id: number; - billing_provider: Database["public"]["Enums"]["billing_provider"]; - created_at: string; - currency: string; - id: string; - status: Database["public"]["Enums"]["payment_status"]; - total_amount: number; - updated_at: string; - }; + account_id: string + billing_customer_id: number + billing_provider: Database["public"]["Enums"]["billing_provider"] + created_at: string + currency: string + id: string + status: Database["public"]["Enums"]["payment_status"] + total_amount: number + updated_at: string + } SetofOptions: { - from: "*"; - to: "orders"; - isOneToOne: true; - isSetofReturn: false; - }; - }; + from: "*" + to: "orders" + isOneToOne: true + isSetofReturn: false + } + } upsert_subscription: { Args: { - active: boolean; - billing_provider: Database["public"]["Enums"]["billing_provider"]; - cancel_at_period_end: boolean; - currency: string; - line_items: Json; - period_ends_at: string; - period_starts_at: string; - status: Database["public"]["Enums"]["subscription_status"]; - target_account_id: string; - target_customer_id: string; - target_subscription_id: string; - trial_ends_at?: string; - trial_starts_at?: string; - }; + active: boolean + billing_provider: Database["public"]["Enums"]["billing_provider"] + cancel_at_period_end: boolean + currency: string + line_items: Json + period_ends_at: string + period_starts_at: string + status: Database["public"]["Enums"]["subscription_status"] + target_account_id: string + target_customer_id: string + target_subscription_id: string + trial_ends_at?: string + trial_starts_at?: string + } Returns: { - account_id: string; - active: boolean; - billing_customer_id: number; - billing_provider: Database["public"]["Enums"]["billing_provider"]; - cancel_at_period_end: boolean; - created_at: string; - currency: string; - id: string; - period_ends_at: string; - period_starts_at: string; - status: Database["public"]["Enums"]["subscription_status"]; - trial_ends_at: string | null; - trial_starts_at: string | null; - updated_at: string; - }; + account_id: string + active: boolean + billing_customer_id: number + billing_provider: Database["public"]["Enums"]["billing_provider"] + cancel_at_period_end: boolean + created_at: string + currency: string + id: string + period_ends_at: string + period_starts_at: string + status: Database["public"]["Enums"]["subscription_status"] + trial_ends_at: string | null + trial_starts_at: string | null + updated_at: string + } SetofOptions: { - from: "*"; - to: "subscriptions"; - isOneToOne: true; - isSetofReturn: false; - }; - }; - }; + from: "*" + to: "subscriptions" + isOneToOne: true + isSetofReturn: false + } + } + } Enums: { app_permissions: | "roles.manage" @@ -4195,14 +4201,20 @@ export type Database = { | "members.manage" | "invites.manage" | "tasks.write" - | "tasks.delete"; - billing_provider: "stripe" | "lemon-squeezy" | "paddle"; - chat_role: "user" | "assistant"; - notification_channel: "in_app" | "email"; - notification_type: "info" | "warning" | "error"; - payment_status: "pending" | "succeeded" | "failed"; - social_type: "TIKTOK" | "YOUTUBE" | "INSTAGRAM" | "TWITTER" | "SPOTIFY" | "APPLE"; - subscription_item_type: "flat" | "per_seat" | "metered"; + | "tasks.delete" + billing_provider: "stripe" | "lemon-squeezy" | "paddle" + chat_role: "user" | "assistant" + notification_channel: "in_app" | "email" + notification_type: "info" | "warning" | "error" + payment_status: "pending" | "succeeded" | "failed" + social_type: + | "TIKTOK" + | "YOUTUBE" + | "INSTAGRAM" + | "TWITTER" + | "SPOTIFY" + | "APPLE" + subscription_item_type: "flat" | "per_seat" | "metered" subscription_status: | "active" | "trialing" @@ -4211,131 +4223,133 @@ export type Database = { | "unpaid" | "incomplete" | "incomplete_expired" - | "paused"; - }; + | "paused" + } CompositeTypes: { invitation: { - email: string | null; - role: string | null; - }; - }; - }; -}; + email: string | null + role: string | null + } + } + } +} -type DatabaseWithoutInternals = Omit; +type DatabaseWithoutInternals = Omit -type DefaultSchema = DatabaseWithoutInternals[Extract]; +type DefaultSchema = DatabaseWithoutInternals[Extract] export type Tables< DefaultSchemaTableNameOrOptions extends | keyof (DefaultSchema["Tables"] & DefaultSchema["Views"]) | { schema: keyof DatabaseWithoutInternals }, TableName extends DefaultSchemaTableNameOrOptions extends { - schema: keyof DatabaseWithoutInternals; + schema: keyof DatabaseWithoutInternals } ? keyof (DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] & DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Views"]) : never = never, > = DefaultSchemaTableNameOrOptions extends { - schema: keyof DatabaseWithoutInternals; + schema: keyof DatabaseWithoutInternals } ? (DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] & DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Views"])[TableName] extends { - Row: infer R; + Row: infer R } ? R : never - : DefaultSchemaTableNameOrOptions extends keyof (DefaultSchema["Tables"] & DefaultSchema["Views"]) - ? (DefaultSchema["Tables"] & DefaultSchema["Views"])[DefaultSchemaTableNameOrOptions] extends { - Row: infer R; + : DefaultSchemaTableNameOrOptions extends keyof (DefaultSchema["Tables"] & + DefaultSchema["Views"]) + ? (DefaultSchema["Tables"] & + DefaultSchema["Views"])[DefaultSchemaTableNameOrOptions] extends { + Row: infer R } ? R : never - : never; + : never export type TablesInsert< DefaultSchemaTableNameOrOptions extends | keyof DefaultSchema["Tables"] | { schema: keyof DatabaseWithoutInternals }, TableName extends DefaultSchemaTableNameOrOptions extends { - schema: keyof DatabaseWithoutInternals; + schema: keyof DatabaseWithoutInternals } ? keyof DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] : never = never, > = DefaultSchemaTableNameOrOptions extends { - schema: keyof DatabaseWithoutInternals; + schema: keyof DatabaseWithoutInternals } ? DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"][TableName] extends { - Insert: infer I; + Insert: infer I } ? I : never : DefaultSchemaTableNameOrOptions extends keyof DefaultSchema["Tables"] ? DefaultSchema["Tables"][DefaultSchemaTableNameOrOptions] extends { - Insert: infer I; + Insert: infer I } ? I : never - : never; + : never export type TablesUpdate< DefaultSchemaTableNameOrOptions extends | keyof DefaultSchema["Tables"] | { schema: keyof DatabaseWithoutInternals }, TableName extends DefaultSchemaTableNameOrOptions extends { - schema: keyof DatabaseWithoutInternals; + schema: keyof DatabaseWithoutInternals } ? keyof DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] : never = never, > = DefaultSchemaTableNameOrOptions extends { - schema: keyof DatabaseWithoutInternals; + schema: keyof DatabaseWithoutInternals } ? DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"][TableName] extends { - Update: infer U; + Update: infer U } ? U : never : DefaultSchemaTableNameOrOptions extends keyof DefaultSchema["Tables"] ? DefaultSchema["Tables"][DefaultSchemaTableNameOrOptions] extends { - Update: infer U; + Update: infer U } ? U : never - : never; + : never export type Enums< DefaultSchemaEnumNameOrOptions extends | keyof DefaultSchema["Enums"] | { schema: keyof DatabaseWithoutInternals }, EnumName extends DefaultSchemaEnumNameOrOptions extends { - schema: keyof DatabaseWithoutInternals; + schema: keyof DatabaseWithoutInternals } ? keyof DatabaseWithoutInternals[DefaultSchemaEnumNameOrOptions["schema"]]["Enums"] : never = never, > = DefaultSchemaEnumNameOrOptions extends { - schema: keyof DatabaseWithoutInternals; + schema: keyof DatabaseWithoutInternals } ? DatabaseWithoutInternals[DefaultSchemaEnumNameOrOptions["schema"]]["Enums"][EnumName] : DefaultSchemaEnumNameOrOptions extends keyof DefaultSchema["Enums"] ? DefaultSchema["Enums"][DefaultSchemaEnumNameOrOptions] - : never; + : never export type CompositeTypes< PublicCompositeTypeNameOrOptions extends | keyof DefaultSchema["CompositeTypes"] | { schema: keyof DatabaseWithoutInternals }, CompositeTypeName extends PublicCompositeTypeNameOrOptions extends { - schema: keyof DatabaseWithoutInternals; + schema: keyof DatabaseWithoutInternals } ? keyof DatabaseWithoutInternals[PublicCompositeTypeNameOrOptions["schema"]]["CompositeTypes"] : never = never, > = PublicCompositeTypeNameOrOptions extends { - schema: keyof DatabaseWithoutInternals; + schema: keyof DatabaseWithoutInternals } ? DatabaseWithoutInternals[PublicCompositeTypeNameOrOptions["schema"]]["CompositeTypes"][CompositeTypeName] : PublicCompositeTypeNameOrOptions extends keyof DefaultSchema["CompositeTypes"] ? DefaultSchema["CompositeTypes"][PublicCompositeTypeNameOrOptions] - : never; + : never export const Constants = { public: { @@ -4354,7 +4368,14 @@ export const Constants = { notification_channel: ["in_app", "email"], notification_type: ["info", "warning", "error"], payment_status: ["pending", "succeeded", "failed"], - social_type: ["TIKTOK", "YOUTUBE", "INSTAGRAM", "TWITTER", "SPOTIFY", "APPLE"], + social_type: [ + "TIKTOK", + "YOUTUBE", + "INSTAGRAM", + "TWITTER", + "SPOTIFY", + "APPLE", + ], subscription_item_type: ["flat", "per_seat", "metered"], subscription_status: [ "active", @@ -4368,4 +4389,4 @@ export const Constants = { ], }, }, -} as const; +} as const From fb1ff0caf732e5197cba513137f26d6b16a6412d Mon Sep 17 00:00:00 2001 From: Sweets Sweetman Date: Sat, 30 May 2026 21:56:43 -0500 Subject: [PATCH 6/8] feat(chats): project artistId + apply artist filter + fix cubic P1s MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Matches the docs#227 contract that GET /api/chats responses include `artistId` and the `artist_account_id` query param is a real filter. - selectChatsWithSessions: project `session.artist_id` in SELECT; accept `artistAccountId` param; `.eq("session.artist_id", id)` when set. - validateGetChatsRequest: return `artistAccountId` on the scope. Fix the unreachable Recoup-admin branch (cubic P1) — check `account_organization_ids` membership instead of `auth.orgId`, which is always null for Bearer tokens. Bearer-authed admins now get the same admin scope as x-api-key org admins. - getChatsHandler: pass `artistAccountId` to the select; include `artistId` in the per-row projection. 500 catch block now returns hardcoded "Internal server error" instead of echoing the raw exception message (cubic P1 — no leaking internals on 500). - registerGetChatsTool (MCP): same projection/filter changes; same admin-via-membership fix. - Tests: updated mocks for getAccountOrganizations, refreshed admin scope cases, added composed filter + artistId-null cases, and updated the 500 expectation to "Internal server error" (cubic). Co-Authored-By: Claude Opus 4.7 (1M context) --- lib/chats/__tests__/getChatsHandler.test.ts | 103 ++++++++++++++---- .../__tests__/validateGetChatsRequest.test.ts | 73 ++++++++++--- lib/chats/getChatsHandler.ts | 24 ++-- lib/chats/validateGetChatsRequest.ts | 32 ++++-- .../__tests__/registerGetChatsTool.test.ts | 78 ++++++++----- lib/mcp/tools/chats/registerGetChatsTool.ts | 28 +++-- .../__tests__/selectChatsWithSessions.test.ts | 28 ++++- lib/supabase/chats/selectChatsWithSessions.ts | 19 +++- 8 files changed, 282 insertions(+), 103 deletions(-) diff --git a/lib/chats/__tests__/getChatsHandler.test.ts b/lib/chats/__tests__/getChatsHandler.test.ts index f453028ce..f6b445a0b 100644 --- a/lib/chats/__tests__/getChatsHandler.test.ts +++ b/lib/chats/__tests__/getChatsHandler.test.ts @@ -4,6 +4,7 @@ import { getChatsHandler } from "../getChatsHandler"; import { validateAuthContext } from "@/lib/auth/validateAuthContext"; import { canAccessAccount } from "@/lib/organizations/canAccessAccount"; +import { getAccountOrganizations } from "@/lib/supabase/account_organization_ids/getAccountOrganizations"; import { selectChatsWithSessions } from "@/lib/supabase/chats/selectChatsWithSessions"; vi.mock("@/lib/auth/validateAuthContext", () => ({ @@ -14,6 +15,10 @@ vi.mock("@/lib/organizations/canAccessAccount", () => ({ canAccessAccount: vi.fn(), })); +vi.mock("@/lib/supabase/account_organization_ids/getAccountOrganizations", () => ({ + getAccountOrganizations: vi.fn(), +})); + vi.mock("@/lib/supabase/chats/selectChatsWithSessions", () => ({ selectChatsWithSessions: vi.fn(), })); @@ -38,9 +43,16 @@ function createMockRequest(url: string, apiKey = "test-api-key"): NextRequest { } as unknown as NextRequest; } +/** Fixture helper — a session embed with optional artist id. */ +function sessionEmbed(accountId: string, artistId: string | null = null) { + return { id: "sess-1", account_id: accountId, artist_id: artistId }; +} + describe("getChatsHandler", () => { beforeEach(() => { vi.clearAllMocks(); + // Default: caller is NOT in Recoup org — admin tests override. + vi.mocked(getAccountOrganizations).mockResolvedValue([]); }); describe("authentication", () => { @@ -62,6 +74,7 @@ describe("getChatsHandler", () => { describe("personal key behavior", () => { it("returns chats projected to the new shape for personal key", async () => { const accountId = "123e4567-e89b-12d3-a456-426614174000"; + const artistId = "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa"; vi.mocked(validateAuthContext).mockResolvedValue({ accountId, orgId: null, @@ -77,7 +90,7 @@ describe("getChatsHandler", () => { active_stream_id: null, last_assistant_message_at: null, model_id: null, - session: { id: "sess-1", account_id: accountId }, + session: sessionEmbed(accountId, artistId), }, ]); @@ -94,9 +107,41 @@ describe("getChatsHandler", () => { accountId, sessionId: "sess-1", updatedAt: "2024-01-02T00:00:00Z", + artistId, }, ]); - expect(selectChatsWithSessions).toHaveBeenCalledWith({ accountIds: [accountId] }); + expect(selectChatsWithSessions).toHaveBeenCalledWith({ + accountIds: [accountId], + artistAccountId: undefined, + }); + }); + + it("surfaces artistId as null when session has no artist", async () => { + const accountId = "123e4567-e89b-12d3-a456-426614174000"; + vi.mocked(validateAuthContext).mockResolvedValue({ + accountId, + orgId: null, + authToken: "test-token", + }); + vi.mocked(selectChatsWithSessions).mockResolvedValue([ + { + id: "chat-1", + title: "Hello", + session_id: "sess-1", + updated_at: "2024-01-02T00:00:00Z", + created_at: "2024-01-01T00:00:00Z", + active_stream_id: null, + last_assistant_message_at: null, + model_id: null, + session: sessionEmbed(accountId, null), + }, + ]); + + const request = createMockRequest("http://localhost/api/chats"); + const response = await getChatsHandler(request); + const json = await response.json(); + + expect(json.chats[0].artistId).toBeNull(); }); it("returns 403 when personal key tries to filter by account_id", async () => { @@ -120,10 +165,10 @@ describe("getChatsHandler", () => { }); }); - describe("backwards compat", () => { - it("accepts artist_account_id but does not filter on it", async () => { + describe("artist filter", () => { + it("passes artist_account_id through to the select", async () => { const accountId = "123e4567-e89b-12d3-a456-426614174000"; - const artistId = "223e4567-e89b-12d3-a456-426614174001"; + const artistAccountId = "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa"; vi.mocked(validateAuthContext).mockResolvedValue({ accountId, @@ -132,39 +177,48 @@ describe("getChatsHandler", () => { }); vi.mocked(selectChatsWithSessions).mockResolvedValue([]); - const request = createMockRequest(`http://localhost/api/chats?artist_account_id=${artistId}`); + const request = createMockRequest( + `http://localhost/api/chats?artist_account_id=${artistAccountId}`, + ); const response = await getChatsHandler(request); - const json = await response.json(); expect(response.status).toBe(200); - expect(json.status).toBe("success"); - expect(selectChatsWithSessions).toHaveBeenCalledWith({ accountIds: [accountId] }); + expect(selectChatsWithSessions).toHaveBeenCalledWith({ + accountIds: [accountId], + artistAccountId, + }); }); }); describe("admin behavior", () => { - it("passes undefined accountIds for Recoup admin (no target filter)", async () => { - const recoupOrgId = "recoup-org-id"; + it("passes undefined accountIds when caller is in Recoup org (membership-based)", async () => { + const adminAccountId = "admin-account-123"; vi.mocked(validateAuthContext).mockResolvedValue({ - accountId: recoupOrgId, - orgId: recoupOrgId, + accountId: adminAccountId, + orgId: null, authToken: "test-token", }); + vi.mocked(getAccountOrganizations).mockResolvedValue([ + { organization_id: "recoup-org-id" } as never, + ]); vi.mocked(selectChatsWithSessions).mockResolvedValue([]); const request = createMockRequest("http://localhost/api/chats"); const response = await getChatsHandler(request); expect(response.status).toBe(200); - expect(selectChatsWithSessions).toHaveBeenCalledWith({ accountIds: undefined }); + expect(selectChatsWithSessions).toHaveBeenCalledWith({ + accountIds: undefined, + artistAccountId: undefined, + }); }); it("scopes admin to the target account when account_id is provided", async () => { - const recoupOrgId = "recoup-org-id"; + const adminAccountId = "admin-account-123"; const target = "323e4567-e89b-12d3-a456-426614174000"; vi.mocked(validateAuthContext).mockResolvedValue({ - accountId: recoupOrgId, - orgId: recoupOrgId, + accountId: adminAccountId, + orgId: null, authToken: "test-token", }); vi.mocked(canAccessAccount).mockResolvedValue(true); @@ -174,7 +228,10 @@ describe("getChatsHandler", () => { const response = await getChatsHandler(request); expect(response.status).toBe(200); - expect(selectChatsWithSessions).toHaveBeenCalledWith({ accountIds: [target] }); + expect(selectChatsWithSessions).toHaveBeenCalledWith({ + accountIds: [target], + artistAccountId: undefined, + }); }); }); @@ -232,7 +289,7 @@ describe("getChatsHandler", () => { expect(json.error).toBe("Failed to retrieve chats"); }); - it("returns 500 when an exception is thrown", async () => { + it("returns 500 with a generic message when an exception is thrown (no leak of raw message)", async () => { const accountId = "123e4567-e89b-12d3-a456-426614174000"; vi.mocked(validateAuthContext).mockResolvedValue({ @@ -248,13 +305,16 @@ describe("getChatsHandler", () => { expect(response.status).toBe(500); expect(json.status).toBe("error"); - expect(json.error).toBe("Database error"); + expect(json.error).toBe("Internal server error"); + // Raw exception message must not leak into the response body. + expect(json.error).not.toContain("Database"); }); }); describe("response projection", () => { it("skips rows whose session embed is missing", async () => { const accountId = "123e4567-e89b-12d3-a456-426614174000"; + const artistId = "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa"; vi.mocked(validateAuthContext).mockResolvedValue({ accountId, orgId: null, @@ -270,7 +330,7 @@ describe("getChatsHandler", () => { active_stream_id: null, last_assistant_message_at: null, model_id: null, - session: { id: "sess-1", account_id: accountId }, + session: sessionEmbed(accountId, artistId), }, { id: "chat-orphan", @@ -296,6 +356,7 @@ describe("getChatsHandler", () => { accountId, sessionId: "sess-1", updatedAt: "2024-01-02T00:00:00Z", + artistId, }, ]); }); diff --git a/lib/chats/__tests__/validateGetChatsRequest.test.ts b/lib/chats/__tests__/validateGetChatsRequest.test.ts index 540ce877e..266267fdc 100644 --- a/lib/chats/__tests__/validateGetChatsRequest.test.ts +++ b/lib/chats/__tests__/validateGetChatsRequest.test.ts @@ -4,6 +4,7 @@ import { validateGetChatsRequest } from "../validateGetChatsRequest"; import { validateAuthContext } from "@/lib/auth/validateAuthContext"; import { canAccessAccount } from "@/lib/organizations/canAccessAccount"; +import { getAccountOrganizations } from "@/lib/supabase/account_organization_ids/getAccountOrganizations"; vi.mock("@/lib/auth/validateAuthContext", () => ({ validateAuthContext: vi.fn(), @@ -13,6 +14,10 @@ vi.mock("@/lib/organizations/canAccessAccount", () => ({ canAccessAccount: vi.fn(), })); +vi.mock("@/lib/supabase/account_organization_ids/getAccountOrganizations", () => ({ + getAccountOrganizations: vi.fn(), +})); + vi.mock("@/lib/networking/getCorsHeaders", () => ({ getCorsHeaders: vi.fn(() => new Headers()), })); @@ -24,6 +29,8 @@ vi.mock("@/lib/const", () => ({ describe("validateGetChatsRequest", () => { beforeEach(() => { vi.clearAllMocks(); + // Default: caller is NOT in the Recoup org. Admin tests override. + vi.mocked(getAccountOrganizations).mockResolvedValue([]); }); it("returns auth error if validateAuthContext fails", async () => { @@ -38,7 +45,7 @@ describe("validateGetChatsRequest", () => { expect((result as NextResponse).status).toBe(401); }); - it("scopes personal key to the caller's account", async () => { + it("scopes personal Bearer to the caller's account", async () => { const accountId = "personal-account-123"; vi.mocked(validateAuthContext).mockResolvedValue({ accountId, @@ -50,7 +57,7 @@ describe("validateGetChatsRequest", () => { const result = await validateGetChatsRequest(request); expect(result).not.toBeInstanceOf(NextResponse); - expect(result).toEqual({ accountIds: [accountId] }); + expect(result).toEqual({ accountIds: [accountId], artistAccountId: undefined }); }); it("scopes org key to the caller's org account (target unspecified)", async () => { @@ -64,29 +71,38 @@ describe("validateGetChatsRequest", () => { const request = new NextRequest("http://localhost/api/chats"); const result = await validateGetChatsRequest(request); - expect(result).toEqual({ accountIds: [orgId] }); + expect(result).toEqual({ accountIds: [orgId], artistAccountId: undefined }); }); - it("returns undefined accountIds for Recoup admin (no target)", async () => { - const recoupOrgId = "recoup-org-id"; + it("returns undefined accountIds for Recoup admin (membership via account_organization_ids)", async () => { + // Bearer-authed caller whose accountId is a member of RECOUP_ORG. + // orgId stays null (Bearer never sets it) — the check goes through + // account_organization_ids instead. + const adminAccountId = "admin-account-123"; vi.mocked(validateAuthContext).mockResolvedValue({ - accountId: recoupOrgId, - orgId: recoupOrgId, + accountId: adminAccountId, + orgId: null, authToken: "test-token", }); + vi.mocked(getAccountOrganizations).mockResolvedValue([ + // Only the organization_id field is read by the validator + // — other AccountOrganization columns aren't accessed. + { organization_id: "recoup-org-id" } as never, + ]); const request = new NextRequest("http://localhost/api/chats"); const result = await validateGetChatsRequest(request); - expect(result).toEqual({ accountIds: undefined }); + expect(getAccountOrganizations).toHaveBeenCalledWith({ accountId: adminAccountId }); + expect(result).toEqual({ accountIds: undefined, artistAccountId: undefined }); }); it("scopes admin to a specific account when account_id is supplied", async () => { - const recoupOrgId = "recoup-org-id"; + const adminAccountId = "admin-account-123"; const target = "a1111111-1111-4111-8111-111111111111"; vi.mocked(validateAuthContext).mockResolvedValue({ - accountId: recoupOrgId, - orgId: recoupOrgId, + accountId: adminAccountId, + orgId: null, authToken: "test-token", }); vi.mocked(canAccessAccount).mockResolvedValue(true); @@ -96,12 +112,12 @@ describe("validateGetChatsRequest", () => { expect(canAccessAccount).toHaveBeenCalledWith({ targetAccountId: target, - currentAccountId: recoupOrgId, + currentAccountId: adminAccountId, }); - expect(result).toEqual({ accountIds: [target] }); + expect(result).toEqual({ accountIds: [target], artistAccountId: undefined }); }); - it("rejects personal key trying to filter by account_id", async () => { + it("rejects personal key trying to filter by account_id they can't access", async () => { const accountId = "a1111111-1111-4111-8111-111111111111"; const other = "b2222222-2222-4222-8222-222222222222"; vi.mocked(validateAuthContext).mockResolvedValue({ @@ -118,19 +134,40 @@ describe("validateGetChatsRequest", () => { expect((result as NextResponse).status).toBe(403); }); - it("accepts but ignores artist_account_id (reserved for artist-surface migration)", async () => { + it("passes artist_account_id through to the scope", async () => { const accountId = "personal-account-123"; - const artistId = "a1111111-1111-4111-8111-111111111111"; + const artistAccountId = "a1111111-1111-4111-8111-111111111111"; vi.mocked(validateAuthContext).mockResolvedValue({ accountId, orgId: null, authToken: "test-token", }); - const request = new NextRequest(`http://localhost/api/chats?artist_account_id=${artistId}`); + const request = new NextRequest( + `http://localhost/api/chats?artist_account_id=${artistAccountId}`, + ); + const result = await validateGetChatsRequest(request); + + expect(result).toEqual({ accountIds: [accountId], artistAccountId }); + }); + + it("composes account_id + artist_account_id when both supplied", async () => { + const callerAccountId = "caller-account-123"; + const target = "a1111111-1111-4111-8111-111111111111"; + const artistAccountId = "c3333333-3333-4333-8333-333333333333"; + vi.mocked(validateAuthContext).mockResolvedValue({ + accountId: callerAccountId, + orgId: null, + authToken: "test-token", + }); + vi.mocked(canAccessAccount).mockResolvedValue(true); + + const request = new NextRequest( + `http://localhost/api/chats?account_id=${target}&artist_account_id=${artistAccountId}`, + ); const result = await validateGetChatsRequest(request); - expect(result).toEqual({ accountIds: [accountId] }); + expect(result).toEqual({ accountIds: [target], artistAccountId }); }); it("returns 400 for invalid artist_account_id UUID", async () => { diff --git a/lib/chats/getChatsHandler.ts b/lib/chats/getChatsHandler.ts index e1972c250..0f7b254a7 100644 --- a/lib/chats/getChatsHandler.ts +++ b/lib/chats/getChatsHandler.ts @@ -9,8 +9,9 @@ import { selectChatsWithSessions } from "@/lib/supabase/chats/selectChatsWithSes * Requires authentication via x-api-key header or Authorization bearer token. * * Returns chats joined with their owning session so the response carries the - * `sessionId` and the owning `accountId` per row, enabling clients to render - * canonical `/sessions/{sid}/chats/{cid}` URLs. + * `sessionId`, owning `accountId`, and `artistId` per row, enabling clients + * to render canonical `/sessions/{sid}/chats/{cid}` URLs and filter by + * artist context. * * Scope: * - Personal/org key: chats belonging to the caller's account. @@ -20,9 +21,8 @@ import { selectChatsWithSessions } from "@/lib/supabase/chats/selectChatsWithSes * * Optional query parameters: * - `account_id`: target account override (validated against access). - * - `artist_account_id`: filter chats to a specific artist. Currently - * a no-op — the filter starts matching rows once the artist column - * is populated on sessions. + * - `artist_account_id`: scope chats to those whose owning session has the + * given artist context (`sessions.artist_id`). Composes with `account_id`. * * @param request - The request object containing query parameters * @returns A NextResponse with chats data @@ -34,7 +34,10 @@ export async function getChatsHandler(request: NextRequest): Promise m.organization_id === RECOUP_ORG_ID); + if (isRecoupAdmin) { + return { accountIds: undefined, artistAccountId }; } - return { accountIds: [accountId] }; + return { accountIds: [accountId], artistAccountId }; } diff --git a/lib/mcp/tools/chats/__tests__/registerGetChatsTool.test.ts b/lib/mcp/tools/chats/__tests__/registerGetChatsTool.test.ts index 04fc64198..68ec298ed 100644 --- a/lib/mcp/tools/chats/__tests__/registerGetChatsTool.test.ts +++ b/lib/mcp/tools/chats/__tests__/registerGetChatsTool.test.ts @@ -7,6 +7,7 @@ import { registerGetChatsTool } from "../registerGetChatsTool"; const mockSelectChatsWithSessions = vi.fn(); const mockCanAccessAccount = vi.fn(); +const mockGetAccountOrganizations = vi.fn(); vi.mock("@/lib/supabase/chats/selectChatsWithSessions", () => ({ selectChatsWithSessions: (...args: unknown[]) => mockSelectChatsWithSessions(...args), @@ -16,6 +17,10 @@ vi.mock("@/lib/organizations/canAccessAccount", () => ({ canAccessAccount: (...args: unknown[]) => mockCanAccessAccount(...args), })); +vi.mock("@/lib/supabase/account_organization_ids/getAccountOrganizations", () => ({ + getAccountOrganizations: (...args: unknown[]) => mockGetAccountOrganizations(...args), +})); + vi.mock("@/lib/const", () => ({ RECOUP_ORG_ID: "recoup-org-id", })); @@ -50,6 +55,8 @@ describe("registerGetChatsTool", () => { beforeEach(() => { vi.clearAllMocks(); + // Default: caller is NOT in Recoup org. Admin tests override. + mockGetAccountOrganizations.mockResolvedValue([]); mockServer = { registerTool: vi.fn((_name, _config, handler) => { @@ -75,7 +82,10 @@ describe("registerGetChatsTool", () => { const result = await registeredHandler({}, createMockExtra({ accountId: "account-123" })); - expect(mockSelectChatsWithSessions).toHaveBeenCalledWith({ accountIds: ["account-123"] }); + expect(mockSelectChatsWithSessions).toHaveBeenCalledWith({ + accountIds: ["account-123"], + artistAccountId: undefined, + }); expect(result).toEqual({ content: [ { @@ -86,7 +96,7 @@ describe("registerGetChatsTool", () => { }); }); - it("returns chats projected to the new wire shape", async () => { + it("returns chats projected to the new wire shape including artistId", async () => { mockSelectChatsWithSessions.mockResolvedValue([ { id: "chat-456", @@ -97,28 +107,36 @@ describe("registerGetChatsTool", () => { active_stream_id: null, last_assistant_message_at: null, model_id: null, - session: { id: "sess-1", account_id: "account-123" }, + session: { id: "sess-1", account_id: "account-123", artist_id: "artist-789" }, }, ]); const result = await registeredHandler({}, createMockExtra({ accountId: "account-123" })); - expect(result).toEqual({ - content: [ - { - type: "text", - text: expect.stringContaining('"sessionId":"sess-1"'), - }, - ], - }); - expect(result).toEqual({ - content: [ - { - type: "text", - text: expect.stringContaining('"accountId":"account-123"'), - }, - ], - }); + const textNode = (result as { content: { type: string; text: string }[] }).content[0]; + expect(textNode.text).toContain('"sessionId":"sess-1"'); + expect(textNode.text).toContain('"accountId":"account-123"'); + expect(textNode.text).toContain('"artistId":"artist-789"'); + }); + + it("surfaces artistId as null when session has no artist", async () => { + mockSelectChatsWithSessions.mockResolvedValue([ + { + id: "chat-456", + title: "Test Chat", + session_id: "sess-1", + updated_at: "2024-01-01T00:00:00Z", + created_at: "2024-01-01T00:00:00Z", + active_stream_id: null, + last_assistant_message_at: null, + model_id: null, + session: { id: "sess-1", account_id: "account-123", artist_id: null }, + }, + ]); + + const result = await registeredHandler({}, createMockExtra({ accountId: "account-123" })); + const textNode = (result as { content: { type: string; text: string }[] }).content[0]; + expect(textNode.text).toContain('"artistId":null'); }); it("allows account_id override with access", async () => { @@ -136,6 +154,7 @@ describe("registerGetChatsTool", () => { }); expect(mockSelectChatsWithSessions).toHaveBeenCalledWith({ accountIds: ["target-account-789"], + artistAccountId: undefined, }); }); @@ -170,7 +189,7 @@ describe("registerGetChatsTool", () => { }); }); - it("accepts artist_account_id but does not filter by it", async () => { + it("passes artist_account_id through to the select", async () => { mockSelectChatsWithSessions.mockResolvedValue([]); await registeredHandler( @@ -178,18 +197,23 @@ describe("registerGetChatsTool", () => { createMockExtra({ accountId: "account-123" }), ); - expect(mockSelectChatsWithSessions).toHaveBeenCalledWith({ accountIds: ["account-123"] }); + expect(mockSelectChatsWithSessions).toHaveBeenCalledWith({ + accountIds: ["account-123"], + artistAccountId: "artist-456", + }); }); - it("passes undefined accountIds for Recoup admin (all chats)", async () => { + it("passes undefined accountIds for Recoup admin (membership-based)", async () => { + mockGetAccountOrganizations.mockResolvedValue([{ organization_id: "recoup-org-id" }]); mockSelectChatsWithSessions.mockResolvedValue([]); - await registeredHandler( - {}, - createMockExtra({ accountId: "recoup-org-id", orgId: "recoup-org-id" }), - ); + await registeredHandler({}, createMockExtra({ accountId: "admin-account-123" })); - expect(mockSelectChatsWithSessions).toHaveBeenCalledWith({ accountIds: undefined }); + expect(mockGetAccountOrganizations).toHaveBeenCalledWith({ accountId: "admin-account-123" }); + expect(mockSelectChatsWithSessions).toHaveBeenCalledWith({ + accountIds: undefined, + artistAccountId: undefined, + }); }); it("returns error when selectChatsWithSessions fails", async () => { diff --git a/lib/mcp/tools/chats/registerGetChatsTool.ts b/lib/mcp/tools/chats/registerGetChatsTool.ts index 2833f33a7..4e974e72e 100644 --- a/lib/mcp/tools/chats/registerGetChatsTool.ts +++ b/lib/mcp/tools/chats/registerGetChatsTool.ts @@ -6,6 +6,7 @@ import type { McpAuthInfo } from "@/lib/mcp/verifyApiKey"; import { getToolResultSuccess } from "@/lib/mcp/getToolResultSuccess"; import { getToolResultError } from "@/lib/mcp/getToolResultError"; import { canAccessAccount } from "@/lib/organizations/canAccessAccount"; +import { getAccountOrganizations } from "@/lib/supabase/account_organization_ids/getAccountOrganizations"; import { selectChatsWithSessions } from "@/lib/supabase/chats/selectChatsWithSessions"; import { RECOUP_ORG_ID } from "@/lib/const"; @@ -15,8 +16,8 @@ const getChatsSchema = z.object({ .string() .optional() .describe( - "Filter chats to those for the specified artist. Currently has no effect — " + - "the filter starts matching rows once the artist column is populated on sessions.", + "Filter chats to those whose owning session is in the specified artist context " + + "(matches `sessions.artist_id`). Composes with `account_id`.", ), }); @@ -26,9 +27,14 @@ export type GetChatsArgs = z.infer; * Registers the "get_chats" tool on the MCP server. * * Returns chats joined with their owning session so each row carries - * `sessionId` and the owning `accountId`. Scope mirrors GET /api/chats: - * personal/org → caller's account; Recoup admin → all; or a specific - * account when `account_id` is supplied and the caller can access it. + * `sessionId`, owning `accountId`, and `artistId`. Scope mirrors + * GET /api/chats: personal/org → caller's account; Recoup admin → all; + * or a specific account when `account_id` is supplied and the caller + * can access it. `artist_account_id` further scopes by artist context. + * + * Admin status is derived from `account_organization_ids` membership so + * that Bearer-authed callers get the same admin scope as x-api-key + * callers with an org-bound key. * * @param server - The MCP server instance to register the tool on. */ @@ -40,11 +46,10 @@ export function registerGetChatsTool(server: McpServer): void { inputSchema: getChatsSchema, }, async (args: GetChatsArgs, extra: RequestHandlerExtra) => { - const { account_id: targetAccountId } = args; + const { account_id: targetAccountId, artist_account_id: artistAccountId } = args; const authInfo = extra.authInfo as McpAuthInfo | undefined; const accountId = authInfo?.extra?.accountId; - const orgId = authInfo?.extra?.orgId ?? null; if (!accountId) { return getToolResultError( @@ -62,13 +67,13 @@ export function registerGetChatsTool(server: McpServer): void { return getToolResultError("Access denied to specified account_id"); } accountIds = [targetAccountId]; - } else if (orgId === RECOUP_ORG_ID) { - accountIds = undefined; } else { - accountIds = [accountId]; + const callerOrgs = await getAccountOrganizations({ accountId }); + const isRecoupAdmin = callerOrgs.some(m => m.organization_id === RECOUP_ORG_ID); + accountIds = isRecoupAdmin ? undefined : [accountId]; } - const rows = await selectChatsWithSessions({ accountIds }); + const rows = await selectChatsWithSessions({ accountIds, artistAccountId }); if (rows === null) { return getToolResultError("Failed to retrieve chats"); } @@ -82,6 +87,7 @@ export function registerGetChatsTool(server: McpServer): void { accountId: row.session.account_id, sessionId: row.session_id, updatedAt: row.updated_at, + artistId: row.session.artist_id, }, ]; }); diff --git a/lib/supabase/chats/__tests__/selectChatsWithSessions.test.ts b/lib/supabase/chats/__tests__/selectChatsWithSessions.test.ts index 4532f0c66..2d9de9afe 100644 --- a/lib/supabase/chats/__tests__/selectChatsWithSessions.test.ts +++ b/lib/supabase/chats/__tests__/selectChatsWithSessions.test.ts @@ -4,6 +4,7 @@ import { selectChatsWithSessions } from "@/lib/supabase/chats/selectChatsWithSes const fromMock = vi.fn(); const selectMock = vi.fn(); const inMock = vi.fn(); +const eqMock = vi.fn(); const orderMock = vi.fn(); vi.mock("@/lib/supabase/serverClient", () => ({ @@ -14,15 +15,17 @@ vi.mock("@/lib/supabase/serverClient", () => ({ beforeEach(() => { vi.clearAllMocks(); - // Default chain: from().select().in().order() -> resolves to { data, error } + // Default chain: from().select().in().eq().order() -> resolves to { data, error } const builder = { select: selectMock, in: inMock, + eq: eqMock, order: orderMock, }; fromMock.mockReturnValue(builder); selectMock.mockReturnValue(builder); inMock.mockReturnValue(builder); + eqMock.mockReturnValue(builder); orderMock.mockResolvedValue({ data: [], error: null }); }); @@ -47,12 +50,35 @@ describe("selectChatsWithSessions", () => { expect(typeof selectArg).toBe("string"); expect(String(selectArg)).toContain("session:sessions!inner"); expect(String(selectArg)).toContain("account_id"); + expect(String(selectArg)).toContain("artist_id"); expect(inMock).toHaveBeenCalledWith("session.account_id", ["acc-1", "acc-2"]); + expect(eqMock).not.toHaveBeenCalled(); expect(orderMock).toHaveBeenCalledWith("updated_at", { ascending: false }); expect(result).toEqual(rows); }); + it("composes accountIds + artistAccountId — both filters applied", async () => { + orderMock.mockResolvedValueOnce({ data: [], error: null }); + + await selectChatsWithSessions({ + accountIds: ["acc-1"], + artistAccountId: "artist-9", + }); + + expect(inMock).toHaveBeenCalledWith("session.account_id", ["acc-1"]); + expect(eqMock).toHaveBeenCalledWith("session.artist_id", "artist-9"); + }); + + it("applies the artist filter alone (admin scope + artist)", async () => { + orderMock.mockResolvedValueOnce({ data: [], error: null }); + + await selectChatsWithSessions({ artistAccountId: "artist-9" }); + + expect(inMock).not.toHaveBeenCalled(); + expect(eqMock).toHaveBeenCalledWith("session.artist_id", "artist-9"); + }); + it("returns [] without calling .in() when accountIds is undefined (admin: all)", async () => { const rows = [ { diff --git a/lib/supabase/chats/selectChatsWithSessions.ts b/lib/supabase/chats/selectChatsWithSessions.ts index 4f68c9e5a..932341ff0 100644 --- a/lib/supabase/chats/selectChatsWithSessions.ts +++ b/lib/supabase/chats/selectChatsWithSessions.ts @@ -7,17 +7,25 @@ export interface SelectChatsWithSessionsParams { * - `[]` short-circuits to an empty result. */ accountIds?: string[]; + /** + * Optional artist account id to filter by (via `sessions.artist_id`). + * Composes with `accountIds`: scopes the result to chats whose owning + * session both belongs to one of the accountIds AND is in the given + * artist context. + */ + artistAccountId?: string; } const SELECT = ` *, - session:sessions!inner ( id, account_id ) + session:sessions!inner ( id, account_id, artist_id ) ` as const; /** * Reads chats joined to their owning session, optionally scoped to a set of - * account IDs through `sessions.account_id`. Ordered by `chats.updated_at` - * descending so newest activity surfaces first. + * account IDs through `sessions.account_id` and/or an artist context through + * `sessions.artist_id`. Ordered by `chats.updated_at` descending so newest + * activity surfaces first. * * Returns `null` when Supabase reports an error so callers can distinguish a * transient failure from an empty result. Row shape is inferred from the @@ -25,7 +33,7 @@ const SELECT = ` * projection surface to callers without an explicit type alias. */ export async function selectChatsWithSessions(params: SelectChatsWithSessionsParams = {}) { - const { accountIds } = params; + const { accountIds, artistAccountId } = params; if (accountIds !== undefined && accountIds.length === 0) { return []; @@ -35,6 +43,9 @@ export async function selectChatsWithSessions(params: SelectChatsWithSessionsPar if (accountIds !== undefined) { query = query.in("session.account_id", accountIds); } + if (artistAccountId) { + query = query.eq("session.artist_id", artistAccountId); + } const { data, error } = await query.order("updated_at", { ascending: false }); if (error) { From fdc6ce5154b0a7b3fe86f01eb9da4620737c935b Mon Sep 17 00:00:00 2001 From: Sweets Sweetman Date: Sat, 30 May 2026 22:14:17 -0500 Subject: [PATCH 7/8] refactor(organizations): extract isRecoupAdmin helper for DRY admin check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two callers were inlining the same `getAccountOrganizations(...).some(m => m.organization_id === RECOUP_ORG_ID)` pattern to detect Recoup-org membership. Extract into a shared helper so the admin-scope decision lives in one place. - New `lib/organizations/isRecoupAdmin.ts` (+ unit tests). - `validateGetChatsRequest` and `registerGetChatsTool` now call it. - `canAccessAccount` deliberately keeps its inline check — it reuses the same org-list query for the subsequent shared-org check, so calling this helper there would double the DB round-trip. - Tests now mock `isRecoupAdmin` directly (cleaner than mocking the Supabase fetch for every admin-scope case). Addresses sweetmantech's review comment on #626. Co-Authored-By: Claude Opus 4.7 (1M context) --- lib/chats/__tests__/getChatsHandler.test.ts | 18 +++---- .../__tests__/validateGetChatsRequest.test.ts | 28 ++++------- lib/chats/validateGetChatsRequest.ts | 11 ++--- .../__tests__/registerGetChatsTool.test.ts | 18 +++---- lib/mcp/tools/chats/registerGetChatsTool.ts | 7 +-- .../__tests__/isRecoupAdmin.test.ts | 47 +++++++++++++++++++ lib/organizations/isRecoupAdmin.ts | 26 ++++++++++ 7 files changed, 102 insertions(+), 53 deletions(-) create mode 100644 lib/organizations/__tests__/isRecoupAdmin.test.ts create mode 100644 lib/organizations/isRecoupAdmin.ts diff --git a/lib/chats/__tests__/getChatsHandler.test.ts b/lib/chats/__tests__/getChatsHandler.test.ts index f6b445a0b..7ed6478d4 100644 --- a/lib/chats/__tests__/getChatsHandler.test.ts +++ b/lib/chats/__tests__/getChatsHandler.test.ts @@ -4,7 +4,7 @@ import { getChatsHandler } from "../getChatsHandler"; import { validateAuthContext } from "@/lib/auth/validateAuthContext"; import { canAccessAccount } from "@/lib/organizations/canAccessAccount"; -import { getAccountOrganizations } from "@/lib/supabase/account_organization_ids/getAccountOrganizations"; +import { isRecoupAdmin } from "@/lib/organizations/isRecoupAdmin"; import { selectChatsWithSessions } from "@/lib/supabase/chats/selectChatsWithSessions"; vi.mock("@/lib/auth/validateAuthContext", () => ({ @@ -15,8 +15,8 @@ vi.mock("@/lib/organizations/canAccessAccount", () => ({ canAccessAccount: vi.fn(), })); -vi.mock("@/lib/supabase/account_organization_ids/getAccountOrganizations", () => ({ - getAccountOrganizations: vi.fn(), +vi.mock("@/lib/organizations/isRecoupAdmin", () => ({ + isRecoupAdmin: vi.fn(), })); vi.mock("@/lib/supabase/chats/selectChatsWithSessions", () => ({ @@ -27,10 +27,6 @@ vi.mock("@/lib/networking/getCorsHeaders", () => ({ getCorsHeaders: vi.fn(() => ({ "Access-Control-Allow-Origin": "*" })), })); -vi.mock("@/lib/const", () => ({ - RECOUP_ORG_ID: "recoup-org-id", -})); - /** * Creates a mock NextRequest with the given URL and headers. */ @@ -51,8 +47,8 @@ function sessionEmbed(accountId: string, artistId: string | null = null) { describe("getChatsHandler", () => { beforeEach(() => { vi.clearAllMocks(); - // Default: caller is NOT in Recoup org — admin tests override. - vi.mocked(getAccountOrganizations).mockResolvedValue([]); + // Default: caller is NOT a Recoup admin — admin tests override. + vi.mocked(isRecoupAdmin).mockResolvedValue(false); }); describe("authentication", () => { @@ -198,9 +194,7 @@ describe("getChatsHandler", () => { orgId: null, authToken: "test-token", }); - vi.mocked(getAccountOrganizations).mockResolvedValue([ - { organization_id: "recoup-org-id" } as never, - ]); + vi.mocked(isRecoupAdmin).mockResolvedValue(true); vi.mocked(selectChatsWithSessions).mockResolvedValue([]); const request = createMockRequest("http://localhost/api/chats"); diff --git a/lib/chats/__tests__/validateGetChatsRequest.test.ts b/lib/chats/__tests__/validateGetChatsRequest.test.ts index 266267fdc..fc0d1a2f3 100644 --- a/lib/chats/__tests__/validateGetChatsRequest.test.ts +++ b/lib/chats/__tests__/validateGetChatsRequest.test.ts @@ -4,7 +4,7 @@ import { validateGetChatsRequest } from "../validateGetChatsRequest"; import { validateAuthContext } from "@/lib/auth/validateAuthContext"; import { canAccessAccount } from "@/lib/organizations/canAccessAccount"; -import { getAccountOrganizations } from "@/lib/supabase/account_organization_ids/getAccountOrganizations"; +import { isRecoupAdmin } from "@/lib/organizations/isRecoupAdmin"; vi.mock("@/lib/auth/validateAuthContext", () => ({ validateAuthContext: vi.fn(), @@ -14,23 +14,19 @@ vi.mock("@/lib/organizations/canAccessAccount", () => ({ canAccessAccount: vi.fn(), })); -vi.mock("@/lib/supabase/account_organization_ids/getAccountOrganizations", () => ({ - getAccountOrganizations: vi.fn(), +vi.mock("@/lib/organizations/isRecoupAdmin", () => ({ + isRecoupAdmin: vi.fn(), })); vi.mock("@/lib/networking/getCorsHeaders", () => ({ getCorsHeaders: vi.fn(() => new Headers()), })); -vi.mock("@/lib/const", () => ({ - RECOUP_ORG_ID: "recoup-org-id", -})); - describe("validateGetChatsRequest", () => { beforeEach(() => { vi.clearAllMocks(); - // Default: caller is NOT in the Recoup org. Admin tests override. - vi.mocked(getAccountOrganizations).mockResolvedValue([]); + // Default: caller is NOT a Recoup admin. Admin tests override. + vi.mocked(isRecoupAdmin).mockResolvedValue(false); }); it("returns auth error if validateAuthContext fails", async () => { @@ -74,26 +70,22 @@ describe("validateGetChatsRequest", () => { expect(result).toEqual({ accountIds: [orgId], artistAccountId: undefined }); }); - it("returns undefined accountIds for Recoup admin (membership via account_organization_ids)", async () => { + it("returns undefined accountIds for Recoup admin (membership-based check)", async () => { // Bearer-authed caller whose accountId is a member of RECOUP_ORG. - // orgId stays null (Bearer never sets it) — the check goes through - // account_organization_ids instead. + // orgId stays null (Bearer never sets it) — the admin check goes + // through isRecoupAdmin → account_organization_ids instead. const adminAccountId = "admin-account-123"; vi.mocked(validateAuthContext).mockResolvedValue({ accountId: adminAccountId, orgId: null, authToken: "test-token", }); - vi.mocked(getAccountOrganizations).mockResolvedValue([ - // Only the organization_id field is read by the validator - // — other AccountOrganization columns aren't accessed. - { organization_id: "recoup-org-id" } as never, - ]); + vi.mocked(isRecoupAdmin).mockResolvedValue(true); const request = new NextRequest("http://localhost/api/chats"); const result = await validateGetChatsRequest(request); - expect(getAccountOrganizations).toHaveBeenCalledWith({ accountId: adminAccountId }); + expect(isRecoupAdmin).toHaveBeenCalledWith(adminAccountId); expect(result).toEqual({ accountIds: undefined, artistAccountId: undefined }); }); diff --git a/lib/chats/validateGetChatsRequest.ts b/lib/chats/validateGetChatsRequest.ts index a3a6e335c..522249aa3 100644 --- a/lib/chats/validateGetChatsRequest.ts +++ b/lib/chats/validateGetChatsRequest.ts @@ -4,8 +4,7 @@ import { z } from "zod"; import { getCorsHeaders } from "@/lib/networking/getCorsHeaders"; import { validateAuthContext } from "@/lib/auth/validateAuthContext"; import { canAccessAccount } from "@/lib/organizations/canAccessAccount"; -import { getAccountOrganizations } from "@/lib/supabase/account_organization_ids/getAccountOrganizations"; -import { RECOUP_ORG_ID } from "@/lib/const"; +import { isRecoupAdmin } from "@/lib/organizations/isRecoupAdmin"; const getChatsQuerySchema = z.object({ account_id: z.string().uuid("account_id must be a valid UUID").optional(), @@ -77,12 +76,10 @@ export async function validateGetChatsRequest( return { accountIds: [targetAccountId], artistAccountId }; } - // Recoup admin → all chats. Check membership directly so Bearer-authed - // admins get the same scope as x-api-key admins (auth.orgId is null for + // Recoup admin → all chats. Membership-based so Bearer-authed admins + // get the same scope as x-api-key admins (auth.orgId is null for // Bearer regardless of the caller's org memberships). - const callerOrgs = await getAccountOrganizations({ accountId }); - const isRecoupAdmin = callerOrgs.some(m => m.organization_id === RECOUP_ORG_ID); - if (isRecoupAdmin) { + if (await isRecoupAdmin(accountId)) { return { accountIds: undefined, artistAccountId }; } diff --git a/lib/mcp/tools/chats/__tests__/registerGetChatsTool.test.ts b/lib/mcp/tools/chats/__tests__/registerGetChatsTool.test.ts index 68ec298ed..f2c7e0fc9 100644 --- a/lib/mcp/tools/chats/__tests__/registerGetChatsTool.test.ts +++ b/lib/mcp/tools/chats/__tests__/registerGetChatsTool.test.ts @@ -7,7 +7,7 @@ import { registerGetChatsTool } from "../registerGetChatsTool"; const mockSelectChatsWithSessions = vi.fn(); const mockCanAccessAccount = vi.fn(); -const mockGetAccountOrganizations = vi.fn(); +const mockIsRecoupAdmin = vi.fn(); vi.mock("@/lib/supabase/chats/selectChatsWithSessions", () => ({ selectChatsWithSessions: (...args: unknown[]) => mockSelectChatsWithSessions(...args), @@ -17,12 +17,8 @@ vi.mock("@/lib/organizations/canAccessAccount", () => ({ canAccessAccount: (...args: unknown[]) => mockCanAccessAccount(...args), })); -vi.mock("@/lib/supabase/account_organization_ids/getAccountOrganizations", () => ({ - getAccountOrganizations: (...args: unknown[]) => mockGetAccountOrganizations(...args), -})); - -vi.mock("@/lib/const", () => ({ - RECOUP_ORG_ID: "recoup-org-id", +vi.mock("@/lib/organizations/isRecoupAdmin", () => ({ + isRecoupAdmin: (...args: unknown[]) => mockIsRecoupAdmin(...args), })); type ServerRequestHandlerExtra = RequestHandlerExtra; @@ -55,8 +51,8 @@ describe("registerGetChatsTool", () => { beforeEach(() => { vi.clearAllMocks(); - // Default: caller is NOT in Recoup org. Admin tests override. - mockGetAccountOrganizations.mockResolvedValue([]); + // Default: caller is NOT a Recoup admin. Admin tests override. + mockIsRecoupAdmin.mockResolvedValue(false); mockServer = { registerTool: vi.fn((_name, _config, handler) => { @@ -204,12 +200,12 @@ describe("registerGetChatsTool", () => { }); it("passes undefined accountIds for Recoup admin (membership-based)", async () => { - mockGetAccountOrganizations.mockResolvedValue([{ organization_id: "recoup-org-id" }]); + mockIsRecoupAdmin.mockResolvedValue(true); mockSelectChatsWithSessions.mockResolvedValue([]); await registeredHandler({}, createMockExtra({ accountId: "admin-account-123" })); - expect(mockGetAccountOrganizations).toHaveBeenCalledWith({ accountId: "admin-account-123" }); + expect(mockIsRecoupAdmin).toHaveBeenCalledWith("admin-account-123"); expect(mockSelectChatsWithSessions).toHaveBeenCalledWith({ accountIds: undefined, artistAccountId: undefined, diff --git a/lib/mcp/tools/chats/registerGetChatsTool.ts b/lib/mcp/tools/chats/registerGetChatsTool.ts index 4e974e72e..d667964ba 100644 --- a/lib/mcp/tools/chats/registerGetChatsTool.ts +++ b/lib/mcp/tools/chats/registerGetChatsTool.ts @@ -6,9 +6,8 @@ import type { McpAuthInfo } from "@/lib/mcp/verifyApiKey"; import { getToolResultSuccess } from "@/lib/mcp/getToolResultSuccess"; import { getToolResultError } from "@/lib/mcp/getToolResultError"; import { canAccessAccount } from "@/lib/organizations/canAccessAccount"; -import { getAccountOrganizations } from "@/lib/supabase/account_organization_ids/getAccountOrganizations"; +import { isRecoupAdmin } from "@/lib/organizations/isRecoupAdmin"; import { selectChatsWithSessions } from "@/lib/supabase/chats/selectChatsWithSessions"; -import { RECOUP_ORG_ID } from "@/lib/const"; const getChatsSchema = z.object({ account_id: z.string().optional().describe("The account ID to filter chats for."), @@ -68,9 +67,7 @@ export function registerGetChatsTool(server: McpServer): void { } accountIds = [targetAccountId]; } else { - const callerOrgs = await getAccountOrganizations({ accountId }); - const isRecoupAdmin = callerOrgs.some(m => m.organization_id === RECOUP_ORG_ID); - accountIds = isRecoupAdmin ? undefined : [accountId]; + accountIds = (await isRecoupAdmin(accountId)) ? undefined : [accountId]; } const rows = await selectChatsWithSessions({ accountIds, artistAccountId }); diff --git a/lib/organizations/__tests__/isRecoupAdmin.test.ts b/lib/organizations/__tests__/isRecoupAdmin.test.ts new file mode 100644 index 000000000..3a5d96df2 --- /dev/null +++ b/lib/organizations/__tests__/isRecoupAdmin.test.ts @@ -0,0 +1,47 @@ +import { describe, it, expect, vi, beforeEach } from "vitest"; +import { isRecoupAdmin } from "@/lib/organizations/isRecoupAdmin"; +import { getAccountOrganizations } from "@/lib/supabase/account_organization_ids/getAccountOrganizations"; + +vi.mock("@/lib/supabase/account_organization_ids/getAccountOrganizations", () => ({ + getAccountOrganizations: vi.fn(), +})); + +vi.mock("@/lib/const", () => ({ + RECOUP_ORG_ID: "recoup-org-id", +})); + +beforeEach(() => { + vi.clearAllMocks(); +}); + +describe("isRecoupAdmin", () => { + it("returns false for an empty/missing accountId without querying", async () => { + expect(await isRecoupAdmin("")).toBe(false); + expect(getAccountOrganizations).not.toHaveBeenCalled(); + }); + + it("returns true when the account is a member of the Recoup org", async () => { + vi.mocked(getAccountOrganizations).mockResolvedValue([ + { organization_id: "some-other-org" } as never, + { organization_id: "recoup-org-id" } as never, + ]); + + expect(await isRecoupAdmin("acc-1")).toBe(true); + expect(getAccountOrganizations).toHaveBeenCalledWith({ accountId: "acc-1" }); + }); + + it("returns false when the account is in orgs but none is Recoup", async () => { + vi.mocked(getAccountOrganizations).mockResolvedValue([ + { organization_id: "org-a" } as never, + { organization_id: "org-b" } as never, + ]); + + expect(await isRecoupAdmin("acc-1")).toBe(false); + }); + + it("returns false when the account is in no orgs", async () => { + vi.mocked(getAccountOrganizations).mockResolvedValue([]); + + expect(await isRecoupAdmin("acc-1")).toBe(false); + }); +}); diff --git a/lib/organizations/isRecoupAdmin.ts b/lib/organizations/isRecoupAdmin.ts new file mode 100644 index 000000000..af8cfb55a --- /dev/null +++ b/lib/organizations/isRecoupAdmin.ts @@ -0,0 +1,26 @@ +import { getAccountOrganizations } from "@/lib/supabase/account_organization_ids/getAccountOrganizations"; +import { RECOUP_ORG_ID } from "@/lib/const"; + +/** + * Returns `true` iff `accountId` is a member of the Recoup organization + * (`RECOUP_ORG_ID`). Used to grant admin-level scope (read/write across + * all accounts) to Recoup team members regardless of which auth method + * they used. + * + * Membership is read via `account_organization_ids` so this works for + * Bearer-authed callers too — `auth.orgId` is only populated by + * x-api-key org keys, leaving Bearer admins unrecognized if you check + * `auth.orgId === RECOUP_ORG_ID` alone. + * + * `canAccessAccount` deliberately inlines an equivalent check because + * it reuses the same org-list query for the subsequent shared-org check + * — calling this helper there would double the DB query for no benefit. + * + * @param accountId - The account to check. + * @returns `true` if the account is in the Recoup org; `false` otherwise. + */ +export async function isRecoupAdmin(accountId: string): Promise { + if (!accountId) return false; + const orgs = await getAccountOrganizations({ accountId }); + return orgs.some(m => m.organization_id === RECOUP_ORG_ID); +} From 0a5b275cad6a8ca4c99e3a1ff097d279e34c9a69 Mon Sep 17 00:00:00 2001 From: Sweets Sweetman Date: Sat, 30 May 2026 22:14:51 -0500 Subject: [PATCH 8/8] chore(format): prettier-format types/database.types.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The supabase CLI emits the file without semicolons (it has its own inline formatter), but the project's prettier config requires them (`semi: true`), so `pnpm format:check` was failing in CI. This is mechanical — diff is purely whitespace + trailing semicolons. Co-Authored-By: Claude Opus 4.7 (1M context) --- types/database.types.ts | 7055 +++++++++++++++++++-------------------- 1 file changed, 3517 insertions(+), 3538 deletions(-) diff --git a/types/database.types.ts b/types/database.types.ts index fc58d7c24..191472132 100644 --- a/types/database.types.ts +++ b/types/database.types.ts @@ -1,4198 +1,4192 @@ -export type Json = - | string - | number - | boolean - | null - | { [key: string]: Json | undefined } - | Json[] +export type Json = string | number | boolean | null | { [key: string]: Json | undefined } | Json[]; export type Database = { // Allows to automatically instantiate createClient with right options // instead of createClient(URL, KEY) __InternalSupabase: { - PostgrestVersion: "12.2.3 (519615d)" - } + PostgrestVersion: "12.2.3 (519615d)"; + }; public: { Tables: { account_api_keys: { Row: { - account: string | null - created_at: string - id: string - key_hash: string | null - last_used: string | null - name: string - } + account: string | null; + created_at: string; + id: string; + key_hash: string | null; + last_used: string | null; + name: string; + }; Insert: { - account?: string | null - created_at?: string - id?: string - key_hash?: string | null - last_used?: string | null - name: string - } + account?: string | null; + created_at?: string; + id?: string; + key_hash?: string | null; + last_used?: string | null; + name: string; + }; Update: { - account?: string | null - created_at?: string - id?: string - key_hash?: string | null - last_used?: string | null - name?: string - } + account?: string | null; + created_at?: string; + id?: string; + key_hash?: string | null; + last_used?: string | null; + name?: string; + }; Relationships: [ { - foreignKeyName: "account_api_keys_account_fkey" - columns: ["account"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "account_api_keys_account_fkey"; + columns: ["account"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; account_artist_ids: { Row: { - account_id: string | null - artist_id: string | null - id: string - pinned: boolean - updated_at: string | null - } + account_id: string | null; + artist_id: string | null; + id: string; + pinned: boolean; + updated_at: string | null; + }; Insert: { - account_id?: string | null - artist_id?: string | null - id?: string - pinned?: boolean - updated_at?: string | null - } + account_id?: string | null; + artist_id?: string | null; + id?: string; + pinned?: boolean; + updated_at?: string | null; + }; Update: { - account_id?: string | null - artist_id?: string | null - id?: string - pinned?: boolean - updated_at?: string | null - } + account_id?: string | null; + artist_id?: string | null; + id?: string; + pinned?: boolean; + updated_at?: string | null; + }; Relationships: [ { - foreignKeyName: "account_artist_ids_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "account_artist_ids_account_id_fkey"; + columns: ["account_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, { - foreignKeyName: "account_artist_ids_artist_id_fkey" - columns: ["artist_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "account_artist_ids_artist_id_fkey"; + columns: ["artist_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; account_catalogs: { Row: { - account: string - catalog: string - created_at: string - id: string - updated_at: string - } + account: string; + catalog: string; + created_at: string; + id: string; + updated_at: string; + }; Insert: { - account: string - catalog: string - created_at?: string - id?: string - updated_at?: string - } + account: string; + catalog: string; + created_at?: string; + id?: string; + updated_at?: string; + }; Update: { - account?: string - catalog?: string - created_at?: string - id?: string - updated_at?: string - } + account?: string; + catalog?: string; + created_at?: string; + id?: string; + updated_at?: string; + }; Relationships: [ { - foreignKeyName: "account_catalogs_account_fkey" - columns: ["account"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "account_catalogs_account_fkey"; + columns: ["account"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, { - foreignKeyName: "account_catalogs_catalog_fkey" - columns: ["catalog"] - isOneToOne: false - referencedRelation: "catalogs" - referencedColumns: ["id"] + foreignKeyName: "account_catalogs_catalog_fkey"; + columns: ["catalog"]; + isOneToOne: false; + referencedRelation: "catalogs"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; account_emails: { Row: { - account_id: string | null - email: string | null - id: string - updated_at: string - } + account_id: string | null; + email: string | null; + id: string; + updated_at: string; + }; Insert: { - account_id?: string | null - email?: string | null - id?: string - updated_at?: string - } + account_id?: string | null; + email?: string | null; + id?: string; + updated_at?: string; + }; Update: { - account_id?: string | null - email?: string | null - id?: string - updated_at?: string - } + account_id?: string | null; + email?: string | null; + id?: string; + updated_at?: string; + }; Relationships: [ { - foreignKeyName: "account_emails_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "account_emails_account_id_fkey"; + columns: ["account_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; account_info: { Row: { - account_id: string | null - company_name: string | null - id: string - image: string | null - instruction: string | null - job_title: string | null - knowledges: Json | null - label: string | null - organization: string | null - role_type: string | null - updated_at: string - } + account_id: string | null; + company_name: string | null; + id: string; + image: string | null; + instruction: string | null; + job_title: string | null; + knowledges: Json | null; + label: string | null; + organization: string | null; + role_type: string | null; + updated_at: string; + }; Insert: { - account_id?: string | null - company_name?: string | null - id?: string - image?: string | null - instruction?: string | null - job_title?: string | null - knowledges?: Json | null - label?: string | null - organization?: string | null - role_type?: string | null - updated_at?: string - } + account_id?: string | null; + company_name?: string | null; + id?: string; + image?: string | null; + instruction?: string | null; + job_title?: string | null; + knowledges?: Json | null; + label?: string | null; + organization?: string | null; + role_type?: string | null; + updated_at?: string; + }; Update: { - account_id?: string | null - company_name?: string | null - id?: string - image?: string | null - instruction?: string | null - job_title?: string | null - knowledges?: Json | null - label?: string | null - organization?: string | null - role_type?: string | null - updated_at?: string - } + account_id?: string | null; + company_name?: string | null; + id?: string; + image?: string | null; + instruction?: string | null; + job_title?: string | null; + knowledges?: Json | null; + label?: string | null; + organization?: string | null; + role_type?: string | null; + updated_at?: string; + }; Relationships: [ { - foreignKeyName: "account_info_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "account_info_account_id_fkey"; + columns: ["account_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; account_organization_ids: { Row: { - account_id: string | null - id: string - organization_id: string | null - updated_at: string | null - } + account_id: string | null; + id: string; + organization_id: string | null; + updated_at: string | null; + }; Insert: { - account_id?: string | null - id?: string - organization_id?: string | null - updated_at?: string | null - } + account_id?: string | null; + id?: string; + organization_id?: string | null; + updated_at?: string | null; + }; Update: { - account_id?: string | null - id?: string - organization_id?: string | null - updated_at?: string | null - } + account_id?: string | null; + id?: string; + organization_id?: string | null; + updated_at?: string | null; + }; Relationships: [ { - foreignKeyName: "account_organization_ids_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "account_organization_ids_account_id_fkey"; + columns: ["account_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, { - foreignKeyName: "account_organization_ids_organization_id_fkey" - columns: ["organization_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "account_organization_ids_organization_id_fkey"; + columns: ["organization_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; account_phone_numbers: { Row: { - account_id: string - id: string - phone_number: string - updated_at: string | null - } + account_id: string; + id: string; + phone_number: string; + updated_at: string | null; + }; Insert: { - account_id: string - id?: string - phone_number: string - updated_at?: string | null - } + account_id: string; + id?: string; + phone_number: string; + updated_at?: string | null; + }; Update: { - account_id?: string - id?: string - phone_number?: string - updated_at?: string | null - } + account_id?: string; + id?: string; + phone_number?: string; + updated_at?: string | null; + }; Relationships: [ { - foreignKeyName: "account_phone_numbers_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "account_phone_numbers_account_id_fkey"; + columns: ["account_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; account_sandboxes: { Row: { - account_id: string - created_at: string - id: string - sandbox_id: string - } + account_id: string; + created_at: string; + id: string; + sandbox_id: string; + }; Insert: { - account_id: string - created_at?: string - id?: string - sandbox_id: string - } + account_id: string; + created_at?: string; + id?: string; + sandbox_id: string; + }; Update: { - account_id?: string - created_at?: string - id?: string - sandbox_id?: string - } + account_id?: string; + created_at?: string; + id?: string; + sandbox_id?: string; + }; Relationships: [ { - foreignKeyName: "account_sandboxes_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "account_sandboxes_account_id_fkey"; + columns: ["account_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; account_snapshots: { Row: { - account_id: string - created_at: string | null - expires_at: string | null - github_repo: string | null - snapshot_id: string | null - } + account_id: string; + created_at: string | null; + expires_at: string | null; + github_repo: string | null; + snapshot_id: string | null; + }; Insert: { - account_id: string - created_at?: string | null - expires_at?: string | null - github_repo?: string | null - snapshot_id?: string | null - } + account_id: string; + created_at?: string | null; + expires_at?: string | null; + github_repo?: string | null; + snapshot_id?: string | null; + }; Update: { - account_id?: string - created_at?: string | null - expires_at?: string | null - github_repo?: string | null - snapshot_id?: string | null - } + account_id?: string; + created_at?: string | null; + expires_at?: string | null; + github_repo?: string | null; + snapshot_id?: string | null; + }; Relationships: [ { - foreignKeyName: "account_snapshots_account_id_fkey" - columns: ["account_id"] - isOneToOne: true - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "account_snapshots_account_id_fkey"; + columns: ["account_id"]; + isOneToOne: true; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; account_socials: { Row: { - account_id: string | null - id: string - social_id: string - } + account_id: string | null; + id: string; + social_id: string; + }; Insert: { - account_id?: string | null - id?: string - social_id?: string - } + account_id?: string | null; + id?: string; + social_id?: string; + }; Update: { - account_id?: string | null - id?: string - social_id?: string - } + account_id?: string | null; + id?: string; + social_id?: string; + }; Relationships: [ { - foreignKeyName: "account_socials_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "account_socials_account_id_fkey"; + columns: ["account_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, { - foreignKeyName: "account_socials_social_id_fkey" - columns: ["social_id"] - isOneToOne: false - referencedRelation: "socials" - referencedColumns: ["id"] + foreignKeyName: "account_socials_social_id_fkey"; + columns: ["social_id"]; + isOneToOne: false; + referencedRelation: "socials"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; account_wallets: { Row: { - account_id: string - id: string - updated_at: string | null - wallet: string - } + account_id: string; + id: string; + updated_at: string | null; + wallet: string; + }; Insert: { - account_id: string - id?: string - updated_at?: string | null - wallet: string - } + account_id: string; + id?: string; + updated_at?: string | null; + wallet: string; + }; Update: { - account_id?: string - id?: string - updated_at?: string | null - wallet?: string - } + account_id?: string; + id?: string; + updated_at?: string | null; + wallet?: string; + }; Relationships: [ { - foreignKeyName: "account_wallets_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "account_wallets_account_id_fkey"; + columns: ["account_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; account_workspace_ids: { Row: { - account_id: string | null - id: string - updated_at: string | null - workspace_id: string | null - } + account_id: string | null; + id: string; + updated_at: string | null; + workspace_id: string | null; + }; Insert: { - account_id?: string | null - id?: string - updated_at?: string | null - workspace_id?: string | null - } + account_id?: string | null; + id?: string; + updated_at?: string | null; + workspace_id?: string | null; + }; Update: { - account_id?: string | null - id?: string - updated_at?: string | null - workspace_id?: string | null - } + account_id?: string | null; + id?: string; + updated_at?: string | null; + workspace_id?: string | null; + }; Relationships: [ { - foreignKeyName: "account_workspace_ids_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "account_workspace_ids_account_id_fkey"; + columns: ["account_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, { - foreignKeyName: "account_workspace_ids_workspace_id_fkey" - columns: ["workspace_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "account_workspace_ids_workspace_id_fkey"; + columns: ["workspace_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; accounts: { Row: { - id: string - name: string | null - timestamp: number | null - } + id: string; + name: string | null; + timestamp: number | null; + }; Insert: { - id?: string - name?: string | null - timestamp?: number | null - } + id?: string; + name?: string | null; + timestamp?: number | null; + }; Update: { - id?: string - name?: string | null - timestamp?: number | null - } - Relationships: [] - } + id?: string; + name?: string | null; + timestamp?: number | null; + }; + Relationships: []; + }; accounts_memberships: { Row: { - account_id: string - account_role: string - created_at: string - created_by: string | null - updated_at: string - updated_by: string | null - user_id: string - } + account_id: string; + account_role: string; + created_at: string; + created_by: string | null; + updated_at: string; + updated_by: string | null; + user_id: string; + }; Insert: { - account_id: string - account_role: string - created_at?: string - created_by?: string | null - updated_at?: string - updated_by?: string | null - user_id: string - } + account_id: string; + account_role: string; + created_at?: string; + created_by?: string | null; + updated_at?: string; + updated_by?: string | null; + user_id: string; + }; Update: { - account_id?: string - account_role?: string - created_at?: string - created_by?: string | null - updated_at?: string - updated_by?: string | null - user_id?: string - } + account_id?: string; + account_role?: string; + created_at?: string; + created_by?: string | null; + updated_at?: string; + updated_by?: string | null; + user_id?: string; + }; Relationships: [ { - foreignKeyName: "accounts_memberships_account_role_fkey" - columns: ["account_role"] - isOneToOne: false - referencedRelation: "roles" - referencedColumns: ["name"] + foreignKeyName: "accounts_memberships_account_role_fkey"; + columns: ["account_role"]; + isOneToOne: false; + referencedRelation: "roles"; + referencedColumns: ["name"]; }, - ] - } + ]; + }; admin_expenses: { Row: { - amount: number - category: string - created_at: string | null - created_by: string | null - id: string - is_active: boolean | null - item_name: string - updated_at: string | null - } + amount: number; + category: string; + created_at: string | null; + created_by: string | null; + id: string; + is_active: boolean | null; + item_name: string; + updated_at: string | null; + }; Insert: { - amount?: number - category: string - created_at?: string | null - created_by?: string | null - id?: string - is_active?: boolean | null - item_name: string - updated_at?: string | null - } + amount?: number; + category: string; + created_at?: string | null; + created_by?: string | null; + id?: string; + is_active?: boolean | null; + item_name: string; + updated_at?: string | null; + }; Update: { - amount?: number - category?: string - created_at?: string | null - created_by?: string | null - id?: string - is_active?: boolean | null - item_name?: string - updated_at?: string | null - } - Relationships: [] - } + amount?: number; + category?: string; + created_at?: string | null; + created_by?: string | null; + id?: string; + is_active?: boolean | null; + item_name?: string; + updated_at?: string | null; + }; + Relationships: []; + }; admin_user_profiles: { Row: { - company: string | null - context_notes: string | null - created_at: string | null - email: string - id: string - job_title: string | null - last_contact_date: string | null - meeting_notes: string | null - observations: string | null - opportunities: string | null - pain_points: string | null - sentiment: string | null - tags: string[] | null - updated_at: string | null - } + company: string | null; + context_notes: string | null; + created_at: string | null; + email: string; + id: string; + job_title: string | null; + last_contact_date: string | null; + meeting_notes: string | null; + observations: string | null; + opportunities: string | null; + pain_points: string | null; + sentiment: string | null; + tags: string[] | null; + updated_at: string | null; + }; Insert: { - company?: string | null - context_notes?: string | null - created_at?: string | null - email: string - id?: string - job_title?: string | null - last_contact_date?: string | null - meeting_notes?: string | null - observations?: string | null - opportunities?: string | null - pain_points?: string | null - sentiment?: string | null - tags?: string[] | null - updated_at?: string | null - } + company?: string | null; + context_notes?: string | null; + created_at?: string | null; + email: string; + id?: string; + job_title?: string | null; + last_contact_date?: string | null; + meeting_notes?: string | null; + observations?: string | null; + opportunities?: string | null; + pain_points?: string | null; + sentiment?: string | null; + tags?: string[] | null; + updated_at?: string | null; + }; Update: { - company?: string | null - context_notes?: string | null - created_at?: string | null - email?: string - id?: string - job_title?: string | null - last_contact_date?: string | null - meeting_notes?: string | null - observations?: string | null - opportunities?: string | null - pain_points?: string | null - sentiment?: string | null - tags?: string[] | null - updated_at?: string | null - } - Relationships: [] - } + company?: string | null; + context_notes?: string | null; + created_at?: string | null; + email?: string; + id?: string; + job_title?: string | null; + last_contact_date?: string | null; + meeting_notes?: string | null; + observations?: string | null; + opportunities?: string | null; + pain_points?: string | null; + sentiment?: string | null; + tags?: string[] | null; + updated_at?: string | null; + }; + Relationships: []; + }; agent_status: { Row: { - agent_id: string - id: string - progress: number | null - social_id: string - status: number | null - updated_at: string - } + agent_id: string; + id: string; + progress: number | null; + social_id: string; + status: number | null; + updated_at: string; + }; Insert: { - agent_id?: string - id?: string - progress?: number | null - social_id: string - status?: number | null - updated_at?: string - } + agent_id?: string; + id?: string; + progress?: number | null; + social_id: string; + status?: number | null; + updated_at?: string; + }; Update: { - agent_id?: string - id?: string - progress?: number | null - social_id?: string - status?: number | null - updated_at?: string - } + agent_id?: string; + id?: string; + progress?: number | null; + social_id?: string; + status?: number | null; + updated_at?: string; + }; Relationships: [ { - foreignKeyName: "agent_status_agent_id_fkey" - columns: ["agent_id"] - isOneToOne: false - referencedRelation: "agents" - referencedColumns: ["id"] + foreignKeyName: "agent_status_agent_id_fkey"; + columns: ["agent_id"]; + isOneToOne: false; + referencedRelation: "agents"; + referencedColumns: ["id"]; }, { - foreignKeyName: "agent_status_social_id_fkey" - columns: ["social_id"] - isOneToOne: false - referencedRelation: "socials" - referencedColumns: ["id"] + foreignKeyName: "agent_status_social_id_fkey"; + columns: ["social_id"]; + isOneToOne: false; + referencedRelation: "socials"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; agent_template_favorites: { Row: { - created_at: string | null - template_id: string - user_id: string - } + created_at: string | null; + template_id: string; + user_id: string; + }; Insert: { - created_at?: string | null - template_id: string - user_id: string - } + created_at?: string | null; + template_id: string; + user_id: string; + }; Update: { - created_at?: string | null - template_id?: string - user_id?: string - } + created_at?: string | null; + template_id?: string; + user_id?: string; + }; Relationships: [ { - foreignKeyName: "agent_template_favorites_template_id_fkey" - columns: ["template_id"] - isOneToOne: false - referencedRelation: "agent_templates" - referencedColumns: ["id"] + foreignKeyName: "agent_template_favorites_template_id_fkey"; + columns: ["template_id"]; + isOneToOne: false; + referencedRelation: "agent_templates"; + referencedColumns: ["id"]; }, { - foreignKeyName: "agent_template_favorites_user_id_fkey" - columns: ["user_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "agent_template_favorites_user_id_fkey"; + columns: ["user_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; agent_template_shares: { Row: { - created_at: string | null - template_id: string - user_id: string - } + created_at: string | null; + template_id: string; + user_id: string; + }; Insert: { - created_at?: string | null - template_id: string - user_id: string - } + created_at?: string | null; + template_id: string; + user_id: string; + }; Update: { - created_at?: string | null - template_id?: string - user_id?: string - } + created_at?: string | null; + template_id?: string; + user_id?: string; + }; Relationships: [ { - foreignKeyName: "agent_template_shares_template_id_fkey" - columns: ["template_id"] - isOneToOne: false - referencedRelation: "agent_templates" - referencedColumns: ["id"] + foreignKeyName: "agent_template_shares_template_id_fkey"; + columns: ["template_id"]; + isOneToOne: false; + referencedRelation: "agent_templates"; + referencedColumns: ["id"]; }, { - foreignKeyName: "agent_template_shares_user_id_fkey" - columns: ["user_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "agent_template_shares_user_id_fkey"; + columns: ["user_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; agent_templates: { Row: { - created_at: string - creator: string | null - description: string - favorites_count: number - id: string - is_private: boolean - prompt: string - tags: string[] - title: string - updated_at: string | null - } + created_at: string; + creator: string | null; + description: string; + favorites_count: number; + id: string; + is_private: boolean; + prompt: string; + tags: string[]; + title: string; + updated_at: string | null; + }; Insert: { - created_at?: string - creator?: string | null - description: string - favorites_count?: number - id?: string - is_private?: boolean - prompt: string - tags?: string[] - title: string - updated_at?: string | null - } + created_at?: string; + creator?: string | null; + description: string; + favorites_count?: number; + id?: string; + is_private?: boolean; + prompt: string; + tags?: string[]; + title: string; + updated_at?: string | null; + }; Update: { - created_at?: string - creator?: string | null - description?: string - favorites_count?: number - id?: string - is_private?: boolean - prompt?: string - tags?: string[] - title?: string - updated_at?: string | null - } + created_at?: string; + creator?: string | null; + description?: string; + favorites_count?: number; + id?: string; + is_private?: boolean; + prompt?: string; + tags?: string[]; + title?: string; + updated_at?: string | null; + }; Relationships: [ { - foreignKeyName: "agent_templates_creator_fkey" - columns: ["creator"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "agent_templates_creator_fkey"; + columns: ["creator"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; agents: { Row: { - id: string - updated_at: string - } + id: string; + updated_at: string; + }; Insert: { - id?: string - updated_at?: string - } + id?: string; + updated_at?: string; + }; Update: { - id?: string - updated_at?: string - } - Relationships: [] - } + id?: string; + updated_at?: string; + }; + Relationships: []; + }; app_store_link_clicked: { Row: { - clientId: string | null - id: string | null - timestamp: number | null - } + clientId: string | null; + id: string | null; + timestamp: number | null; + }; Insert: { - clientId?: string | null - id?: string | null - timestamp?: number | null - } + clientId?: string | null; + id?: string | null; + timestamp?: number | null; + }; Update: { - clientId?: string | null - id?: string | null - timestamp?: number | null - } - Relationships: [] - } + clientId?: string | null; + id?: string | null; + timestamp?: number | null; + }; + Relationships: []; + }; apple_login_button_clicked: { Row: { - campaignId: string | null - clientId: string | null - fanId: string | null - game: string | null - id: string | null - timestamp: number | null - } + campaignId: string | null; + clientId: string | null; + fanId: string | null; + game: string | null; + id: string | null; + timestamp: number | null; + }; Insert: { - campaignId?: string | null - clientId?: string | null - fanId?: string | null - game?: string | null - id?: string | null - timestamp?: number | null - } + campaignId?: string | null; + clientId?: string | null; + fanId?: string | null; + game?: string | null; + id?: string | null; + timestamp?: number | null; + }; Update: { - campaignId?: string | null - clientId?: string | null - fanId?: string | null - game?: string | null - id?: string | null - timestamp?: number | null - } + campaignId?: string | null; + clientId?: string | null; + fanId?: string | null; + game?: string | null; + id?: string | null; + timestamp?: number | null; + }; Relationships: [ { - foreignKeyName: "apple_login_button_clicked_campaignId_fkey" - columns: ["campaignId"] - isOneToOne: false - referencedRelation: "campaigns" - referencedColumns: ["id"] + foreignKeyName: "apple_login_button_clicked_campaignId_fkey"; + columns: ["campaignId"]; + isOneToOne: false; + referencedRelation: "campaigns"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; apple_music: { Row: { - fanId: string | null - game: string | null - id: string | null - syncid: string | null - syncId: string | null - timestamp: number | null - } + fanId: string | null; + game: string | null; + id: string | null; + syncid: string | null; + syncId: string | null; + timestamp: number | null; + }; Insert: { - fanId?: string | null - game?: string | null - id?: string | null - syncid?: string | null - syncId?: string | null - timestamp?: number | null - } + fanId?: string | null; + game?: string | null; + id?: string | null; + syncid?: string | null; + syncId?: string | null; + timestamp?: number | null; + }; Update: { - fanId?: string | null - game?: string | null - id?: string | null - syncid?: string | null - syncId?: string | null - timestamp?: number | null - } - Relationships: [] - } + fanId?: string | null; + game?: string | null; + id?: string | null; + syncid?: string | null; + syncId?: string | null; + timestamp?: number | null; + }; + Relationships: []; + }; apple_play_button_clicked: { Row: { - appleId: string | null - campaignId: string | null - clientId: string | null - fanId: string | null - game: string | null - id: string - timestamp: number | null - } + appleId: string | null; + campaignId: string | null; + clientId: string | null; + fanId: string | null; + game: string | null; + id: string; + timestamp: number | null; + }; Insert: { - appleId?: string | null - campaignId?: string | null - clientId?: string | null - fanId?: string | null - game?: string | null - id?: string - timestamp?: number | null - } + appleId?: string | null; + campaignId?: string | null; + clientId?: string | null; + fanId?: string | null; + game?: string | null; + id?: string; + timestamp?: number | null; + }; Update: { - appleId?: string | null - campaignId?: string | null - clientId?: string | null - fanId?: string | null - game?: string | null - id?: string - timestamp?: number | null - } + appleId?: string | null; + campaignId?: string | null; + clientId?: string | null; + fanId?: string | null; + game?: string | null; + id?: string; + timestamp?: number | null; + }; Relationships: [ { - foreignKeyName: "apple_play_button_clicked_campaignId_fkey" - columns: ["campaignId"] - isOneToOne: false - referencedRelation: "campaigns" - referencedColumns: ["id"] + foreignKeyName: "apple_play_button_clicked_campaignId_fkey"; + columns: ["campaignId"]; + isOneToOne: false; + referencedRelation: "campaigns"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; artist_fan_segment: { Row: { - artist_social_id: string | null - fan_social_id: string | null - id: string - segment_name: string | null - updated_at: string - } + artist_social_id: string | null; + fan_social_id: string | null; + id: string; + segment_name: string | null; + updated_at: string; + }; Insert: { - artist_social_id?: string | null - fan_social_id?: string | null - id?: string - segment_name?: string | null - updated_at?: string - } + artist_social_id?: string | null; + fan_social_id?: string | null; + id?: string; + segment_name?: string | null; + updated_at?: string; + }; Update: { - artist_social_id?: string | null - fan_social_id?: string | null - id?: string - segment_name?: string | null - updated_at?: string - } + artist_social_id?: string | null; + fan_social_id?: string | null; + id?: string; + segment_name?: string | null; + updated_at?: string; + }; Relationships: [ { - foreignKeyName: "artist_fan_segment_artist_social_id_fkey" - columns: ["artist_social_id"] - isOneToOne: false - referencedRelation: "socials" - referencedColumns: ["id"] + foreignKeyName: "artist_fan_segment_artist_social_id_fkey"; + columns: ["artist_social_id"]; + isOneToOne: false; + referencedRelation: "socials"; + referencedColumns: ["id"]; }, { - foreignKeyName: "artist_fan_segment_fan_social_id_fkey" - columns: ["fan_social_id"] - isOneToOne: false - referencedRelation: "socials" - referencedColumns: ["id"] + foreignKeyName: "artist_fan_segment_fan_social_id_fkey"; + columns: ["fan_social_id"]; + isOneToOne: false; + referencedRelation: "socials"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; artist_organization_ids: { Row: { - artist_id: string - created_at: string | null - id: string - organization_id: string - updated_at: string | null - } + artist_id: string; + created_at: string | null; + id: string; + organization_id: string; + updated_at: string | null; + }; Insert: { - artist_id: string - created_at?: string | null - id?: string - organization_id: string - updated_at?: string | null - } + artist_id: string; + created_at?: string | null; + id?: string; + organization_id: string; + updated_at?: string | null; + }; Update: { - artist_id?: string - created_at?: string | null - id?: string - organization_id?: string - updated_at?: string | null - } + artist_id?: string; + created_at?: string | null; + id?: string; + organization_id?: string; + updated_at?: string | null; + }; Relationships: [ { - foreignKeyName: "artist_organization_ids_artist_id_fkey" - columns: ["artist_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "artist_organization_ids_artist_id_fkey"; + columns: ["artist_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, { - foreignKeyName: "artist_organization_ids_organization_id_fkey" - columns: ["organization_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "artist_organization_ids_organization_id_fkey"; + columns: ["organization_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; artist_segments: { Row: { - artist_account_id: string - id: string - segment_id: string - updated_at: string | null - } + artist_account_id: string; + id: string; + segment_id: string; + updated_at: string | null; + }; Insert: { - artist_account_id: string - id?: string - segment_id: string - updated_at?: string | null - } + artist_account_id: string; + id?: string; + segment_id: string; + updated_at?: string | null; + }; Update: { - artist_account_id?: string - id?: string - segment_id?: string - updated_at?: string | null - } + artist_account_id?: string; + id?: string; + segment_id?: string; + updated_at?: string | null; + }; Relationships: [ { - foreignKeyName: "artist_segments_artist_account_id_fkey" - columns: ["artist_account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "artist_segments_artist_account_id_fkey"; + columns: ["artist_account_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, { - foreignKeyName: "artist_segments_segment_id_fkey" - columns: ["segment_id"] - isOneToOne: false - referencedRelation: "segments" - referencedColumns: ["id"] + foreignKeyName: "artist_segments_segment_id_fkey"; + columns: ["segment_id"]; + isOneToOne: false; + referencedRelation: "segments"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; billing_customers: { Row: { - account_id: string - customer_id: string - email: string | null - id: number - provider: Database["public"]["Enums"]["billing_provider"] - } + account_id: string; + customer_id: string; + email: string | null; + id: number; + provider: Database["public"]["Enums"]["billing_provider"]; + }; Insert: { - account_id: string - customer_id: string - email?: string | null - id?: number - provider: Database["public"]["Enums"]["billing_provider"] - } + account_id: string; + customer_id: string; + email?: string | null; + id?: number; + provider: Database["public"]["Enums"]["billing_provider"]; + }; Update: { - account_id?: string - customer_id?: string - email?: string | null - id?: number - provider?: Database["public"]["Enums"]["billing_provider"] - } - Relationships: [] - } + account_id?: string; + customer_id?: string; + email?: string | null; + id?: number; + provider?: Database["public"]["Enums"]["billing_provider"]; + }; + Relationships: []; + }; campaigns: { Row: { - artist_id: string | null - clientId: string | null - id: string - timestamp: number | null - } + artist_id: string | null; + clientId: string | null; + id: string; + timestamp: number | null; + }; Insert: { - artist_id?: string | null - clientId?: string | null - id?: string - timestamp?: number | null - } + artist_id?: string | null; + clientId?: string | null; + id?: string; + timestamp?: number | null; + }; Update: { - artist_id?: string | null - clientId?: string | null - id?: string - timestamp?: number | null - } + artist_id?: string | null; + clientId?: string | null; + id?: string; + timestamp?: number | null; + }; Relationships: [ { - foreignKeyName: "campaigns_artist_id_fkey" - columns: ["artist_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "campaigns_artist_id_fkey"; + columns: ["artist_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; catalog_songs: { Row: { - catalog: string - created_at: string - id: string - song: string - updated_at: string - } + catalog: string; + created_at: string; + id: string; + song: string; + updated_at: string; + }; Insert: { - catalog: string - created_at?: string - id?: string - song: string - updated_at?: string - } + catalog: string; + created_at?: string; + id?: string; + song: string; + updated_at?: string; + }; Update: { - catalog?: string - created_at?: string - id?: string - song?: string - updated_at?: string - } + catalog?: string; + created_at?: string; + id?: string; + song?: string; + updated_at?: string; + }; Relationships: [ { - foreignKeyName: "catalog_songs_catalog_fkey" - columns: ["catalog"] - isOneToOne: false - referencedRelation: "catalogs" - referencedColumns: ["id"] + foreignKeyName: "catalog_songs_catalog_fkey"; + columns: ["catalog"]; + isOneToOne: false; + referencedRelation: "catalogs"; + referencedColumns: ["id"]; }, { - foreignKeyName: "catalog_songs_song_fkey" - columns: ["song"] - isOneToOne: false - referencedRelation: "songs" - referencedColumns: ["isrc"] + foreignKeyName: "catalog_songs_song_fkey"; + columns: ["song"]; + isOneToOne: false; + referencedRelation: "songs"; + referencedColumns: ["isrc"]; }, - ] - } + ]; + }; catalogs: { Row: { - created_at: string - id: string - name: string - updated_at: string - } + created_at: string; + id: string; + name: string; + updated_at: string; + }; Insert: { - created_at?: string - id?: string - name: string - updated_at?: string - } + created_at?: string; + id?: string; + name: string; + updated_at?: string; + }; Update: { - created_at?: string - id?: string - name?: string - updated_at?: string - } - Relationships: [] - } + created_at?: string; + id?: string; + name?: string; + updated_at?: string; + }; + Relationships: []; + }; chat_messages: { Row: { - chat_id: string - created_at: string - id: string - parts: Json - role: string - } + chat_id: string; + created_at: string; + id: string; + parts: Json; + role: string; + }; Insert: { - chat_id: string - created_at?: string - id: string - parts: Json - role: string - } + chat_id: string; + created_at?: string; + id: string; + parts: Json; + role: string; + }; Update: { - chat_id?: string - created_at?: string - id?: string - parts?: Json - role?: string - } + chat_id?: string; + created_at?: string; + id?: string; + parts?: Json; + role?: string; + }; Relationships: [ { - foreignKeyName: "chat_messages_chat_id_fkey" - columns: ["chat_id"] - isOneToOne: false - referencedRelation: "chats" - referencedColumns: ["id"] + foreignKeyName: "chat_messages_chat_id_fkey"; + columns: ["chat_id"]; + isOneToOne: false; + referencedRelation: "chats"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; chat_reads: { Row: { - account_id: string - chat_id: string - created_at: string - last_read_at: string - updated_at: string - } + account_id: string; + chat_id: string; + created_at: string; + last_read_at: string; + updated_at: string; + }; Insert: { - account_id: string - chat_id: string - created_at?: string - last_read_at?: string - updated_at?: string - } + account_id: string; + chat_id: string; + created_at?: string; + last_read_at?: string; + updated_at?: string; + }; Update: { - account_id?: string - chat_id?: string - created_at?: string - last_read_at?: string - updated_at?: string - } + account_id?: string; + chat_id?: string; + created_at?: string; + last_read_at?: string; + updated_at?: string; + }; Relationships: [ { - foreignKeyName: "chat_reads_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "chat_reads_account_id_fkey"; + columns: ["account_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, { - foreignKeyName: "chat_reads_chat_id_fkey" - columns: ["chat_id"] - isOneToOne: false - referencedRelation: "chats" - referencedColumns: ["id"] + foreignKeyName: "chat_reads_chat_id_fkey"; + columns: ["chat_id"]; + isOneToOne: false; + referencedRelation: "chats"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; chats: { Row: { - active_stream_id: string | null - created_at: string - id: string - last_assistant_message_at: string | null - model_id: string | null - session_id: string - title: string - updated_at: string - } + active_stream_id: string | null; + created_at: string; + id: string; + last_assistant_message_at: string | null; + model_id: string | null; + session_id: string; + title: string; + updated_at: string; + }; Insert: { - active_stream_id?: string | null - created_at?: string - id: string - last_assistant_message_at?: string | null - model_id?: string | null - session_id: string - title: string - updated_at?: string - } + active_stream_id?: string | null; + created_at?: string; + id: string; + last_assistant_message_at?: string | null; + model_id?: string | null; + session_id: string; + title: string; + updated_at?: string; + }; Update: { - active_stream_id?: string | null - created_at?: string - id?: string - last_assistant_message_at?: string | null - model_id?: string | null - session_id?: string - title?: string - updated_at?: string - } + active_stream_id?: string | null; + created_at?: string; + id?: string; + last_assistant_message_at?: string | null; + model_id?: string | null; + session_id?: string; + title?: string; + updated_at?: string; + }; Relationships: [ { - foreignKeyName: "chats_session_id_fkey" - columns: ["session_id"] - isOneToOne: false - referencedRelation: "sessions" - referencedColumns: ["id"] + foreignKeyName: "chats_session_id_fkey"; + columns: ["session_id"]; + isOneToOne: false; + referencedRelation: "sessions"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; config: { Row: { - billing_provider: Database["public"]["Enums"]["billing_provider"] - enable_account_billing: boolean - enable_team_account_billing: boolean - enable_team_accounts: boolean - } + billing_provider: Database["public"]["Enums"]["billing_provider"]; + enable_account_billing: boolean; + enable_team_account_billing: boolean; + enable_team_accounts: boolean; + }; Insert: { - billing_provider?: Database["public"]["Enums"]["billing_provider"] - enable_account_billing?: boolean - enable_team_account_billing?: boolean - enable_team_accounts?: boolean - } + billing_provider?: Database["public"]["Enums"]["billing_provider"]; + enable_account_billing?: boolean; + enable_team_account_billing?: boolean; + enable_team_accounts?: boolean; + }; Update: { - billing_provider?: Database["public"]["Enums"]["billing_provider"] - enable_account_billing?: boolean - enable_team_account_billing?: boolean - enable_team_accounts?: boolean - } - Relationships: [] - } + billing_provider?: Database["public"]["Enums"]["billing_provider"]; + enable_account_billing?: boolean; + enable_team_account_billing?: boolean; + enable_team_accounts?: boolean; + }; + Relationships: []; + }; cookie_players: { Row: { - game: string | null - id: string | null - timestamp: number | null - uniquePlayerID: string | null - } + game: string | null; + id: string | null; + timestamp: number | null; + uniquePlayerID: string | null; + }; Insert: { - game?: string | null - id?: string | null - timestamp?: number | null - uniquePlayerID?: string | null - } + game?: string | null; + id?: string | null; + timestamp?: number | null; + uniquePlayerID?: string | null; + }; Update: { - game?: string | null - id?: string | null - timestamp?: number | null - uniquePlayerID?: string | null - } - Relationships: [] - } + game?: string | null; + id?: string | null; + timestamp?: number | null; + uniquePlayerID?: string | null; + }; + Relationships: []; + }; credits_usage: { Row: { - account_id: string - id: number - remaining_credits: number - timestamp: string | null - } + account_id: string; + id: number; + remaining_credits: number; + timestamp: string | null; + }; Insert: { - account_id: string - id?: number - remaining_credits?: number - timestamp?: string | null - } + account_id: string; + id?: number; + remaining_credits?: number; + timestamp?: string | null; + }; Update: { - account_id?: string - id?: number - remaining_credits?: number - timestamp?: string | null - } + account_id?: string; + id?: number; + remaining_credits?: number; + timestamp?: string | null; + }; Relationships: [ { - foreignKeyName: "credits_usage_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "credits_usage_account_id_fkey"; + columns: ["account_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; cta_redirect: { Row: { - clientId: string - id: number - timestamp: string | null - url: string | null - } + clientId: string; + id: number; + timestamp: string | null; + url: string | null; + }; Insert: { - clientId: string - id?: number - timestamp?: string | null - url?: string | null - } + clientId: string; + id?: number; + timestamp?: string | null; + url?: string | null; + }; Update: { - clientId?: string - id?: number - timestamp?: string | null - url?: string | null - } - Relationships: [] - } + clientId?: string; + id?: number; + timestamp?: string | null; + url?: string | null; + }; + Relationships: []; + }; error_logs: { Row: { - account_id: string | null - created_at: string - error_message: string | null - error_timestamp: string | null - error_type: string | null - id: string - last_message: string | null - raw_message: string - room_id: string | null - stack_trace: string | null - telegram_message_id: number | null - tool_name: string | null - } + account_id: string | null; + created_at: string; + error_message: string | null; + error_timestamp: string | null; + error_type: string | null; + id: string; + last_message: string | null; + raw_message: string; + room_id: string | null; + stack_trace: string | null; + telegram_message_id: number | null; + tool_name: string | null; + }; Insert: { - account_id?: string | null - created_at?: string - error_message?: string | null - error_timestamp?: string | null - error_type?: string | null - id?: string - last_message?: string | null - raw_message: string - room_id?: string | null - stack_trace?: string | null - telegram_message_id?: number | null - tool_name?: string | null - } + account_id?: string | null; + created_at?: string; + error_message?: string | null; + error_timestamp?: string | null; + error_type?: string | null; + id?: string; + last_message?: string | null; + raw_message: string; + room_id?: string | null; + stack_trace?: string | null; + telegram_message_id?: number | null; + tool_name?: string | null; + }; Update: { - account_id?: string | null - created_at?: string - error_message?: string | null - error_timestamp?: string | null - error_type?: string | null - id?: string - last_message?: string | null - raw_message?: string - room_id?: string | null - stack_trace?: string | null - telegram_message_id?: number | null - tool_name?: string | null - } + account_id?: string | null; + created_at?: string; + error_message?: string | null; + error_timestamp?: string | null; + error_type?: string | null; + id?: string; + last_message?: string | null; + raw_message?: string; + room_id?: string | null; + stack_trace?: string | null; + telegram_message_id?: number | null; + tool_name?: string | null; + }; Relationships: [ { - foreignKeyName: "error_logs_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "error_logs_account_id_fkey"; + columns: ["account_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, { - foreignKeyName: "error_logs_room_id_fkey" - columns: ["room_id"] - isOneToOne: false - referencedRelation: "rooms" - referencedColumns: ["id"] + foreignKeyName: "error_logs_room_id_fkey"; + columns: ["room_id"]; + isOneToOne: false; + referencedRelation: "rooms"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; fan_segments: { Row: { - fan_social_id: string - id: string - segment_id: string - updated_at: string | null - } + fan_social_id: string; + id: string; + segment_id: string; + updated_at: string | null; + }; Insert: { - fan_social_id: string - id?: string - segment_id: string - updated_at?: string | null - } + fan_social_id: string; + id?: string; + segment_id: string; + updated_at?: string | null; + }; Update: { - fan_social_id?: string - id?: string - segment_id?: string - updated_at?: string | null - } + fan_social_id?: string; + id?: string; + segment_id?: string; + updated_at?: string | null; + }; Relationships: [ { - foreignKeyName: "fan_segments_fan_social_id_fkey" - columns: ["fan_social_id"] - isOneToOne: false - referencedRelation: "socials" - referencedColumns: ["id"] + foreignKeyName: "fan_segments_fan_social_id_fkey"; + columns: ["fan_social_id"]; + isOneToOne: false; + referencedRelation: "socials"; + referencedColumns: ["id"]; }, { - foreignKeyName: "fan_segments_segment_id_fkey" - columns: ["segment_id"] - isOneToOne: false - referencedRelation: "segments" - referencedColumns: ["id"] + foreignKeyName: "fan_segments_segment_id_fkey"; + columns: ["segment_id"]; + isOneToOne: false; + referencedRelation: "segments"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; fans: { Row: { - account_status: string | null - apple_token: string | null - campaign_id: string | null - campaign_interaction_count: number | null - campaignId: string | null - city: string | null - click_through_rate: number | null - clientId: string | null - consent_given: boolean | null - country: string | null - custom_tags: Json | null - discord_username: string | null - display_name: string | null - email: string | null - email_open_rate: number | null - engagement_level: string | null - episodes: Json | null - explicit_content_filter_enabled: boolean | null - explicit_content_filter_locked: boolean | null - "explicit_content.filter_enabled": boolean | null - "explicit_content.filter_locked": boolean | null - external_urls_spotify: string | null - "external_urls.spotify": string | null - facebook_profile_url: string | null - first_stream_date: string | null - followedArtists: Json | null - followers_total: number | null - "followers.href": string | null - "followers.total": number | null - gamification_points: number | null - genres: Json | null - heavyRotations: Json | null - href: string | null - id: string - images: Json | null - instagram_handle: string | null - last_campaign_interaction: string | null - last_login: string | null - last_purchase_date: string | null - last_stream_date: string | null - linkedin_profile_url: string | null - os_type: string | null - playlist: Json | null - preferences: Json | null - preferred_artists: Json | null - preferred_device: string | null - product: string | null - recentlyPlayed: Json | null - recommendations: Json | null - recommended_events: Json | null - reddit_username: string | null - saved_podcasts: Json | null - savedAlbums: Json | null - savedAudioBooks: Json | null - savedShows: Json | null - savedTracks: Json | null - social_shares: number | null - spotify_token: string | null - subscription_tier: string | null - testField: string | null - tiktok_handle: string | null - time_zone: string | null - timestamp: string | null - top_artists_long_term: Json | null - top_artists_medium_term: Json | null - top_tracks_long_term: Json | null - top_tracks_medium_term: Json | null - top_tracks_short_term: Json | null - topArtists: Json | null - topTracks: Json | null - total_spent: number | null - total_streams: number | null - twitter_handle: string | null - type: string | null - uri: string | null - youtube_channel_url: string | null - } + account_status: string | null; + apple_token: string | null; + campaign_id: string | null; + campaign_interaction_count: number | null; + campaignId: string | null; + city: string | null; + click_through_rate: number | null; + clientId: string | null; + consent_given: boolean | null; + country: string | null; + custom_tags: Json | null; + discord_username: string | null; + display_name: string | null; + email: string | null; + email_open_rate: number | null; + engagement_level: string | null; + episodes: Json | null; + explicit_content_filter_enabled: boolean | null; + explicit_content_filter_locked: boolean | null; + "explicit_content.filter_enabled": boolean | null; + "explicit_content.filter_locked": boolean | null; + external_urls_spotify: string | null; + "external_urls.spotify": string | null; + facebook_profile_url: string | null; + first_stream_date: string | null; + followedArtists: Json | null; + followers_total: number | null; + "followers.href": string | null; + "followers.total": number | null; + gamification_points: number | null; + genres: Json | null; + heavyRotations: Json | null; + href: string | null; + id: string; + images: Json | null; + instagram_handle: string | null; + last_campaign_interaction: string | null; + last_login: string | null; + last_purchase_date: string | null; + last_stream_date: string | null; + linkedin_profile_url: string | null; + os_type: string | null; + playlist: Json | null; + preferences: Json | null; + preferred_artists: Json | null; + preferred_device: string | null; + product: string | null; + recentlyPlayed: Json | null; + recommendations: Json | null; + recommended_events: Json | null; + reddit_username: string | null; + saved_podcasts: Json | null; + savedAlbums: Json | null; + savedAudioBooks: Json | null; + savedShows: Json | null; + savedTracks: Json | null; + social_shares: number | null; + spotify_token: string | null; + subscription_tier: string | null; + testField: string | null; + tiktok_handle: string | null; + time_zone: string | null; + timestamp: string | null; + top_artists_long_term: Json | null; + top_artists_medium_term: Json | null; + top_tracks_long_term: Json | null; + top_tracks_medium_term: Json | null; + top_tracks_short_term: Json | null; + topArtists: Json | null; + topTracks: Json | null; + total_spent: number | null; + total_streams: number | null; + twitter_handle: string | null; + type: string | null; + uri: string | null; + youtube_channel_url: string | null; + }; Insert: { - account_status?: string | null - apple_token?: string | null - campaign_id?: string | null - campaign_interaction_count?: number | null - campaignId?: string | null - city?: string | null - click_through_rate?: number | null - clientId?: string | null - consent_given?: boolean | null - country?: string | null - custom_tags?: Json | null - discord_username?: string | null - display_name?: string | null - email?: string | null - email_open_rate?: number | null - engagement_level?: string | null - episodes?: Json | null - explicit_content_filter_enabled?: boolean | null - explicit_content_filter_locked?: boolean | null - "explicit_content.filter_enabled"?: boolean | null - "explicit_content.filter_locked"?: boolean | null - external_urls_spotify?: string | null - "external_urls.spotify"?: string | null - facebook_profile_url?: string | null - first_stream_date?: string | null - followedArtists?: Json | null - followers_total?: number | null - "followers.href"?: string | null - "followers.total"?: number | null - gamification_points?: number | null - genres?: Json | null - heavyRotations?: Json | null - href?: string | null - id?: string - images?: Json | null - instagram_handle?: string | null - last_campaign_interaction?: string | null - last_login?: string | null - last_purchase_date?: string | null - last_stream_date?: string | null - linkedin_profile_url?: string | null - os_type?: string | null - playlist?: Json | null - preferences?: Json | null - preferred_artists?: Json | null - preferred_device?: string | null - product?: string | null - recentlyPlayed?: Json | null - recommendations?: Json | null - recommended_events?: Json | null - reddit_username?: string | null - saved_podcasts?: Json | null - savedAlbums?: Json | null - savedAudioBooks?: Json | null - savedShows?: Json | null - savedTracks?: Json | null - social_shares?: number | null - spotify_token?: string | null - subscription_tier?: string | null - testField?: string | null - tiktok_handle?: string | null - time_zone?: string | null - timestamp?: string | null - top_artists_long_term?: Json | null - top_artists_medium_term?: Json | null - top_tracks_long_term?: Json | null - top_tracks_medium_term?: Json | null - top_tracks_short_term?: Json | null - topArtists?: Json | null - topTracks?: Json | null - total_spent?: number | null - total_streams?: number | null - twitter_handle?: string | null - type?: string | null - uri?: string | null - youtube_channel_url?: string | null - } + account_status?: string | null; + apple_token?: string | null; + campaign_id?: string | null; + campaign_interaction_count?: number | null; + campaignId?: string | null; + city?: string | null; + click_through_rate?: number | null; + clientId?: string | null; + consent_given?: boolean | null; + country?: string | null; + custom_tags?: Json | null; + discord_username?: string | null; + display_name?: string | null; + email?: string | null; + email_open_rate?: number | null; + engagement_level?: string | null; + episodes?: Json | null; + explicit_content_filter_enabled?: boolean | null; + explicit_content_filter_locked?: boolean | null; + "explicit_content.filter_enabled"?: boolean | null; + "explicit_content.filter_locked"?: boolean | null; + external_urls_spotify?: string | null; + "external_urls.spotify"?: string | null; + facebook_profile_url?: string | null; + first_stream_date?: string | null; + followedArtists?: Json | null; + followers_total?: number | null; + "followers.href"?: string | null; + "followers.total"?: number | null; + gamification_points?: number | null; + genres?: Json | null; + heavyRotations?: Json | null; + href?: string | null; + id?: string; + images?: Json | null; + instagram_handle?: string | null; + last_campaign_interaction?: string | null; + last_login?: string | null; + last_purchase_date?: string | null; + last_stream_date?: string | null; + linkedin_profile_url?: string | null; + os_type?: string | null; + playlist?: Json | null; + preferences?: Json | null; + preferred_artists?: Json | null; + preferred_device?: string | null; + product?: string | null; + recentlyPlayed?: Json | null; + recommendations?: Json | null; + recommended_events?: Json | null; + reddit_username?: string | null; + saved_podcasts?: Json | null; + savedAlbums?: Json | null; + savedAudioBooks?: Json | null; + savedShows?: Json | null; + savedTracks?: Json | null; + social_shares?: number | null; + spotify_token?: string | null; + subscription_tier?: string | null; + testField?: string | null; + tiktok_handle?: string | null; + time_zone?: string | null; + timestamp?: string | null; + top_artists_long_term?: Json | null; + top_artists_medium_term?: Json | null; + top_tracks_long_term?: Json | null; + top_tracks_medium_term?: Json | null; + top_tracks_short_term?: Json | null; + topArtists?: Json | null; + topTracks?: Json | null; + total_spent?: number | null; + total_streams?: number | null; + twitter_handle?: string | null; + type?: string | null; + uri?: string | null; + youtube_channel_url?: string | null; + }; Update: { - account_status?: string | null - apple_token?: string | null - campaign_id?: string | null - campaign_interaction_count?: number | null - campaignId?: string | null - city?: string | null - click_through_rate?: number | null - clientId?: string | null - consent_given?: boolean | null - country?: string | null - custom_tags?: Json | null - discord_username?: string | null - display_name?: string | null - email?: string | null - email_open_rate?: number | null - engagement_level?: string | null - episodes?: Json | null - explicit_content_filter_enabled?: boolean | null - explicit_content_filter_locked?: boolean | null - "explicit_content.filter_enabled"?: boolean | null - "explicit_content.filter_locked"?: boolean | null - external_urls_spotify?: string | null - "external_urls.spotify"?: string | null - facebook_profile_url?: string | null - first_stream_date?: string | null - followedArtists?: Json | null - followers_total?: number | null - "followers.href"?: string | null - "followers.total"?: number | null - gamification_points?: number | null - genres?: Json | null - heavyRotations?: Json | null - href?: string | null - id?: string - images?: Json | null - instagram_handle?: string | null - last_campaign_interaction?: string | null - last_login?: string | null - last_purchase_date?: string | null - last_stream_date?: string | null - linkedin_profile_url?: string | null - os_type?: string | null - playlist?: Json | null - preferences?: Json | null - preferred_artists?: Json | null - preferred_device?: string | null - product?: string | null - recentlyPlayed?: Json | null - recommendations?: Json | null - recommended_events?: Json | null - reddit_username?: string | null - saved_podcasts?: Json | null - savedAlbums?: Json | null - savedAudioBooks?: Json | null - savedShows?: Json | null - savedTracks?: Json | null - social_shares?: number | null - spotify_token?: string | null - subscription_tier?: string | null - testField?: string | null - tiktok_handle?: string | null - time_zone?: string | null - timestamp?: string | null - top_artists_long_term?: Json | null - top_artists_medium_term?: Json | null - top_tracks_long_term?: Json | null - top_tracks_medium_term?: Json | null - top_tracks_short_term?: Json | null - topArtists?: Json | null - topTracks?: Json | null - total_spent?: number | null - total_streams?: number | null - twitter_handle?: string | null - type?: string | null - uri?: string | null - youtube_channel_url?: string | null - } + account_status?: string | null; + apple_token?: string | null; + campaign_id?: string | null; + campaign_interaction_count?: number | null; + campaignId?: string | null; + city?: string | null; + click_through_rate?: number | null; + clientId?: string | null; + consent_given?: boolean | null; + country?: string | null; + custom_tags?: Json | null; + discord_username?: string | null; + display_name?: string | null; + email?: string | null; + email_open_rate?: number | null; + engagement_level?: string | null; + episodes?: Json | null; + explicit_content_filter_enabled?: boolean | null; + explicit_content_filter_locked?: boolean | null; + "explicit_content.filter_enabled"?: boolean | null; + "explicit_content.filter_locked"?: boolean | null; + external_urls_spotify?: string | null; + "external_urls.spotify"?: string | null; + facebook_profile_url?: string | null; + first_stream_date?: string | null; + followedArtists?: Json | null; + followers_total?: number | null; + "followers.href"?: string | null; + "followers.total"?: number | null; + gamification_points?: number | null; + genres?: Json | null; + heavyRotations?: Json | null; + href?: string | null; + id?: string; + images?: Json | null; + instagram_handle?: string | null; + last_campaign_interaction?: string | null; + last_login?: string | null; + last_purchase_date?: string | null; + last_stream_date?: string | null; + linkedin_profile_url?: string | null; + os_type?: string | null; + playlist?: Json | null; + preferences?: Json | null; + preferred_artists?: Json | null; + preferred_device?: string | null; + product?: string | null; + recentlyPlayed?: Json | null; + recommendations?: Json | null; + recommended_events?: Json | null; + reddit_username?: string | null; + saved_podcasts?: Json | null; + savedAlbums?: Json | null; + savedAudioBooks?: Json | null; + savedShows?: Json | null; + savedTracks?: Json | null; + social_shares?: number | null; + spotify_token?: string | null; + subscription_tier?: string | null; + testField?: string | null; + tiktok_handle?: string | null; + time_zone?: string | null; + timestamp?: string | null; + top_artists_long_term?: Json | null; + top_artists_medium_term?: Json | null; + top_tracks_long_term?: Json | null; + top_tracks_medium_term?: Json | null; + top_tracks_short_term?: Json | null; + topArtists?: Json | null; + topTracks?: Json | null; + total_spent?: number | null; + total_streams?: number | null; + twitter_handle?: string | null; + type?: string | null; + uri?: string | null; + youtube_channel_url?: string | null; + }; Relationships: [ { - foreignKeyName: "fans_campaignId_fkey" - columns: ["campaignId"] - isOneToOne: false - referencedRelation: "campaigns" - referencedColumns: ["id"] + foreignKeyName: "fans_campaignId_fkey"; + columns: ["campaignId"]; + isOneToOne: false; + referencedRelation: "campaigns"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; files: { Row: { - artist_account_id: string - created_at: string - description: string | null - file_name: string - id: string - is_directory: boolean - mime_type: string | null - owner_account_id: string - size_bytes: number | null - storage_key: string - tags: string[] | null - updated_at: string - } + artist_account_id: string; + created_at: string; + description: string | null; + file_name: string; + id: string; + is_directory: boolean; + mime_type: string | null; + owner_account_id: string; + size_bytes: number | null; + storage_key: string; + tags: string[] | null; + updated_at: string; + }; Insert: { - artist_account_id: string - created_at?: string - description?: string | null - file_name: string - id?: string - is_directory?: boolean - mime_type?: string | null - owner_account_id: string - size_bytes?: number | null - storage_key: string - tags?: string[] | null - updated_at?: string - } + artist_account_id: string; + created_at?: string; + description?: string | null; + file_name: string; + id?: string; + is_directory?: boolean; + mime_type?: string | null; + owner_account_id: string; + size_bytes?: number | null; + storage_key: string; + tags?: string[] | null; + updated_at?: string; + }; Update: { - artist_account_id?: string - created_at?: string - description?: string | null - file_name?: string - id?: string - is_directory?: boolean - mime_type?: string | null - owner_account_id?: string - size_bytes?: number | null - storage_key?: string - tags?: string[] | null - updated_at?: string - } + artist_account_id?: string; + created_at?: string; + description?: string | null; + file_name?: string; + id?: string; + is_directory?: boolean; + mime_type?: string | null; + owner_account_id?: string; + size_bytes?: number | null; + storage_key?: string; + tags?: string[] | null; + updated_at?: string; + }; Relationships: [ { - foreignKeyName: "files_artist_account_id_fkey" - columns: ["artist_account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "files_artist_account_id_fkey"; + columns: ["artist_account_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, { - foreignKeyName: "files_owner_account_id_fkey" - columns: ["owner_account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "files_owner_account_id_fkey"; + columns: ["owner_account_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; follows: { Row: { - game: string | null - id: string | null - timestamp: number | null - } + game: string | null; + id: string | null; + timestamp: number | null; + }; Insert: { - game?: string | null - id?: string | null - timestamp?: number | null - } + game?: string | null; + id?: string | null; + timestamp?: number | null; + }; Update: { - game?: string | null - id?: string | null - timestamp?: number | null - } - Relationships: [] - } + game?: string | null; + id?: string | null; + timestamp?: number | null; + }; + Relationships: []; + }; founder_dashboard_chart_annotations: { Row: { - chart_type: string | null - created_at: string | null - event_date: string - event_description: string | null - id: string - } + chart_type: string | null; + created_at: string | null; + event_date: string; + event_description: string | null; + id: string; + }; Insert: { - chart_type?: string | null - created_at?: string | null - event_date: string - event_description?: string | null - id?: string - } + chart_type?: string | null; + created_at?: string | null; + event_date: string; + event_description?: string | null; + id?: string; + }; Update: { - chart_type?: string | null - created_at?: string | null - event_date?: string - event_description?: string | null - id?: string - } - Relationships: [] - } + chart_type?: string | null; + created_at?: string | null; + event_date?: string; + event_description?: string | null; + id?: string; + }; + Relationships: []; + }; funnel_analytics: { Row: { - artist_id: string | null - handle: string | null - id: string - pilot_id: string | null - status: number | null - type: Database["public"]["Enums"]["social_type"] | null - updated_at: string - } + artist_id: string | null; + handle: string | null; + id: string; + pilot_id: string | null; + status: number | null; + type: Database["public"]["Enums"]["social_type"] | null; + updated_at: string; + }; Insert: { - artist_id?: string | null - handle?: string | null - id?: string - pilot_id?: string | null - status?: number | null - type?: Database["public"]["Enums"]["social_type"] | null - updated_at?: string - } + artist_id?: string | null; + handle?: string | null; + id?: string; + pilot_id?: string | null; + status?: number | null; + type?: Database["public"]["Enums"]["social_type"] | null; + updated_at?: string; + }; Update: { - artist_id?: string | null - handle?: string | null - id?: string - pilot_id?: string | null - status?: number | null - type?: Database["public"]["Enums"]["social_type"] | null - updated_at?: string - } + artist_id?: string | null; + handle?: string | null; + id?: string; + pilot_id?: string | null; + status?: number | null; + type?: Database["public"]["Enums"]["social_type"] | null; + updated_at?: string; + }; Relationships: [ { - foreignKeyName: "funnel_analytics_artist_id_fkey" - columns: ["artist_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "funnel_analytics_artist_id_fkey"; + columns: ["artist_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; funnel_analytics_accounts: { Row: { - account_id: string | null - analysis_id: string | null - created_at: string - id: string - updated_at: string | null - } + account_id: string | null; + analysis_id: string | null; + created_at: string; + id: string; + updated_at: string | null; + }; Insert: { - account_id?: string | null - analysis_id?: string | null - created_at?: string - id?: string - updated_at?: string | null - } + account_id?: string | null; + analysis_id?: string | null; + created_at?: string; + id?: string; + updated_at?: string | null; + }; Update: { - account_id?: string | null - analysis_id?: string | null - created_at?: string - id?: string - updated_at?: string | null - } + account_id?: string | null; + analysis_id?: string | null; + created_at?: string; + id?: string; + updated_at?: string | null; + }; Relationships: [ { - foreignKeyName: "account_funnel_analytics_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "account_funnel_analytics_account_id_fkey"; + columns: ["account_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, { - foreignKeyName: "account_funnel_analytics_analysis_id_fkey" - columns: ["analysis_id"] - isOneToOne: false - referencedRelation: "funnel_analytics" - referencedColumns: ["id"] + foreignKeyName: "account_funnel_analytics_analysis_id_fkey"; + columns: ["analysis_id"]; + isOneToOne: false; + referencedRelation: "funnel_analytics"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; funnel_analytics_segments: { Row: { - analysis_id: string | null - created_at: string - icon: string | null - id: string - name: string | null - size: number | null - } + analysis_id: string | null; + created_at: string; + icon: string | null; + id: string; + name: string | null; + size: number | null; + }; Insert: { - analysis_id?: string | null - created_at?: string - icon?: string | null - id?: string - name?: string | null - size?: number | null - } + analysis_id?: string | null; + created_at?: string; + icon?: string | null; + id?: string; + name?: string | null; + size?: number | null; + }; Update: { - analysis_id?: string | null - created_at?: string - icon?: string | null - id?: string - name?: string | null - size?: number | null - } + analysis_id?: string | null; + created_at?: string; + icon?: string | null; + id?: string; + name?: string | null; + size?: number | null; + }; Relationships: [ { - foreignKeyName: "funnel_analytics_segments_analysis_id_fkey" - columns: ["analysis_id"] - isOneToOne: false - referencedRelation: "funnel_analytics" - referencedColumns: ["id"] + foreignKeyName: "funnel_analytics_segments_analysis_id_fkey"; + columns: ["analysis_id"]; + isOneToOne: false; + referencedRelation: "funnel_analytics"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; funnel_reports: { Row: { - id: string - next_steps: string | null - report: string | null - stack_unique_id: string | null - timestamp: string - type: Database["public"]["Enums"]["social_type"] | null - } + id: string; + next_steps: string | null; + report: string | null; + stack_unique_id: string | null; + timestamp: string; + type: Database["public"]["Enums"]["social_type"] | null; + }; Insert: { - id?: string - next_steps?: string | null - report?: string | null - stack_unique_id?: string | null - timestamp?: string - type?: Database["public"]["Enums"]["social_type"] | null - } + id?: string; + next_steps?: string | null; + report?: string | null; + stack_unique_id?: string | null; + timestamp?: string; + type?: Database["public"]["Enums"]["social_type"] | null; + }; Update: { - id?: string - next_steps?: string | null - report?: string | null - stack_unique_id?: string | null - timestamp?: string - type?: Database["public"]["Enums"]["social_type"] | null - } - Relationships: [] - } + id?: string; + next_steps?: string | null; + report?: string | null; + stack_unique_id?: string | null; + timestamp?: string; + type?: Database["public"]["Enums"]["social_type"] | null; + }; + Relationships: []; + }; game_start: { Row: { - clientId: string | null - fanId: Json | null - game: string | null - id: string | null - timestamp: number | null - } + clientId: string | null; + fanId: Json | null; + game: string | null; + id: string | null; + timestamp: number | null; + }; Insert: { - clientId?: string | null - fanId?: Json | null - game?: string | null - id?: string | null - timestamp?: number | null - } + clientId?: string | null; + fanId?: Json | null; + game?: string | null; + id?: string | null; + timestamp?: number | null; + }; Update: { - clientId?: string | null - fanId?: Json | null - game?: string | null - id?: string | null - timestamp?: number | null - } - Relationships: [] - } + clientId?: string | null; + fanId?: Json | null; + game?: string | null; + id?: string | null; + timestamp?: number | null; + }; + Relationships: []; + }; invitations: { Row: { - account_id: string - created_at: string - email: string - expires_at: string - id: number - invite_token: string - invited_by: string - role: string - updated_at: string - } + account_id: string; + created_at: string; + email: string; + expires_at: string; + id: number; + invite_token: string; + invited_by: string; + role: string; + updated_at: string; + }; Insert: { - account_id: string - created_at?: string - email: string - expires_at?: string - id?: number - invite_token: string - invited_by: string - role: string - updated_at?: string - } + account_id: string; + created_at?: string; + email: string; + expires_at?: string; + id?: number; + invite_token: string; + invited_by: string; + role: string; + updated_at?: string; + }; Update: { - account_id?: string - created_at?: string - email?: string - expires_at?: string - id?: number - invite_token?: string - invited_by?: string - role?: string - updated_at?: string - } + account_id?: string; + created_at?: string; + email?: string; + expires_at?: string; + id?: number; + invite_token?: string; + invited_by?: string; + role?: string; + updated_at?: string; + }; Relationships: [ { - foreignKeyName: "invitations_role_fkey" - columns: ["role"] - isOneToOne: false - referencedRelation: "roles" - referencedColumns: ["name"] + foreignKeyName: "invitations_role_fkey"; + columns: ["role"]; + isOneToOne: false; + referencedRelation: "roles"; + referencedColumns: ["name"]; }, - ] - } + ]; + }; ios_redirect: { Row: { - clientId: string | null - fanId: string | null - id: string | null - timestamp: number | null - } + clientId: string | null; + fanId: string | null; + id: string | null; + timestamp: number | null; + }; Insert: { - clientId?: string | null - fanId?: string | null - id?: string | null - timestamp?: number | null - } + clientId?: string | null; + fanId?: string | null; + id?: string | null; + timestamp?: number | null; + }; Update: { - clientId?: string | null - fanId?: string | null - id?: string | null - timestamp?: number | null - } - Relationships: [] - } + clientId?: string | null; + fanId?: string | null; + id?: string | null; + timestamp?: number | null; + }; + Relationships: []; + }; leaderboard: { Row: { - id: string | null - Name: string | null - Number: string | null - Score: string | null - Spotify: string | null - "Time._nanoseconds": string | null - "Time._seconds": string | null - } + id: string | null; + Name: string | null; + Number: string | null; + Score: string | null; + Spotify: string | null; + "Time._nanoseconds": string | null; + "Time._seconds": string | null; + }; Insert: { - id?: string | null - Name?: string | null - Number?: string | null - Score?: string | null - Spotify?: string | null - "Time._nanoseconds"?: string | null - "Time._seconds"?: string | null - } + id?: string | null; + Name?: string | null; + Number?: string | null; + Score?: string | null; + Spotify?: string | null; + "Time._nanoseconds"?: string | null; + "Time._seconds"?: string | null; + }; Update: { - id?: string | null - Name?: string | null - Number?: string | null - Score?: string | null - Spotify?: string | null - "Time._nanoseconds"?: string | null - "Time._seconds"?: string | null - } - Relationships: [] - } + id?: string | null; + Name?: string | null; + Number?: string | null; + Score?: string | null; + Spotify?: string | null; + "Time._nanoseconds"?: string | null; + "Time._seconds"?: string | null; + }; + Relationships: []; + }; leaderboard_boogie: { Row: { - clientId: string | null - displayName: string | null - fanId: string | null - gameType: string | null - id: string | null - score: number | null - timestamp: string | null - } + clientId: string | null; + displayName: string | null; + fanId: string | null; + gameType: string | null; + id: string | null; + score: number | null; + timestamp: string | null; + }; Insert: { - clientId?: string | null - displayName?: string | null - fanId?: string | null - gameType?: string | null - id?: string | null - score?: number | null - timestamp?: string | null - } + clientId?: string | null; + displayName?: string | null; + fanId?: string | null; + gameType?: string | null; + id?: string | null; + score?: number | null; + timestamp?: string | null; + }; Update: { - clientId?: string | null - displayName?: string | null - fanId?: string | null - gameType?: string | null - id?: string | null - score?: number | null - timestamp?: string | null - } - Relationships: [] - } + clientId?: string | null; + displayName?: string | null; + fanId?: string | null; + gameType?: string | null; + id?: string | null; + score?: number | null; + timestamp?: string | null; + }; + Relationships: []; + }; leaderboard_luh_tyler_3d: { Row: { - FanId: string | null - id: string | null - Score: string | null - ScorePerTime: string | null - Time: string | null - timestamp: string | null - UserName: string | null - } + FanId: string | null; + id: string | null; + Score: string | null; + ScorePerTime: string | null; + Time: string | null; + timestamp: string | null; + UserName: string | null; + }; Insert: { - FanId?: string | null - id?: string | null - Score?: string | null - ScorePerTime?: string | null - Time?: string | null - timestamp?: string | null - UserName?: string | null - } + FanId?: string | null; + id?: string | null; + Score?: string | null; + ScorePerTime?: string | null; + Time?: string | null; + timestamp?: string | null; + UserName?: string | null; + }; Update: { - FanId?: string | null - id?: string | null - Score?: string | null - ScorePerTime?: string | null - Time?: string | null - timestamp?: string | null - UserName?: string | null - } - Relationships: [] - } + FanId?: string | null; + id?: string | null; + Score?: string | null; + ScorePerTime?: string | null; + Time?: string | null; + timestamp?: string | null; + UserName?: string | null; + }; + Relationships: []; + }; leaderboard_luv: { Row: { - f: string | null - id: string | null - } + f: string | null; + id: string | null; + }; Insert: { - f?: string | null - id?: string | null - } + f?: string | null; + id?: string | null; + }; Update: { - f?: string | null - id?: string | null - } - Relationships: [] - } + f?: string | null; + id?: string | null; + }; + Relationships: []; + }; memories: { Row: { - content: Json - id: string - room_id: string | null - updated_at: string - } + content: Json; + id: string; + room_id: string | null; + updated_at: string; + }; Insert: { - content: Json - id?: string - room_id?: string | null - updated_at?: string - } + content: Json; + id?: string; + room_id?: string | null; + updated_at?: string; + }; Update: { - content?: Json - id?: string - room_id?: string | null - updated_at?: string - } + content?: Json; + id?: string; + room_id?: string | null; + updated_at?: string; + }; Relationships: [ { - foreignKeyName: "memories_room_id_fkey" - columns: ["room_id"] - isOneToOne: false - referencedRelation: "rooms" - referencedColumns: ["id"] + foreignKeyName: "memories_room_id_fkey"; + columns: ["room_id"]; + isOneToOne: false; + referencedRelation: "rooms"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; memory_emails: { Row: { - created_at: string - email_id: string - id: string - memory: string - message_id: string - } + created_at: string; + email_id: string; + id: string; + memory: string; + message_id: string; + }; Insert: { - created_at?: string - email_id: string - id?: string - memory: string - message_id: string - } + created_at?: string; + email_id: string; + id?: string; + memory: string; + message_id: string; + }; Update: { - created_at?: string - email_id?: string - id?: string - memory?: string - message_id?: string - } + created_at?: string; + email_id?: string; + id?: string; + memory?: string; + message_id?: string; + }; Relationships: [ { - foreignKeyName: "memory_emails_memory_fkey" - columns: ["memory"] - isOneToOne: false - referencedRelation: "memories" - referencedColumns: ["id"] + foreignKeyName: "memory_emails_memory_fkey"; + columns: ["memory"]; + isOneToOne: false; + referencedRelation: "memories"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; notifications: { Row: { - account_id: string - body: string - channel: Database["public"]["Enums"]["notification_channel"] - created_at: string - dismissed: boolean - expires_at: string | null - id: number - link: string | null - type: Database["public"]["Enums"]["notification_type"] - } + account_id: string; + body: string; + channel: Database["public"]["Enums"]["notification_channel"]; + created_at: string; + dismissed: boolean; + expires_at: string | null; + id: number; + link: string | null; + type: Database["public"]["Enums"]["notification_type"]; + }; Insert: { - account_id: string - body: string - channel?: Database["public"]["Enums"]["notification_channel"] - created_at?: string - dismissed?: boolean - expires_at?: string | null - id?: never - link?: string | null - type?: Database["public"]["Enums"]["notification_type"] - } + account_id: string; + body: string; + channel?: Database["public"]["Enums"]["notification_channel"]; + created_at?: string; + dismissed?: boolean; + expires_at?: string | null; + id?: never; + link?: string | null; + type?: Database["public"]["Enums"]["notification_type"]; + }; Update: { - account_id?: string - body?: string - channel?: Database["public"]["Enums"]["notification_channel"] - created_at?: string - dismissed?: boolean - expires_at?: string | null - id?: never - link?: string | null - type?: Database["public"]["Enums"]["notification_type"] - } - Relationships: [] - } + account_id?: string; + body?: string; + channel?: Database["public"]["Enums"]["notification_channel"]; + created_at?: string; + dismissed?: boolean; + expires_at?: string | null; + id?: never; + link?: string | null; + type?: Database["public"]["Enums"]["notification_type"]; + }; + Relationships: []; + }; order_items: { Row: { - created_at: string - id: string - order_id: string - price_amount: number | null - product_id: string - quantity: number - updated_at: string - variant_id: string - } + created_at: string; + id: string; + order_id: string; + price_amount: number | null; + product_id: string; + quantity: number; + updated_at: string; + variant_id: string; + }; Insert: { - created_at?: string - id: string - order_id: string - price_amount?: number | null - product_id: string - quantity?: number - updated_at?: string - variant_id: string - } + created_at?: string; + id: string; + order_id: string; + price_amount?: number | null; + product_id: string; + quantity?: number; + updated_at?: string; + variant_id: string; + }; Update: { - created_at?: string - id?: string - order_id?: string - price_amount?: number | null - product_id?: string - quantity?: number - updated_at?: string - variant_id?: string - } + created_at?: string; + id?: string; + order_id?: string; + price_amount?: number | null; + product_id?: string; + quantity?: number; + updated_at?: string; + variant_id?: string; + }; Relationships: [ { - foreignKeyName: "order_items_order_id_fkey" - columns: ["order_id"] - isOneToOne: false - referencedRelation: "orders" - referencedColumns: ["id"] + foreignKeyName: "order_items_order_id_fkey"; + columns: ["order_id"]; + isOneToOne: false; + referencedRelation: "orders"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; orders: { Row: { - account_id: string - billing_customer_id: number - billing_provider: Database["public"]["Enums"]["billing_provider"] - created_at: string - currency: string - id: string - status: Database["public"]["Enums"]["payment_status"] - total_amount: number - updated_at: string - } + account_id: string; + billing_customer_id: number; + billing_provider: Database["public"]["Enums"]["billing_provider"]; + created_at: string; + currency: string; + id: string; + status: Database["public"]["Enums"]["payment_status"]; + total_amount: number; + updated_at: string; + }; Insert: { - account_id: string - billing_customer_id: number - billing_provider: Database["public"]["Enums"]["billing_provider"] - created_at?: string - currency: string - id: string - status: Database["public"]["Enums"]["payment_status"] - total_amount: number - updated_at?: string - } + account_id: string; + billing_customer_id: number; + billing_provider: Database["public"]["Enums"]["billing_provider"]; + created_at?: string; + currency: string; + id: string; + status: Database["public"]["Enums"]["payment_status"]; + total_amount: number; + updated_at?: string; + }; Update: { - account_id?: string - billing_customer_id?: number - billing_provider?: Database["public"]["Enums"]["billing_provider"] - created_at?: string - currency?: string - id?: string - status?: Database["public"]["Enums"]["payment_status"] - total_amount?: number - updated_at?: string - } + account_id?: string; + billing_customer_id?: number; + billing_provider?: Database["public"]["Enums"]["billing_provider"]; + created_at?: string; + currency?: string; + id?: string; + status?: Database["public"]["Enums"]["payment_status"]; + total_amount?: number; + updated_at?: string; + }; Relationships: [ { - foreignKeyName: "orders_billing_customer_id_fkey" - columns: ["billing_customer_id"] - isOneToOne: false - referencedRelation: "billing_customers" - referencedColumns: ["id"] + foreignKeyName: "orders_billing_customer_id_fkey"; + columns: ["billing_customer_id"]; + isOneToOne: false; + referencedRelation: "billing_customers"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; organization_domains: { Row: { - created_at: string | null - domain: string - id: string - organization_id: string - } + created_at: string | null; + domain: string; + id: string; + organization_id: string; + }; Insert: { - created_at?: string | null - domain: string - id?: string - organization_id: string - } + created_at?: string | null; + domain: string; + id?: string; + organization_id: string; + }; Update: { - created_at?: string | null - domain?: string - id?: string - organization_id?: string - } + created_at?: string | null; + domain?: string; + id?: string; + organization_id?: string; + }; Relationships: [ { - foreignKeyName: "organization_domains_organization_id_fkey" - columns: ["organization_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "organization_domains_organization_id_fkey"; + columns: ["organization_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; plans: { Row: { - name: string - tokens_quota: number - variant_id: string - } + name: string; + tokens_quota: number; + variant_id: string; + }; Insert: { - name: string - tokens_quota: number - variant_id: string - } + name: string; + tokens_quota: number; + variant_id: string; + }; Update: { - name?: string - tokens_quota?: number - variant_id?: string - } - Relationships: [] - } + name?: string; + tokens_quota?: number; + variant_id?: string; + }; + Relationships: []; + }; popup_open: { Row: { - campaignId: string | null - clientId: string | null - fanId: string | null - game: string | null - id: string | null - timestamp: string | null - } + campaignId: string | null; + clientId: string | null; + fanId: string | null; + game: string | null; + id: string | null; + timestamp: string | null; + }; Insert: { - campaignId?: string | null - clientId?: string | null - fanId?: string | null - game?: string | null - id?: string | null - timestamp?: string | null - } + campaignId?: string | null; + clientId?: string | null; + fanId?: string | null; + game?: string | null; + id?: string | null; + timestamp?: string | null; + }; Update: { - campaignId?: string | null - clientId?: string | null - fanId?: string | null - game?: string | null - id?: string | null - timestamp?: string | null - } - Relationships: [] - } + campaignId?: string | null; + clientId?: string | null; + fanId?: string | null; + game?: string | null; + id?: string | null; + timestamp?: string | null; + }; + Relationships: []; + }; post_comments: { Row: { - comment: string | null - commented_at: string - id: string - post_id: string | null - social_id: string | null - } + comment: string | null; + commented_at: string; + id: string; + post_id: string | null; + social_id: string | null; + }; Insert: { - comment?: string | null - commented_at: string - id?: string - post_id?: string | null - social_id?: string | null - } + comment?: string | null; + commented_at: string; + id?: string; + post_id?: string | null; + social_id?: string | null; + }; Update: { - comment?: string | null - commented_at?: string - id?: string - post_id?: string | null - social_id?: string | null - } + comment?: string | null; + commented_at?: string; + id?: string; + post_id?: string | null; + social_id?: string | null; + }; Relationships: [ { - foreignKeyName: "post_comments_post_id_fkey" - columns: ["post_id"] - isOneToOne: false - referencedRelation: "posts" - referencedColumns: ["id"] + foreignKeyName: "post_comments_post_id_fkey"; + columns: ["post_id"]; + isOneToOne: false; + referencedRelation: "posts"; + referencedColumns: ["id"]; }, { - foreignKeyName: "post_comments_social_id_fkey" - columns: ["social_id"] - isOneToOne: false - referencedRelation: "socials" - referencedColumns: ["id"] + foreignKeyName: "post_comments_social_id_fkey"; + columns: ["social_id"]; + isOneToOne: false; + referencedRelation: "socials"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; posts: { Row: { - id: string - post_url: string - updated_at: string - } + id: string; + post_url: string; + updated_at: string; + }; Insert: { - id?: string - post_url: string - updated_at?: string - } + id?: string; + post_url: string; + updated_at?: string; + }; Update: { - id?: string - post_url?: string - updated_at?: string - } - Relationships: [] - } + id?: string; + post_url?: string; + updated_at?: string; + }; + Relationships: []; + }; presave: { Row: { - accessToken: string | null - fanId: string | null - "fanId.error.code": string | null - "fanId.error.name": string | null - id: string | null - presaveId: string | null - presaveReleaseDate: string | null - refreshToken: string | null - timestamp: number | null - } + accessToken: string | null; + fanId: string | null; + "fanId.error.code": string | null; + "fanId.error.name": string | null; + id: string | null; + presaveId: string | null; + presaveReleaseDate: string | null; + refreshToken: string | null; + timestamp: number | null; + }; Insert: { - accessToken?: string | null - fanId?: string | null - "fanId.error.code"?: string | null - "fanId.error.name"?: string | null - id?: string | null - presaveId?: string | null - presaveReleaseDate?: string | null - refreshToken?: string | null - timestamp?: number | null - } + accessToken?: string | null; + fanId?: string | null; + "fanId.error.code"?: string | null; + "fanId.error.name"?: string | null; + id?: string | null; + presaveId?: string | null; + presaveReleaseDate?: string | null; + refreshToken?: string | null; + timestamp?: number | null; + }; Update: { - accessToken?: string | null - fanId?: string | null - "fanId.error.code"?: string | null - "fanId.error.name"?: string | null - id?: string | null - presaveId?: string | null - presaveReleaseDate?: string | null - refreshToken?: string | null - timestamp?: number | null - } - Relationships: [] - } + accessToken?: string | null; + fanId?: string | null; + "fanId.error.code"?: string | null; + "fanId.error.name"?: string | null; + id?: string | null; + presaveId?: string | null; + presaveReleaseDate?: string | null; + refreshToken?: string | null; + timestamp?: number | null; + }; + Relationships: []; + }; pulse_accounts: { Row: { - account_id: string - active: boolean - id: string - } + account_id: string; + active: boolean; + id: string; + }; Insert: { - account_id: string - active?: boolean - id?: string - } + account_id: string; + active?: boolean; + id?: string; + }; Update: { - account_id?: string - active?: boolean - id?: string - } + account_id?: string; + active?: boolean; + id?: string; + }; Relationships: [ { - foreignKeyName: "pulse_accounts_account_id_fkey" - columns: ["account_id"] - isOneToOne: true - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "pulse_accounts_account_id_fkey"; + columns: ["account_id"]; + isOneToOne: true; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; role_permissions: { Row: { - id: number - permission: Database["public"]["Enums"]["app_permissions"] - role: string - } + id: number; + permission: Database["public"]["Enums"]["app_permissions"]; + role: string; + }; Insert: { - id?: number - permission: Database["public"]["Enums"]["app_permissions"] - role: string - } + id?: number; + permission: Database["public"]["Enums"]["app_permissions"]; + role: string; + }; Update: { - id?: number - permission?: Database["public"]["Enums"]["app_permissions"] - role?: string - } + id?: number; + permission?: Database["public"]["Enums"]["app_permissions"]; + role?: string; + }; Relationships: [ { - foreignKeyName: "role_permissions_role_fkey" - columns: ["role"] - isOneToOne: false - referencedRelation: "roles" - referencedColumns: ["name"] + foreignKeyName: "role_permissions_role_fkey"; + columns: ["role"]; + isOneToOne: false; + referencedRelation: "roles"; + referencedColumns: ["name"]; }, - ] - } + ]; + }; roles: { Row: { - hierarchy_level: number - name: string - } + hierarchy_level: number; + name: string; + }; Insert: { - hierarchy_level: number - name: string - } + hierarchy_level: number; + name: string; + }; Update: { - hierarchy_level?: number - name?: string - } - Relationships: [] - } + hierarchy_level?: number; + name?: string; + }; + Relationships: []; + }; room_reports: { Row: { - id: string - report_id: string - room_id: string | null - } + id: string; + report_id: string; + room_id: string | null; + }; Insert: { - id?: string - report_id?: string - room_id?: string | null - } + id?: string; + report_id?: string; + room_id?: string | null; + }; Update: { - id?: string - report_id?: string - room_id?: string | null - } + id?: string; + report_id?: string; + room_id?: string | null; + }; Relationships: [ { - foreignKeyName: "room_reports_report_id_fkey" - columns: ["report_id"] - isOneToOne: false - referencedRelation: "segment_reports" - referencedColumns: ["id"] + foreignKeyName: "room_reports_report_id_fkey"; + columns: ["report_id"]; + isOneToOne: false; + referencedRelation: "segment_reports"; + referencedColumns: ["id"]; }, { - foreignKeyName: "room_reports_room_id_fkey" - columns: ["room_id"] - isOneToOne: false - referencedRelation: "rooms" - referencedColumns: ["id"] + foreignKeyName: "room_reports_room_id_fkey"; + columns: ["room_id"]; + isOneToOne: false; + referencedRelation: "rooms"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; rooms: { Row: { - account_id: string | null - artist_id: string | null - id: string - topic: string | null - updated_at: string - } + account_id: string | null; + artist_id: string | null; + id: string; + topic: string | null; + updated_at: string; + }; Insert: { - account_id?: string | null - artist_id?: string | null - id?: string - topic?: string | null - updated_at?: string - } + account_id?: string | null; + artist_id?: string | null; + id?: string; + topic?: string | null; + updated_at?: string; + }; Update: { - account_id?: string | null - artist_id?: string | null - id?: string - topic?: string | null - updated_at?: string - } + account_id?: string | null; + artist_id?: string | null; + id?: string; + topic?: string | null; + updated_at?: string; + }; Relationships: [ { - foreignKeyName: "rooms_artist_id_fkey" - columns: ["artist_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "rooms_artist_id_fkey"; + columns: ["artist_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; sales_pipeline_customers: { Row: { - activity_count: number | null - assigned_to: string | null - company_size: string | null - competitors: string[] | null - contact_email: string | null - contact_name: string | null - contact_phone: string | null - contacts: Json | null - conversion_stage: string | null - conversion_target_date: string | null - created_at: string | null - current_artists: number - current_mrr: number - custom_fields: Json | null - days_in_stage: number | null - domain: string | null - email: string | null - engagement_health: string | null - expected_close_date: string | null - external_ids: Json | null - id: string - industry: string | null - internal_owner: string | null - last_activity_date: string | null - last_activity_type: string | null - last_contact_date: string - logo_url: string | null - lost_reason: string | null - name: string - next_action: string | null - next_activity_date: string | null - next_activity_type: string | null - notes: string | null - order_index: number | null - organization: string | null - potential_artists: number - potential_mrr: number - priority: string | null - probability: number | null - recoupable_user_id: string | null - source: string | null - stage: string - stage_entered_at: string | null - tags: string[] | null - todos: Json | null - trial_end_date: string | null - trial_start_date: string | null - type: string | null - updated_at: string | null - use_case_type: string | null - website: string | null - weighted_mrr: number | null - win_reason: string | null - } + activity_count: number | null; + assigned_to: string | null; + company_size: string | null; + competitors: string[] | null; + contact_email: string | null; + contact_name: string | null; + contact_phone: string | null; + contacts: Json | null; + conversion_stage: string | null; + conversion_target_date: string | null; + created_at: string | null; + current_artists: number; + current_mrr: number; + custom_fields: Json | null; + days_in_stage: number | null; + domain: string | null; + email: string | null; + engagement_health: string | null; + expected_close_date: string | null; + external_ids: Json | null; + id: string; + industry: string | null; + internal_owner: string | null; + last_activity_date: string | null; + last_activity_type: string | null; + last_contact_date: string; + logo_url: string | null; + lost_reason: string | null; + name: string; + next_action: string | null; + next_activity_date: string | null; + next_activity_type: string | null; + notes: string | null; + order_index: number | null; + organization: string | null; + potential_artists: number; + potential_mrr: number; + priority: string | null; + probability: number | null; + recoupable_user_id: string | null; + source: string | null; + stage: string; + stage_entered_at: string | null; + tags: string[] | null; + todos: Json | null; + trial_end_date: string | null; + trial_start_date: string | null; + type: string | null; + updated_at: string | null; + use_case_type: string | null; + website: string | null; + weighted_mrr: number | null; + win_reason: string | null; + }; Insert: { - activity_count?: number | null - assigned_to?: string | null - company_size?: string | null - competitors?: string[] | null - contact_email?: string | null - contact_name?: string | null - contact_phone?: string | null - contacts?: Json | null - conversion_stage?: string | null - conversion_target_date?: string | null - created_at?: string | null - current_artists?: number - current_mrr?: number - custom_fields?: Json | null - days_in_stage?: number | null - domain?: string | null - email?: string | null - engagement_health?: string | null - expected_close_date?: string | null - external_ids?: Json | null - id?: string - industry?: string | null - internal_owner?: string | null - last_activity_date?: string | null - last_activity_type?: string | null - last_contact_date?: string - logo_url?: string | null - lost_reason?: string | null - name: string - next_action?: string | null - next_activity_date?: string | null - next_activity_type?: string | null - notes?: string | null - order_index?: number | null - organization?: string | null - potential_artists?: number - potential_mrr?: number - priority?: string | null - probability?: number | null - recoupable_user_id?: string | null - source?: string | null - stage: string - stage_entered_at?: string | null - tags?: string[] | null - todos?: Json | null - trial_end_date?: string | null - trial_start_date?: string | null - type?: string | null - updated_at?: string | null - use_case_type?: string | null - website?: string | null - weighted_mrr?: number | null - win_reason?: string | null - } + activity_count?: number | null; + assigned_to?: string | null; + company_size?: string | null; + competitors?: string[] | null; + contact_email?: string | null; + contact_name?: string | null; + contact_phone?: string | null; + contacts?: Json | null; + conversion_stage?: string | null; + conversion_target_date?: string | null; + created_at?: string | null; + current_artists?: number; + current_mrr?: number; + custom_fields?: Json | null; + days_in_stage?: number | null; + domain?: string | null; + email?: string | null; + engagement_health?: string | null; + expected_close_date?: string | null; + external_ids?: Json | null; + id?: string; + industry?: string | null; + internal_owner?: string | null; + last_activity_date?: string | null; + last_activity_type?: string | null; + last_contact_date?: string; + logo_url?: string | null; + lost_reason?: string | null; + name: string; + next_action?: string | null; + next_activity_date?: string | null; + next_activity_type?: string | null; + notes?: string | null; + order_index?: number | null; + organization?: string | null; + potential_artists?: number; + potential_mrr?: number; + priority?: string | null; + probability?: number | null; + recoupable_user_id?: string | null; + source?: string | null; + stage: string; + stage_entered_at?: string | null; + tags?: string[] | null; + todos?: Json | null; + trial_end_date?: string | null; + trial_start_date?: string | null; + type?: string | null; + updated_at?: string | null; + use_case_type?: string | null; + website?: string | null; + weighted_mrr?: number | null; + win_reason?: string | null; + }; Update: { - activity_count?: number | null - assigned_to?: string | null - company_size?: string | null - competitors?: string[] | null - contact_email?: string | null - contact_name?: string | null - contact_phone?: string | null - contacts?: Json | null - conversion_stage?: string | null - conversion_target_date?: string | null - created_at?: string | null - current_artists?: number - current_mrr?: number - custom_fields?: Json | null - days_in_stage?: number | null - domain?: string | null - email?: string | null - engagement_health?: string | null - expected_close_date?: string | null - external_ids?: Json | null - id?: string - industry?: string | null - internal_owner?: string | null - last_activity_date?: string | null - last_activity_type?: string | null - last_contact_date?: string - logo_url?: string | null - lost_reason?: string | null - name?: string - next_action?: string | null - next_activity_date?: string | null - next_activity_type?: string | null - notes?: string | null - order_index?: number | null - organization?: string | null - potential_artists?: number - potential_mrr?: number - priority?: string | null - probability?: number | null - recoupable_user_id?: string | null - source?: string | null - stage?: string - stage_entered_at?: string | null - tags?: string[] | null - todos?: Json | null - trial_end_date?: string | null - trial_start_date?: string | null - type?: string | null - updated_at?: string | null - use_case_type?: string | null - website?: string | null - weighted_mrr?: number | null - win_reason?: string | null - } - Relationships: [] - } + activity_count?: number | null; + assigned_to?: string | null; + company_size?: string | null; + competitors?: string[] | null; + contact_email?: string | null; + contact_name?: string | null; + contact_phone?: string | null; + contacts?: Json | null; + conversion_stage?: string | null; + conversion_target_date?: string | null; + created_at?: string | null; + current_artists?: number; + current_mrr?: number; + custom_fields?: Json | null; + days_in_stage?: number | null; + domain?: string | null; + email?: string | null; + engagement_health?: string | null; + expected_close_date?: string | null; + external_ids?: Json | null; + id?: string; + industry?: string | null; + internal_owner?: string | null; + last_activity_date?: string | null; + last_activity_type?: string | null; + last_contact_date?: string; + logo_url?: string | null; + lost_reason?: string | null; + name?: string; + next_action?: string | null; + next_activity_date?: string | null; + next_activity_type?: string | null; + notes?: string | null; + order_index?: number | null; + organization?: string | null; + potential_artists?: number; + potential_mrr?: number; + priority?: string | null; + probability?: number | null; + recoupable_user_id?: string | null; + source?: string | null; + stage?: string; + stage_entered_at?: string | null; + tags?: string[] | null; + todos?: Json | null; + trial_end_date?: string | null; + trial_start_date?: string | null; + type?: string | null; + updated_at?: string | null; + use_case_type?: string | null; + website?: string | null; + weighted_mrr?: number | null; + win_reason?: string | null; + }; + Relationships: []; + }; save_track: { Row: { - game: string | null - id: string | null - timestamp: string | null - } + game: string | null; + id: string | null; + timestamp: string | null; + }; Insert: { - game?: string | null - id?: string | null - timestamp?: string | null - } + game?: string | null; + id?: string | null; + timestamp?: string | null; + }; Update: { - game?: string | null - id?: string | null - timestamp?: string | null - } - Relationships: [] - } + game?: string | null; + id?: string | null; + timestamp?: string | null; + }; + Relationships: []; + }; scheduled_actions: { Row: { - account_id: string - artist_account_id: string - created_at: string | null - enabled: boolean | null - id: string - last_run: string | null - model: string | null - next_run: string | null - prompt: string - schedule: string - title: string - trigger_schedule_id: string | null - updated_at: string | null - } + account_id: string; + artist_account_id: string; + created_at: string | null; + enabled: boolean | null; + id: string; + last_run: string | null; + model: string | null; + next_run: string | null; + prompt: string; + schedule: string; + title: string; + trigger_schedule_id: string | null; + updated_at: string | null; + }; Insert: { - account_id: string - artist_account_id: string - created_at?: string | null - enabled?: boolean | null - id?: string - last_run?: string | null - model?: string | null - next_run?: string | null - prompt: string - schedule: string - title: string - trigger_schedule_id?: string | null - updated_at?: string | null - } + account_id: string; + artist_account_id: string; + created_at?: string | null; + enabled?: boolean | null; + id?: string; + last_run?: string | null; + model?: string | null; + next_run?: string | null; + prompt: string; + schedule: string; + title: string; + trigger_schedule_id?: string | null; + updated_at?: string | null; + }; Update: { - account_id?: string - artist_account_id?: string - created_at?: string | null - enabled?: boolean | null - id?: string - last_run?: string | null - model?: string | null - next_run?: string | null - prompt?: string - schedule?: string - title?: string - trigger_schedule_id?: string | null - updated_at?: string | null - } + account_id?: string; + artist_account_id?: string; + created_at?: string | null; + enabled?: boolean | null; + id?: string; + last_run?: string | null; + model?: string | null; + next_run?: string | null; + prompt?: string; + schedule?: string; + title?: string; + trigger_schedule_id?: string | null; + updated_at?: string | null; + }; Relationships: [ { - foreignKeyName: "scheduled_actions_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "scheduled_actions_account_id_fkey"; + columns: ["account_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, { - foreignKeyName: "scheduled_actions_artist_account_id_fkey" - columns: ["artist_account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "scheduled_actions_artist_account_id_fkey"; + columns: ["artist_account_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; segment_reports: { Row: { - artist_id: string | null - id: string - next_steps: string | null - report: string | null - updated_at: string | null - } + artist_id: string | null; + id: string; + next_steps: string | null; + report: string | null; + updated_at: string | null; + }; Insert: { - artist_id?: string | null - id?: string - next_steps?: string | null - report?: string | null - updated_at?: string | null - } + artist_id?: string | null; + id?: string; + next_steps?: string | null; + report?: string | null; + updated_at?: string | null; + }; Update: { - artist_id?: string | null - id?: string - next_steps?: string | null - report?: string | null - updated_at?: string | null - } + artist_id?: string | null; + id?: string; + next_steps?: string | null; + report?: string | null; + updated_at?: string | null; + }; Relationships: [ { - foreignKeyName: "segment_reports_artist_id_fkey" - columns: ["artist_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "segment_reports_artist_id_fkey"; + columns: ["artist_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; segment_rooms: { Row: { - id: string - room_id: string - segment_id: string - updated_at: string - } + id: string; + room_id: string; + segment_id: string; + updated_at: string; + }; Insert: { - id?: string - room_id: string - segment_id: string - updated_at?: string - } + id?: string; + room_id: string; + segment_id: string; + updated_at?: string; + }; Update: { - id?: string - room_id?: string - segment_id?: string - updated_at?: string - } + id?: string; + room_id?: string; + segment_id?: string; + updated_at?: string; + }; Relationships: [ { - foreignKeyName: "segment_rooms_room_id_fkey" - columns: ["room_id"] - isOneToOne: false - referencedRelation: "rooms" - referencedColumns: ["id"] + foreignKeyName: "segment_rooms_room_id_fkey"; + columns: ["room_id"]; + isOneToOne: false; + referencedRelation: "rooms"; + referencedColumns: ["id"]; }, { - foreignKeyName: "segment_rooms_segment_id_fkey" - columns: ["segment_id"] - isOneToOne: false - referencedRelation: "segments" - referencedColumns: ["id"] + foreignKeyName: "segment_rooms_segment_id_fkey"; + columns: ["segment_id"]; + isOneToOne: false; + referencedRelation: "segments"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; segments: { Row: { - id: string - name: string - updated_at: string | null - } + id: string; + name: string; + updated_at: string | null; + }; Insert: { - id?: string - name: string - updated_at?: string | null - } + id?: string; + name: string; + updated_at?: string | null; + }; Update: { - id?: string - name?: string - updated_at?: string | null - } - Relationships: [] - } + id?: string; + name?: string; + updated_at?: string | null; + }; + Relationships: []; + }; sessions: { Row: { - account_id: string - artist_id: string | null - branch: string | null - cached_diff: Json | null - cached_diff_updated_at: string | null - clone_url: string | null - created_at: string - global_skill_refs: Json - hibernate_after: string | null - id: string - is_new_branch: boolean - last_activity_at: string | null - lifecycle_error: string | null - lifecycle_run_id: string | null - lifecycle_state: string | null - lifecycle_version: number - lines_added: number | null - lines_removed: number | null - repo_name: string | null - repo_owner: string | null - sandbox_expires_at: string | null - sandbox_state: Json | null - snapshot_created_at: string | null - snapshot_size_bytes: number | null - snapshot_url: string | null - status: string - title: string - updated_at: string - } + account_id: string; + artist_id: string | null; + branch: string | null; + cached_diff: Json | null; + cached_diff_updated_at: string | null; + clone_url: string | null; + created_at: string; + global_skill_refs: Json; + hibernate_after: string | null; + id: string; + is_new_branch: boolean; + last_activity_at: string | null; + lifecycle_error: string | null; + lifecycle_run_id: string | null; + lifecycle_state: string | null; + lifecycle_version: number; + lines_added: number | null; + lines_removed: number | null; + repo_name: string | null; + repo_owner: string | null; + sandbox_expires_at: string | null; + sandbox_state: Json | null; + snapshot_created_at: string | null; + snapshot_size_bytes: number | null; + snapshot_url: string | null; + status: string; + title: string; + updated_at: string; + }; Insert: { - account_id: string - artist_id?: string | null - branch?: string | null - cached_diff?: Json | null - cached_diff_updated_at?: string | null - clone_url?: string | null - created_at?: string - global_skill_refs?: Json - hibernate_after?: string | null - id: string - is_new_branch?: boolean - last_activity_at?: string | null - lifecycle_error?: string | null - lifecycle_run_id?: string | null - lifecycle_state?: string | null - lifecycle_version?: number - lines_added?: number | null - lines_removed?: number | null - repo_name?: string | null - repo_owner?: string | null - sandbox_expires_at?: string | null - sandbox_state?: Json | null - snapshot_created_at?: string | null - snapshot_size_bytes?: number | null - snapshot_url?: string | null - status?: string - title: string - updated_at?: string - } + account_id: string; + artist_id?: string | null; + branch?: string | null; + cached_diff?: Json | null; + cached_diff_updated_at?: string | null; + clone_url?: string | null; + created_at?: string; + global_skill_refs?: Json; + hibernate_after?: string | null; + id: string; + is_new_branch?: boolean; + last_activity_at?: string | null; + lifecycle_error?: string | null; + lifecycle_run_id?: string | null; + lifecycle_state?: string | null; + lifecycle_version?: number; + lines_added?: number | null; + lines_removed?: number | null; + repo_name?: string | null; + repo_owner?: string | null; + sandbox_expires_at?: string | null; + sandbox_state?: Json | null; + snapshot_created_at?: string | null; + snapshot_size_bytes?: number | null; + snapshot_url?: string | null; + status?: string; + title: string; + updated_at?: string; + }; Update: { - account_id?: string - artist_id?: string | null - branch?: string | null - cached_diff?: Json | null - cached_diff_updated_at?: string | null - clone_url?: string | null - created_at?: string - global_skill_refs?: Json - hibernate_after?: string | null - id?: string - is_new_branch?: boolean - last_activity_at?: string | null - lifecycle_error?: string | null - lifecycle_run_id?: string | null - lifecycle_state?: string | null - lifecycle_version?: number - lines_added?: number | null - lines_removed?: number | null - repo_name?: string | null - repo_owner?: string | null - sandbox_expires_at?: string | null - sandbox_state?: Json | null - snapshot_created_at?: string | null - snapshot_size_bytes?: number | null - snapshot_url?: string | null - status?: string - title?: string - updated_at?: string - } + account_id?: string; + artist_id?: string | null; + branch?: string | null; + cached_diff?: Json | null; + cached_diff_updated_at?: string | null; + clone_url?: string | null; + created_at?: string; + global_skill_refs?: Json; + hibernate_after?: string | null; + id?: string; + is_new_branch?: boolean; + last_activity_at?: string | null; + lifecycle_error?: string | null; + lifecycle_run_id?: string | null; + lifecycle_state?: string | null; + lifecycle_version?: number; + lines_added?: number | null; + lines_removed?: number | null; + repo_name?: string | null; + repo_owner?: string | null; + sandbox_expires_at?: string | null; + sandbox_state?: Json | null; + snapshot_created_at?: string | null; + snapshot_size_bytes?: number | null; + snapshot_url?: string | null; + status?: string; + title?: string; + updated_at?: string; + }; Relationships: [ { - foreignKeyName: "sessions_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "sessions_account_id_fkey"; + columns: ["account_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, { - foreignKeyName: "sessions_artist_id_fkey" - columns: ["artist_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "sessions_artist_id_fkey"; + columns: ["artist_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; social_fans: { Row: { - artist_social_id: string - created_at: string - fan_social_id: string - id: string - latest_engagement: string | null - latest_engagement_id: string | null - updated_at: string - } + artist_social_id: string; + created_at: string; + fan_social_id: string; + id: string; + latest_engagement: string | null; + latest_engagement_id: string | null; + updated_at: string; + }; Insert: { - artist_social_id: string - created_at?: string - fan_social_id: string - id?: string - latest_engagement?: string | null - latest_engagement_id?: string | null - updated_at?: string - } + artist_social_id: string; + created_at?: string; + fan_social_id: string; + id?: string; + latest_engagement?: string | null; + latest_engagement_id?: string | null; + updated_at?: string; + }; Update: { - artist_social_id?: string - created_at?: string - fan_social_id?: string - id?: string - latest_engagement?: string | null - latest_engagement_id?: string | null - updated_at?: string - } + artist_social_id?: string; + created_at?: string; + fan_social_id?: string; + id?: string; + latest_engagement?: string | null; + latest_engagement_id?: string | null; + updated_at?: string; + }; Relationships: [ { - foreignKeyName: "social_fans_artist_social_id_fkey" - columns: ["artist_social_id"] - isOneToOne: false - referencedRelation: "socials" - referencedColumns: ["id"] + foreignKeyName: "social_fans_artist_social_id_fkey"; + columns: ["artist_social_id"]; + isOneToOne: false; + referencedRelation: "socials"; + referencedColumns: ["id"]; }, { - foreignKeyName: "social_fans_fan_social_id_fkey" - columns: ["fan_social_id"] - isOneToOne: false - referencedRelation: "socials" - referencedColumns: ["id"] + foreignKeyName: "social_fans_fan_social_id_fkey"; + columns: ["fan_social_id"]; + isOneToOne: false; + referencedRelation: "socials"; + referencedColumns: ["id"]; }, { - foreignKeyName: "social_fans_latest_engagement_id_fkey" - columns: ["latest_engagement_id"] - isOneToOne: false - referencedRelation: "post_comments" - referencedColumns: ["id"] + foreignKeyName: "social_fans_latest_engagement_id_fkey"; + columns: ["latest_engagement_id"]; + isOneToOne: false; + referencedRelation: "post_comments"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; social_posts: { Row: { - id: string - post_id: string | null - social_id: string | null - updated_at: string | null - } + id: string; + post_id: string | null; + social_id: string | null; + updated_at: string | null; + }; Insert: { - id?: string - post_id?: string | null - social_id?: string | null - updated_at?: string | null - } + id?: string; + post_id?: string | null; + social_id?: string | null; + updated_at?: string | null; + }; Update: { - id?: string - post_id?: string | null - social_id?: string | null - updated_at?: string | null - } + id?: string; + post_id?: string | null; + social_id?: string | null; + updated_at?: string | null; + }; Relationships: [ { - foreignKeyName: "social_posts_post_id_fkey" - columns: ["post_id"] - isOneToOne: false - referencedRelation: "posts" - referencedColumns: ["id"] + foreignKeyName: "social_posts_post_id_fkey"; + columns: ["post_id"]; + isOneToOne: false; + referencedRelation: "posts"; + referencedColumns: ["id"]; }, { - foreignKeyName: "social_posts_social_id_fkey" - columns: ["social_id"] - isOneToOne: false - referencedRelation: "socials" - referencedColumns: ["id"] + foreignKeyName: "social_posts_social_id_fkey"; + columns: ["social_id"]; + isOneToOne: false; + referencedRelation: "socials"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; social_spotify_albums: { Row: { - album_id: string | null - id: string - social_id: string | null - updated_at: string - } + album_id: string | null; + id: string; + social_id: string | null; + updated_at: string; + }; Insert: { - album_id?: string | null - id?: string - social_id?: string | null - updated_at?: string - } + album_id?: string | null; + id?: string; + social_id?: string | null; + updated_at?: string; + }; Update: { - album_id?: string | null - id?: string - social_id?: string | null - updated_at?: string - } + album_id?: string | null; + id?: string; + social_id?: string | null; + updated_at?: string; + }; Relationships: [ { - foreignKeyName: "social_spotify_albums_album_id_fkey" - columns: ["album_id"] - isOneToOne: false - referencedRelation: "spotify_albums" - referencedColumns: ["id"] + foreignKeyName: "social_spotify_albums_album_id_fkey"; + columns: ["album_id"]; + isOneToOne: false; + referencedRelation: "spotify_albums"; + referencedColumns: ["id"]; }, { - foreignKeyName: "social_spotify_albums_social_id_fkey" - columns: ["social_id"] - isOneToOne: false - referencedRelation: "socials" - referencedColumns: ["id"] + foreignKeyName: "social_spotify_albums_social_id_fkey"; + columns: ["social_id"]; + isOneToOne: false; + referencedRelation: "socials"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; social_spotify_tracks: { Row: { - id: string - social_id: string - track_id: string | null - updated_at: string | null - } + id: string; + social_id: string; + track_id: string | null; + updated_at: string | null; + }; Insert: { - id?: string - social_id?: string - track_id?: string | null - updated_at?: string | null - } + id?: string; + social_id?: string; + track_id?: string | null; + updated_at?: string | null; + }; Update: { - id?: string - social_id?: string - track_id?: string | null - updated_at?: string | null - } + id?: string; + social_id?: string; + track_id?: string | null; + updated_at?: string | null; + }; Relationships: [ { - foreignKeyName: "social_spotify_tracks_social_id_fkey" - columns: ["social_id"] - isOneToOne: false - referencedRelation: "socials" - referencedColumns: ["id"] + foreignKeyName: "social_spotify_tracks_social_id_fkey"; + columns: ["social_id"]; + isOneToOne: false; + referencedRelation: "socials"; + referencedColumns: ["id"]; }, { - foreignKeyName: "social_spotify_tracks_track_id_fkey" - columns: ["track_id"] - isOneToOne: false - referencedRelation: "spotify_tracks" - referencedColumns: ["id"] + foreignKeyName: "social_spotify_tracks_track_id_fkey"; + columns: ["track_id"]; + isOneToOne: false; + referencedRelation: "spotify_tracks"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; socials: { Row: { - avatar: string | null - bio: string | null - followerCount: number | null - followingCount: number | null - id: string - profile_url: string - region: string | null - updated_at: string - username: string - } + avatar: string | null; + bio: string | null; + followerCount: number | null; + followingCount: number | null; + id: string; + profile_url: string; + region: string | null; + updated_at: string; + username: string; + }; Insert: { - avatar?: string | null - bio?: string | null - followerCount?: number | null - followingCount?: number | null - id?: string - profile_url: string - region?: string | null - updated_at?: string - username: string - } + avatar?: string | null; + bio?: string | null; + followerCount?: number | null; + followingCount?: number | null; + id?: string; + profile_url: string; + region?: string | null; + updated_at?: string; + username: string; + }; Update: { - avatar?: string | null - bio?: string | null - followerCount?: number | null - followingCount?: number | null - id?: string - profile_url?: string - region?: string | null - updated_at?: string - username?: string - } - Relationships: [] - } + avatar?: string | null; + bio?: string | null; + followerCount?: number | null; + followingCount?: number | null; + id?: string; + profile_url?: string; + region?: string | null; + updated_at?: string; + username?: string; + }; + Relationships: []; + }; song_artists: { Row: { - artist: string - created_at: string - id: string - song: string - updated_at: string - } + artist: string; + created_at: string; + id: string; + song: string; + updated_at: string; + }; Insert: { - artist: string - created_at?: string - id?: string - song: string - updated_at?: string - } + artist: string; + created_at?: string; + id?: string; + song: string; + updated_at?: string; + }; Update: { - artist?: string - created_at?: string - id?: string - song?: string - updated_at?: string - } + artist?: string; + created_at?: string; + id?: string; + song?: string; + updated_at?: string; + }; Relationships: [ { - foreignKeyName: "song_artists_artist_fkey" - columns: ["artist"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "song_artists_artist_fkey"; + columns: ["artist"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, { - foreignKeyName: "song_artists_song_fkey" - columns: ["song"] - isOneToOne: false - referencedRelation: "songs" - referencedColumns: ["isrc"] + foreignKeyName: "song_artists_song_fkey"; + columns: ["song"]; + isOneToOne: false; + referencedRelation: "songs"; + referencedColumns: ["isrc"]; }, - ] - } + ]; + }; songs: { Row: { - album: string | null - isrc: string - name: string | null - notes: string | null - updated_at: string - } + album: string | null; + isrc: string; + name: string | null; + notes: string | null; + updated_at: string; + }; Insert: { - album?: string | null - isrc: string - name?: string | null - notes?: string | null - updated_at?: string - } + album?: string | null; + isrc: string; + name?: string | null; + notes?: string | null; + updated_at?: string; + }; Update: { - album?: string | null - isrc?: string - name?: string | null - notes?: string | null - updated_at?: string - } - Relationships: [] - } + album?: string | null; + isrc?: string; + name?: string | null; + notes?: string | null; + updated_at?: string; + }; + Relationships: []; + }; spotify: { Row: { - clientId: string | null - country: string | null - display_name: string | null - email: string | null - "explicit_content.filter_enabled": string | null - "explicit_content.filter_locked": string | null - "external_urls.spotify": Json | null - fanId: string | null - "fanId.country": string | null - "fanId.display_name": string | null - "fanId.email": string | null - "fanId.explicit_content.filter_enabled": string | null - "fanId.explicit_content.filter_locked": string | null - "fanId.external_urls.spotify": string | null - "fanId.followers.total": string | null - "fanId.href": string | null - "fanId.id": string | null - "fanId.images": string | null - "fanId.isNewFan": string | null - "fanId.playlist": string | null - "fanId.presavedData.clientId": string | null - "fanId.presavedData.country": string | null - "fanId.presavedData.display_name": string | null - "fanId.presavedData.email": string | null - "fanId.presavedData.explicit_content.filter_enabled": string | null - "fanId.presavedData.explicit_content.filter_locked": string | null - "fanId.presavedData.external_urls.spotify": string | null - "fanId.presavedData.followers.total": string | null - "fanId.presavedData.href": string | null - "fanId.presavedData.id": string | null - "fanId.presavedData.images": string | null - "fanId.presavedData.playlist": string | null - "fanId.presavedData.product": string | null - "fanId.presavedData.recentlyPlayed": string | null - "fanId.presavedData.timestamp": string | null - "fanId.presavedData.type": string | null - "fanId.presavedData.uri": string | null - "fanId.product": string | null - "fanId.timestamp": string | null - "fanId.type": string | null - "fanId.uri": string | null - "followers.total": Json | null - game: string | null - href: string | null - id: string | null - images: Json | null - playlist: Json | null - product: string | null - syncId: string | null - timestamp: string | null - type: string | null - uri: string | null - } + clientId: string | null; + country: string | null; + display_name: string | null; + email: string | null; + "explicit_content.filter_enabled": string | null; + "explicit_content.filter_locked": string | null; + "external_urls.spotify": Json | null; + fanId: string | null; + "fanId.country": string | null; + "fanId.display_name": string | null; + "fanId.email": string | null; + "fanId.explicit_content.filter_enabled": string | null; + "fanId.explicit_content.filter_locked": string | null; + "fanId.external_urls.spotify": string | null; + "fanId.followers.total": string | null; + "fanId.href": string | null; + "fanId.id": string | null; + "fanId.images": string | null; + "fanId.isNewFan": string | null; + "fanId.playlist": string | null; + "fanId.presavedData.clientId": string | null; + "fanId.presavedData.country": string | null; + "fanId.presavedData.display_name": string | null; + "fanId.presavedData.email": string | null; + "fanId.presavedData.explicit_content.filter_enabled": string | null; + "fanId.presavedData.explicit_content.filter_locked": string | null; + "fanId.presavedData.external_urls.spotify": string | null; + "fanId.presavedData.followers.total": string | null; + "fanId.presavedData.href": string | null; + "fanId.presavedData.id": string | null; + "fanId.presavedData.images": string | null; + "fanId.presavedData.playlist": string | null; + "fanId.presavedData.product": string | null; + "fanId.presavedData.recentlyPlayed": string | null; + "fanId.presavedData.timestamp": string | null; + "fanId.presavedData.type": string | null; + "fanId.presavedData.uri": string | null; + "fanId.product": string | null; + "fanId.timestamp": string | null; + "fanId.type": string | null; + "fanId.uri": string | null; + "followers.total": Json | null; + game: string | null; + href: string | null; + id: string | null; + images: Json | null; + playlist: Json | null; + product: string | null; + syncId: string | null; + timestamp: string | null; + type: string | null; + uri: string | null; + }; Insert: { - clientId?: string | null - country?: string | null - display_name?: string | null - email?: string | null - "explicit_content.filter_enabled"?: string | null - "explicit_content.filter_locked"?: string | null - "external_urls.spotify"?: Json | null - fanId?: string | null - "fanId.country"?: string | null - "fanId.display_name"?: string | null - "fanId.email"?: string | null - "fanId.explicit_content.filter_enabled"?: string | null - "fanId.explicit_content.filter_locked"?: string | null - "fanId.external_urls.spotify"?: string | null - "fanId.followers.total"?: string | null - "fanId.href"?: string | null - "fanId.id"?: string | null - "fanId.images"?: string | null - "fanId.isNewFan"?: string | null - "fanId.playlist"?: string | null - "fanId.presavedData.clientId"?: string | null - "fanId.presavedData.country"?: string | null - "fanId.presavedData.display_name"?: string | null - "fanId.presavedData.email"?: string | null - "fanId.presavedData.explicit_content.filter_enabled"?: string | null - "fanId.presavedData.explicit_content.filter_locked"?: string | null - "fanId.presavedData.external_urls.spotify"?: string | null - "fanId.presavedData.followers.total"?: string | null - "fanId.presavedData.href"?: string | null - "fanId.presavedData.id"?: string | null - "fanId.presavedData.images"?: string | null - "fanId.presavedData.playlist"?: string | null - "fanId.presavedData.product"?: string | null - "fanId.presavedData.recentlyPlayed"?: string | null - "fanId.presavedData.timestamp"?: string | null - "fanId.presavedData.type"?: string | null - "fanId.presavedData.uri"?: string | null - "fanId.product"?: string | null - "fanId.timestamp"?: string | null - "fanId.type"?: string | null - "fanId.uri"?: string | null - "followers.total"?: Json | null - game?: string | null - href?: string | null - id?: string | null - images?: Json | null - playlist?: Json | null - product?: string | null - syncId?: string | null - timestamp?: string | null - type?: string | null - uri?: string | null - } + clientId?: string | null; + country?: string | null; + display_name?: string | null; + email?: string | null; + "explicit_content.filter_enabled"?: string | null; + "explicit_content.filter_locked"?: string | null; + "external_urls.spotify"?: Json | null; + fanId?: string | null; + "fanId.country"?: string | null; + "fanId.display_name"?: string | null; + "fanId.email"?: string | null; + "fanId.explicit_content.filter_enabled"?: string | null; + "fanId.explicit_content.filter_locked"?: string | null; + "fanId.external_urls.spotify"?: string | null; + "fanId.followers.total"?: string | null; + "fanId.href"?: string | null; + "fanId.id"?: string | null; + "fanId.images"?: string | null; + "fanId.isNewFan"?: string | null; + "fanId.playlist"?: string | null; + "fanId.presavedData.clientId"?: string | null; + "fanId.presavedData.country"?: string | null; + "fanId.presavedData.display_name"?: string | null; + "fanId.presavedData.email"?: string | null; + "fanId.presavedData.explicit_content.filter_enabled"?: string | null; + "fanId.presavedData.explicit_content.filter_locked"?: string | null; + "fanId.presavedData.external_urls.spotify"?: string | null; + "fanId.presavedData.followers.total"?: string | null; + "fanId.presavedData.href"?: string | null; + "fanId.presavedData.id"?: string | null; + "fanId.presavedData.images"?: string | null; + "fanId.presavedData.playlist"?: string | null; + "fanId.presavedData.product"?: string | null; + "fanId.presavedData.recentlyPlayed"?: string | null; + "fanId.presavedData.timestamp"?: string | null; + "fanId.presavedData.type"?: string | null; + "fanId.presavedData.uri"?: string | null; + "fanId.product"?: string | null; + "fanId.timestamp"?: string | null; + "fanId.type"?: string | null; + "fanId.uri"?: string | null; + "followers.total"?: Json | null; + game?: string | null; + href?: string | null; + id?: string | null; + images?: Json | null; + playlist?: Json | null; + product?: string | null; + syncId?: string | null; + timestamp?: string | null; + type?: string | null; + uri?: string | null; + }; Update: { - clientId?: string | null - country?: string | null - display_name?: string | null - email?: string | null - "explicit_content.filter_enabled"?: string | null - "explicit_content.filter_locked"?: string | null - "external_urls.spotify"?: Json | null - fanId?: string | null - "fanId.country"?: string | null - "fanId.display_name"?: string | null - "fanId.email"?: string | null - "fanId.explicit_content.filter_enabled"?: string | null - "fanId.explicit_content.filter_locked"?: string | null - "fanId.external_urls.spotify"?: string | null - "fanId.followers.total"?: string | null - "fanId.href"?: string | null - "fanId.id"?: string | null - "fanId.images"?: string | null - "fanId.isNewFan"?: string | null - "fanId.playlist"?: string | null - "fanId.presavedData.clientId"?: string | null - "fanId.presavedData.country"?: string | null - "fanId.presavedData.display_name"?: string | null - "fanId.presavedData.email"?: string | null - "fanId.presavedData.explicit_content.filter_enabled"?: string | null - "fanId.presavedData.explicit_content.filter_locked"?: string | null - "fanId.presavedData.external_urls.spotify"?: string | null - "fanId.presavedData.followers.total"?: string | null - "fanId.presavedData.href"?: string | null - "fanId.presavedData.id"?: string | null - "fanId.presavedData.images"?: string | null - "fanId.presavedData.playlist"?: string | null - "fanId.presavedData.product"?: string | null - "fanId.presavedData.recentlyPlayed"?: string | null - "fanId.presavedData.timestamp"?: string | null - "fanId.presavedData.type"?: string | null - "fanId.presavedData.uri"?: string | null - "fanId.product"?: string | null - "fanId.timestamp"?: string | null - "fanId.type"?: string | null - "fanId.uri"?: string | null - "followers.total"?: Json | null - game?: string | null - href?: string | null - id?: string | null - images?: Json | null - playlist?: Json | null - product?: string | null - syncId?: string | null - timestamp?: string | null - type?: string | null - uri?: string | null - } - Relationships: [] - } + clientId?: string | null; + country?: string | null; + display_name?: string | null; + email?: string | null; + "explicit_content.filter_enabled"?: string | null; + "explicit_content.filter_locked"?: string | null; + "external_urls.spotify"?: Json | null; + fanId?: string | null; + "fanId.country"?: string | null; + "fanId.display_name"?: string | null; + "fanId.email"?: string | null; + "fanId.explicit_content.filter_enabled"?: string | null; + "fanId.explicit_content.filter_locked"?: string | null; + "fanId.external_urls.spotify"?: string | null; + "fanId.followers.total"?: string | null; + "fanId.href"?: string | null; + "fanId.id"?: string | null; + "fanId.images"?: string | null; + "fanId.isNewFan"?: string | null; + "fanId.playlist"?: string | null; + "fanId.presavedData.clientId"?: string | null; + "fanId.presavedData.country"?: string | null; + "fanId.presavedData.display_name"?: string | null; + "fanId.presavedData.email"?: string | null; + "fanId.presavedData.explicit_content.filter_enabled"?: string | null; + "fanId.presavedData.explicit_content.filter_locked"?: string | null; + "fanId.presavedData.external_urls.spotify"?: string | null; + "fanId.presavedData.followers.total"?: string | null; + "fanId.presavedData.href"?: string | null; + "fanId.presavedData.id"?: string | null; + "fanId.presavedData.images"?: string | null; + "fanId.presavedData.playlist"?: string | null; + "fanId.presavedData.product"?: string | null; + "fanId.presavedData.recentlyPlayed"?: string | null; + "fanId.presavedData.timestamp"?: string | null; + "fanId.presavedData.type"?: string | null; + "fanId.presavedData.uri"?: string | null; + "fanId.product"?: string | null; + "fanId.timestamp"?: string | null; + "fanId.type"?: string | null; + "fanId.uri"?: string | null; + "followers.total"?: Json | null; + game?: string | null; + href?: string | null; + id?: string | null; + images?: Json | null; + playlist?: Json | null; + product?: string | null; + syncId?: string | null; + timestamp?: string | null; + type?: string | null; + uri?: string | null; + }; + Relationships: []; + }; spotify_albums: { Row: { - id: string - name: string | null - release_date: string | null - updated_at: string - uri: string - } + id: string; + name: string | null; + release_date: string | null; + updated_at: string; + uri: string; + }; Insert: { - id?: string - name?: string | null - release_date?: string | null - updated_at?: string - uri: string - } + id?: string; + name?: string | null; + release_date?: string | null; + updated_at?: string; + uri: string; + }; Update: { - id?: string - name?: string | null - release_date?: string | null - updated_at?: string - uri?: string - } - Relationships: [] - } + id?: string; + name?: string | null; + release_date?: string | null; + updated_at?: string; + uri?: string; + }; + Relationships: []; + }; spotify_analytics_albums: { Row: { - analysis_id: string | null - artist_name: string | null - created_at: string - id: string - name: string | null - release_date: number | null - uri: string | null - } + analysis_id: string | null; + artist_name: string | null; + created_at: string; + id: string; + name: string | null; + release_date: number | null; + uri: string | null; + }; Insert: { - analysis_id?: string | null - artist_name?: string | null - created_at?: string - id?: string - name?: string | null - release_date?: number | null - uri?: string | null - } + analysis_id?: string | null; + artist_name?: string | null; + created_at?: string; + id?: string; + name?: string | null; + release_date?: number | null; + uri?: string | null; + }; Update: { - analysis_id?: string | null - artist_name?: string | null - created_at?: string - id?: string - name?: string | null - release_date?: number | null - uri?: string | null - } + analysis_id?: string | null; + artist_name?: string | null; + created_at?: string; + id?: string; + name?: string | null; + release_date?: number | null; + uri?: string | null; + }; Relationships: [ { - foreignKeyName: "spotify_analytics_albums_analysis_id_fkey" - columns: ["analysis_id"] - isOneToOne: false - referencedRelation: "funnel_analytics" - referencedColumns: ["id"] + foreignKeyName: "spotify_analytics_albums_analysis_id_fkey"; + columns: ["analysis_id"]; + isOneToOne: false; + referencedRelation: "funnel_analytics"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; spotify_analytics_tracks: { Row: { - analysis_id: string | null - artist_name: string | null - created_at: string - id: string - name: string | null - popularity: number | null - uri: string | null - } + analysis_id: string | null; + artist_name: string | null; + created_at: string; + id: string; + name: string | null; + popularity: number | null; + uri: string | null; + }; Insert: { - analysis_id?: string | null - artist_name?: string | null - created_at?: string - id?: string - name?: string | null - popularity?: number | null - uri?: string | null - } + analysis_id?: string | null; + artist_name?: string | null; + created_at?: string; + id?: string; + name?: string | null; + popularity?: number | null; + uri?: string | null; + }; Update: { - analysis_id?: string | null - artist_name?: string | null - created_at?: string - id?: string - name?: string | null - popularity?: number | null - uri?: string | null - } + analysis_id?: string | null; + artist_name?: string | null; + created_at?: string; + id?: string; + name?: string | null; + popularity?: number | null; + uri?: string | null; + }; Relationships: [ { - foreignKeyName: "spotify_analytics_tracks_analysis_id_fkey" - columns: ["analysis_id"] - isOneToOne: false - referencedRelation: "funnel_analytics" - referencedColumns: ["id"] + foreignKeyName: "spotify_analytics_tracks_analysis_id_fkey"; + columns: ["analysis_id"]; + isOneToOne: false; + referencedRelation: "funnel_analytics"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; spotify_login_button_clicked: { Row: { - campaignId: string | null - clientId: string | null - fanId: string | null - game: string | null - id: string | null - timestamp: number | null - } + campaignId: string | null; + clientId: string | null; + fanId: string | null; + game: string | null; + id: string | null; + timestamp: number | null; + }; Insert: { - campaignId?: string | null - clientId?: string | null - fanId?: string | null - game?: string | null - id?: string | null - timestamp?: number | null - } + campaignId?: string | null; + clientId?: string | null; + fanId?: string | null; + game?: string | null; + id?: string | null; + timestamp?: number | null; + }; Update: { - campaignId?: string | null - clientId?: string | null - fanId?: string | null - game?: string | null - id?: string | null - timestamp?: number | null - } + campaignId?: string | null; + clientId?: string | null; + fanId?: string | null; + game?: string | null; + id?: string | null; + timestamp?: number | null; + }; Relationships: [ { - foreignKeyName: "spotify_login_button_clicked_campaignId_fkey" - columns: ["campaignId"] - isOneToOne: false - referencedRelation: "campaigns" - referencedColumns: ["id"] + foreignKeyName: "spotify_login_button_clicked_campaignId_fkey"; + columns: ["campaignId"]; + isOneToOne: false; + referencedRelation: "campaigns"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; spotify_play_button_clicked: { Row: { - campaignId: string | null - clientId: string | null - fanId: string | null - game: string | null - id: string - isPremium: boolean | null - timestamp: number | null - } + campaignId: string | null; + clientId: string | null; + fanId: string | null; + game: string | null; + id: string; + isPremium: boolean | null; + timestamp: number | null; + }; Insert: { - campaignId?: string | null - clientId?: string | null - fanId?: string | null - game?: string | null - id?: string - isPremium?: boolean | null - timestamp?: number | null - } + campaignId?: string | null; + clientId?: string | null; + fanId?: string | null; + game?: string | null; + id?: string; + isPremium?: boolean | null; + timestamp?: number | null; + }; Update: { - campaignId?: string | null - clientId?: string | null - fanId?: string | null - game?: string | null - id?: string - isPremium?: boolean | null - timestamp?: number | null - } + campaignId?: string | null; + clientId?: string | null; + fanId?: string | null; + game?: string | null; + id?: string; + isPremium?: boolean | null; + timestamp?: number | null; + }; Relationships: [ { - foreignKeyName: "spotify_play_button_clicked_campaignId_fkey" - columns: ["campaignId"] - isOneToOne: false - referencedRelation: "campaigns" - referencedColumns: ["id"] + foreignKeyName: "spotify_play_button_clicked_campaignId_fkey"; + columns: ["campaignId"]; + isOneToOne: false; + referencedRelation: "campaigns"; + referencedColumns: ["id"]; }, { - foreignKeyName: "spotify_play_button_clicked_fanId_fkey" - columns: ["fanId"] - isOneToOne: false - referencedRelation: "fans" - referencedColumns: ["id"] + foreignKeyName: "spotify_play_button_clicked_fanId_fkey"; + columns: ["fanId"]; + isOneToOne: false; + referencedRelation: "fans"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; spotify_tracks: { Row: { - id: string - name: string | null - popularity: number | null - updated_at: string - uri: string - } + id: string; + name: string | null; + popularity: number | null; + updated_at: string; + uri: string; + }; Insert: { - id?: string - name?: string | null - popularity?: number | null - updated_at?: string - uri: string - } + id?: string; + name?: string | null; + popularity?: number | null; + updated_at?: string; + uri: string; + }; Update: { - id?: string - name?: string | null - popularity?: number | null - updated_at?: string - uri?: string - } - Relationships: [] - } + id?: string; + name?: string | null; + popularity?: number | null; + updated_at?: string; + uri?: string; + }; + Relationships: []; + }; subscription_items: { Row: { - created_at: string - id: string - interval: string - interval_count: number - price_amount: number | null - product_id: string - quantity: number - subscription_id: string - type: Database["public"]["Enums"]["subscription_item_type"] - updated_at: string - variant_id: string - } + created_at: string; + id: string; + interval: string; + interval_count: number; + price_amount: number | null; + product_id: string; + quantity: number; + subscription_id: string; + type: Database["public"]["Enums"]["subscription_item_type"]; + updated_at: string; + variant_id: string; + }; Insert: { - created_at?: string - id: string - interval: string - interval_count: number - price_amount?: number | null - product_id: string - quantity?: number - subscription_id: string - type: Database["public"]["Enums"]["subscription_item_type"] - updated_at?: string - variant_id: string - } + created_at?: string; + id: string; + interval: string; + interval_count: number; + price_amount?: number | null; + product_id: string; + quantity?: number; + subscription_id: string; + type: Database["public"]["Enums"]["subscription_item_type"]; + updated_at?: string; + variant_id: string; + }; Update: { - created_at?: string - id?: string - interval?: string - interval_count?: number - price_amount?: number | null - product_id?: string - quantity?: number - subscription_id?: string - type?: Database["public"]["Enums"]["subscription_item_type"] - updated_at?: string - variant_id?: string - } + created_at?: string; + id?: string; + interval?: string; + interval_count?: number; + price_amount?: number | null; + product_id?: string; + quantity?: number; + subscription_id?: string; + type?: Database["public"]["Enums"]["subscription_item_type"]; + updated_at?: string; + variant_id?: string; + }; Relationships: [ { - foreignKeyName: "subscription_items_subscription_id_fkey" - columns: ["subscription_id"] - isOneToOne: false - referencedRelation: "subscriptions" - referencedColumns: ["id"] + foreignKeyName: "subscription_items_subscription_id_fkey"; + columns: ["subscription_id"]; + isOneToOne: false; + referencedRelation: "subscriptions"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; subscriptions: { Row: { - account_id: string - active: boolean - billing_customer_id: number - billing_provider: Database["public"]["Enums"]["billing_provider"] - cancel_at_period_end: boolean - created_at: string - currency: string - id: string - period_ends_at: string - period_starts_at: string - status: Database["public"]["Enums"]["subscription_status"] - trial_ends_at: string | null - trial_starts_at: string | null - updated_at: string - } + account_id: string; + active: boolean; + billing_customer_id: number; + billing_provider: Database["public"]["Enums"]["billing_provider"]; + cancel_at_period_end: boolean; + created_at: string; + currency: string; + id: string; + period_ends_at: string; + period_starts_at: string; + status: Database["public"]["Enums"]["subscription_status"]; + trial_ends_at: string | null; + trial_starts_at: string | null; + updated_at: string; + }; Insert: { - account_id: string - active: boolean - billing_customer_id: number - billing_provider: Database["public"]["Enums"]["billing_provider"] - cancel_at_period_end: boolean - created_at?: string - currency: string - id: string - period_ends_at: string - period_starts_at: string - status: Database["public"]["Enums"]["subscription_status"] - trial_ends_at?: string | null - trial_starts_at?: string | null - updated_at?: string - } + account_id: string; + active: boolean; + billing_customer_id: number; + billing_provider: Database["public"]["Enums"]["billing_provider"]; + cancel_at_period_end: boolean; + created_at?: string; + currency: string; + id: string; + period_ends_at: string; + period_starts_at: string; + status: Database["public"]["Enums"]["subscription_status"]; + trial_ends_at?: string | null; + trial_starts_at?: string | null; + updated_at?: string; + }; Update: { - account_id?: string - active?: boolean - billing_customer_id?: number - billing_provider?: Database["public"]["Enums"]["billing_provider"] - cancel_at_period_end?: boolean - created_at?: string - currency?: string - id?: string - period_ends_at?: string - period_starts_at?: string - status?: Database["public"]["Enums"]["subscription_status"] - trial_ends_at?: string | null - trial_starts_at?: string | null - updated_at?: string - } + account_id?: string; + active?: boolean; + billing_customer_id?: number; + billing_provider?: Database["public"]["Enums"]["billing_provider"]; + cancel_at_period_end?: boolean; + created_at?: string; + currency?: string; + id?: string; + period_ends_at?: string; + period_starts_at?: string; + status?: Database["public"]["Enums"]["subscription_status"]; + trial_ends_at?: string | null; + trial_starts_at?: string | null; + updated_at?: string; + }; Relationships: [ { - foreignKeyName: "subscriptions_billing_customer_id_fkey" - columns: ["billing_customer_id"] - isOneToOne: false - referencedRelation: "billing_customers" - referencedColumns: ["id"] + foreignKeyName: "subscriptions_billing_customer_id_fkey"; + columns: ["billing_customer_id"]; + isOneToOne: false; + referencedRelation: "billing_customers"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; tasks: { Row: { - account_id: string - created_at: string - description: string | null - done: boolean - id: string - title: string - updated_at: string - } + account_id: string; + created_at: string; + description: string | null; + done: boolean; + id: string; + title: string; + updated_at: string; + }; Insert: { - account_id: string - created_at?: string - description?: string | null - done?: boolean - id?: string - title: string - updated_at?: string - } + account_id: string; + created_at?: string; + description?: string | null; + done?: boolean; + id?: string; + title: string; + updated_at?: string; + }; Update: { - account_id?: string - created_at?: string - description?: string | null - done?: boolean - id?: string - title?: string - updated_at?: string - } - Relationships: [] - } + account_id?: string; + created_at?: string; + description?: string | null; + done?: boolean; + id?: string; + title?: string; + updated_at?: string; + }; + Relationships: []; + }; test_emails: { Row: { - created_at: string - email: string | null - id: number - } + created_at: string; + email: string | null; + id: number; + }; Insert: { - created_at?: string - email?: string | null - id?: number - } + created_at?: string; + email?: string | null; + id?: number; + }; Update: { - created_at?: string - email?: string | null - id?: number - } - Relationships: [] - } + created_at?: string; + email?: string | null; + id?: number; + }; + Relationships: []; + }; usage_events: { Row: { - account_id: string - agent_type: string - cached_input_tokens: number - created_at: string - credits_deducted_cents: number - id: string - input_tokens: number - model_id: string | null - output_tokens: number - provider: string | null - source: string - tool_call_count: number - } + account_id: string; + agent_type: string; + cached_input_tokens: number; + created_at: string; + credits_deducted_cents: number; + id: string; + input_tokens: number; + model_id: string | null; + output_tokens: number; + provider: string | null; + source: string; + tool_call_count: number; + }; Insert: { - account_id: string - agent_type?: string - cached_input_tokens?: number - created_at?: string - credits_deducted_cents?: number - id: string - input_tokens?: number - model_id?: string | null - output_tokens?: number - provider?: string | null - source?: string - tool_call_count?: number - } + account_id: string; + agent_type?: string; + cached_input_tokens?: number; + created_at?: string; + credits_deducted_cents?: number; + id: string; + input_tokens?: number; + model_id?: string | null; + output_tokens?: number; + provider?: string | null; + source?: string; + tool_call_count?: number; + }; Update: { - account_id?: string - agent_type?: string - cached_input_tokens?: number - created_at?: string - credits_deducted_cents?: number - id?: string - input_tokens?: number - model_id?: string | null - output_tokens?: number - provider?: string | null - source?: string - tool_call_count?: number - } + account_id?: string; + agent_type?: string; + cached_input_tokens?: number; + created_at?: string; + credits_deducted_cents?: number; + id?: string; + input_tokens?: number; + model_id?: string | null; + output_tokens?: number; + provider?: string | null; + source?: string; + tool_call_count?: number; + }; Relationships: [ { - foreignKeyName: "usage_events_account_id_fkey" - columns: ["account_id"] - isOneToOne: false - referencedRelation: "accounts" - referencedColumns: ["id"] + foreignKeyName: "usage_events_account_id_fkey"; + columns: ["account_id"]; + isOneToOne: false; + referencedRelation: "accounts"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; workflow_run_steps: { Row: { - created_at: string - duration_ms: number - finish_reason: string | null - finished_at: string - id: string - raw_finish_reason: string | null - started_at: string - step_number: number - workflow_run_id: string - } + created_at: string; + duration_ms: number; + finish_reason: string | null; + finished_at: string; + id: string; + raw_finish_reason: string | null; + started_at: string; + step_number: number; + workflow_run_id: string; + }; Insert: { - created_at?: string - duration_ms: number - finish_reason?: string | null - finished_at: string - id: string - raw_finish_reason?: string | null - started_at: string - step_number: number - workflow_run_id: string - } + created_at?: string; + duration_ms: number; + finish_reason?: string | null; + finished_at: string; + id: string; + raw_finish_reason?: string | null; + started_at: string; + step_number: number; + workflow_run_id: string; + }; Update: { - created_at?: string - duration_ms?: number - finish_reason?: string | null - finished_at?: string - id?: string - raw_finish_reason?: string | null - started_at?: string - step_number?: number - workflow_run_id?: string - } + created_at?: string; + duration_ms?: number; + finish_reason?: string | null; + finished_at?: string; + id?: string; + raw_finish_reason?: string | null; + started_at?: string; + step_number?: number; + workflow_run_id?: string; + }; Relationships: [ { - foreignKeyName: "workflow_run_steps_workflow_run_id_fkey" - columns: ["workflow_run_id"] - isOneToOne: false - referencedRelation: "workflow_runs" - referencedColumns: ["id"] + foreignKeyName: "workflow_run_steps_workflow_run_id_fkey"; + columns: ["workflow_run_id"]; + isOneToOne: false; + referencedRelation: "workflow_runs"; + referencedColumns: ["id"]; }, - ] - } + ]; + }; workflow_runs: { Row: { - chat_id: string - created_at: string - finished_at: string - id: string - model_id: string | null - started_at: string - status: string - total_duration_ms: number - } + chat_id: string; + created_at: string; + finished_at: string; + id: string; + model_id: string | null; + started_at: string; + status: string; + total_duration_ms: number; + }; Insert: { - chat_id: string - created_at?: string - finished_at: string - id: string - model_id?: string | null - started_at: string - status: string - total_duration_ms: number - } + chat_id: string; + created_at?: string; + finished_at: string; + id: string; + model_id?: string | null; + started_at: string; + status: string; + total_duration_ms: number; + }; Update: { - chat_id?: string - created_at?: string - finished_at?: string - id?: string - model_id?: string | null - started_at?: string - status?: string - total_duration_ms?: number - } + chat_id?: string; + created_at?: string; + finished_at?: string; + id?: string; + model_id?: string | null; + started_at?: string; + status?: string; + total_duration_ms?: number; + }; Relationships: [ { - foreignKeyName: "workflow_runs_chat_id_fkey" - columns: ["chat_id"] - isOneToOne: false - referencedRelation: "chats" - referencedColumns: ["id"] + foreignKeyName: "workflow_runs_chat_id_fkey"; + columns: ["chat_id"]; + isOneToOne: false; + referencedRelation: "chats"; + referencedColumns: ["id"]; }, - ] - } - } + ]; + }; + }; Views: { - [_ in never]: never - } + [_ in never]: never; + }; Functions: { accept_invitation: { - Args: { token: string; user_id: string } - Returns: string - } + Args: { token: string; user_id: string }; + Returns: string; + }; add_invitations_to_account: { Args: { - account_slug: string - invitations: Database["public"]["CompositeTypes"]["invitation"][] - } - Returns: Database["public"]["Tables"]["invitations"]["Row"][] - } + account_slug: string; + invitations: Database["public"]["CompositeTypes"]["invitation"][]; + }; + Returns: Database["public"]["Tables"]["invitations"]["Row"][]; + }; can_action_account_member: { - Args: { target_team_account_id: string; target_user_id: string } - Returns: boolean - } + Args: { target_team_account_id: string; target_user_id: string }; + Returns: boolean; + }; count_reports_by_day: { - Args: { end_date: string; start_date: string } + Args: { end_date: string; start_date: string }; Returns: { - count: number - date_key: string - }[] - } + count: number; + date_key: string; + }[]; + }; count_reports_by_month: { - Args: { end_date: string; start_date: string } + Args: { end_date: string; start_date: string }; Returns: { - count: number - date_key: string - }[] - } + count: number; + date_key: string; + }[]; + }; count_reports_by_week: { - Args: { end_date: string; start_date: string } + Args: { end_date: string; start_date: string }; Returns: { - count: number - date_key: string - }[] - } + count: number; + date_key: string; + }[]; + }; create_invitation: { - Args: { account_id: string; email: string; role: string } + Args: { account_id: string; email: string; role: string }; Returns: { - account_id: string - created_at: string - email: string - expires_at: string - id: number - invite_token: string - invited_by: string - role: string - updated_at: string - } + account_id: string; + created_at: string; + email: string; + expires_at: string; + id: number; + invite_token: string; + invited_by: string; + role: string; + updated_at: string; + }; SetofOptions: { - from: "*" - to: "invitations" - isOneToOne: true - isSetofReturn: false - } - } + from: "*"; + to: "invitations"; + isOneToOne: true; + isSetofReturn: false; + }; + }; deduct_credits: { - Args: { account_id: string; amount: number } - Returns: undefined - } + Args: { account_id: string; amount: number }; + Returns: undefined; + }; deduct_credits_with_audit: { Args: { - p_account_id: string - p_amount: number - p_event: Json - p_event_id: string - } - Returns: undefined - } - extract_domain: { Args: { email: string }; Returns: string } + p_account_id: string; + p_amount: number; + p_event: Json; + p_event_id: string; + }; + Returns: undefined; + }; + extract_domain: { Args: { email: string }; Returns: string }; get_account_invitations: { - Args: { account_slug: string } + Args: { account_slug: string }; Returns: { - account_id: string - created_at: string - email: string - expires_at: string - id: number - invited_by: string - inviter_email: string - inviter_name: string - role: string - updated_at: string - }[] - } + account_id: string; + created_at: string; + email: string; + expires_at: string; + id: number; + invited_by: string; + inviter_email: string; + inviter_name: string; + role: string; + updated_at: string; + }[]; + }; get_account_members: { - Args: { account_slug: string } + Args: { account_slug: string }; Returns: { - account_id: string - created_at: string - email: string - id: string - name: string - picture_url: string - primary_owner_user_id: string - role: string - role_hierarchy_level: number - updated_at: string - user_id: string - }[] - } + account_id: string; + created_at: string; + email: string; + id: string; + name: string; + picture_url: string; + primary_owner_user_id: string; + role: string; + role_hierarchy_level: number; + updated_at: string; + user_id: string; + }[]; + }; get_campaign: | { Args: { clientid: string }; Returns: Json } | { - Args: { artistid: string; campaignid: string; email: string } - Returns: Json - } + Args: { artistid: string; campaignid: string; email: string }; + Returns: Json; + }; get_campaign_fans: { - Args: { artistid: string; email: string } - Returns: Json - } - get_config: { Args: never; Returns: Json } + Args: { artistid: string; email: string }; + Returns: Json; + }; + get_config: { Args: never; Returns: Json }; get_fans_listening_top_songs: { - Args: { artistid: string; email: string } - Returns: Json - } + Args: { artistid: string; email: string }; + Returns: Json; + }; get_message_counts_by_user: | { - Args: { start_date: string } + Args: { start_date: string }; Returns: { - account_email: string - message_count: number - }[] + account_email: string; + message_count: number; + }[]; } | { - Args: { end_date: string; start_date: string } + Args: { end_date: string; start_date: string }; Returns: { - account_email: string - message_count: number - }[] - } + account_email: string; + message_count: number; + }[]; + }; get_rooms_created_by_user: { - Args: { start_date: string } + Args: { start_date: string }; Returns: { - account_email: string - rooms_created: number - }[] - } + account_email: string; + rooms_created: number; + }[]; + }; get_segment_reports_by_user: { - Args: { start_date: string } + Args: { start_date: string }; Returns: { - email: string - segment_report_count: number - }[] - } - get_upper_system_role: { Args: never; Returns: string } + email: string; + segment_report_count: number; + }[]; + }; + get_upper_system_role: { Args: never; Returns: string }; has_active_subscription: { - Args: { target_account_id: string } - Returns: boolean - } - has_credits: { Args: { account_id: string }; Returns: boolean } + Args: { target_account_id: string }; + Returns: boolean; + }; + has_credits: { Args: { account_id: string }; Returns: boolean }; has_more_elevated_role: { Args: { - role_name: string - target_account_id: string - target_user_id: string - } - Returns: boolean - } + role_name: string; + target_account_id: string; + target_user_id: string; + }; + Returns: boolean; + }; has_permission: { Args: { - account_id: string - permission_name: Database["public"]["Enums"]["app_permissions"] - user_id: string - } - Returns: boolean - } + account_id: string; + permission_name: Database["public"]["Enums"]["app_permissions"]; + user_id: string; + }; + Returns: boolean; + }; has_role_on_account: { - Args: { account_id: string; account_role?: string } - Returns: boolean - } + Args: { account_id: string; account_role?: string }; + Returns: boolean; + }; has_same_role_hierarchy_level: { Args: { - role_name: string - target_account_id: string - target_user_id: string - } - Returns: boolean - } - is_account_owner: { Args: { account_id: string }; Returns: boolean } + role_name: string; + target_account_id: string; + target_user_id: string; + }; + Returns: boolean; + }; + is_account_owner: { Args: { account_id: string }; Returns: boolean }; is_account_team_member: { - Args: { target_account_id: string } - Returns: boolean - } - is_set: { Args: { field_name: string }; Returns: boolean } + Args: { target_account_id: string }; + Returns: boolean; + }; + is_set: { Args: { field_name: string }; Returns: boolean }; is_team_member: { - Args: { account_id: string; user_id: string } - Returns: boolean - } + Args: { account_id: string; user_id: string }; + Returns: boolean; + }; team_account_workspace: { - Args: { account_slug: string } + Args: { account_slug: string }; Returns: { - id: string - name: string - permissions: Database["public"]["Enums"]["app_permissions"][] - picture_url: string - primary_owner_user_id: string - role: string - role_hierarchy_level: number - slug: string - subscription_status: Database["public"]["Enums"]["subscription_status"] - }[] - } + id: string; + name: string; + permissions: Database["public"]["Enums"]["app_permissions"][]; + picture_url: string; + primary_owner_user_id: string; + role: string; + role_hierarchy_level: number; + slug: string; + subscription_status: Database["public"]["Enums"]["subscription_status"]; + }[]; + }; transfer_team_account_ownership: { - Args: { new_owner_id: string; target_account_id: string } - Returns: undefined - } + Args: { new_owner_id: string; target_account_id: string }; + Returns: undefined; + }; upsert_order: { Args: { - billing_provider: Database["public"]["Enums"]["billing_provider"] - currency: string - line_items: Json - status: Database["public"]["Enums"]["payment_status"] - target_account_id: string - target_customer_id: string - target_order_id: string - total_amount: number - } + billing_provider: Database["public"]["Enums"]["billing_provider"]; + currency: string; + line_items: Json; + status: Database["public"]["Enums"]["payment_status"]; + target_account_id: string; + target_customer_id: string; + target_order_id: string; + total_amount: number; + }; Returns: { - account_id: string - billing_customer_id: number - billing_provider: Database["public"]["Enums"]["billing_provider"] - created_at: string - currency: string - id: string - status: Database["public"]["Enums"]["payment_status"] - total_amount: number - updated_at: string - } + account_id: string; + billing_customer_id: number; + billing_provider: Database["public"]["Enums"]["billing_provider"]; + created_at: string; + currency: string; + id: string; + status: Database["public"]["Enums"]["payment_status"]; + total_amount: number; + updated_at: string; + }; SetofOptions: { - from: "*" - to: "orders" - isOneToOne: true - isSetofReturn: false - } - } + from: "*"; + to: "orders"; + isOneToOne: true; + isSetofReturn: false; + }; + }; upsert_subscription: { Args: { - active: boolean - billing_provider: Database["public"]["Enums"]["billing_provider"] - cancel_at_period_end: boolean - currency: string - line_items: Json - period_ends_at: string - period_starts_at: string - status: Database["public"]["Enums"]["subscription_status"] - target_account_id: string - target_customer_id: string - target_subscription_id: string - trial_ends_at?: string - trial_starts_at?: string - } + active: boolean; + billing_provider: Database["public"]["Enums"]["billing_provider"]; + cancel_at_period_end: boolean; + currency: string; + line_items: Json; + period_ends_at: string; + period_starts_at: string; + status: Database["public"]["Enums"]["subscription_status"]; + target_account_id: string; + target_customer_id: string; + target_subscription_id: string; + trial_ends_at?: string; + trial_starts_at?: string; + }; Returns: { - account_id: string - active: boolean - billing_customer_id: number - billing_provider: Database["public"]["Enums"]["billing_provider"] - cancel_at_period_end: boolean - created_at: string - currency: string - id: string - period_ends_at: string - period_starts_at: string - status: Database["public"]["Enums"]["subscription_status"] - trial_ends_at: string | null - trial_starts_at: string | null - updated_at: string - } + account_id: string; + active: boolean; + billing_customer_id: number; + billing_provider: Database["public"]["Enums"]["billing_provider"]; + cancel_at_period_end: boolean; + created_at: string; + currency: string; + id: string; + period_ends_at: string; + period_starts_at: string; + status: Database["public"]["Enums"]["subscription_status"]; + trial_ends_at: string | null; + trial_starts_at: string | null; + updated_at: string; + }; SetofOptions: { - from: "*" - to: "subscriptions" - isOneToOne: true - isSetofReturn: false - } - } - } + from: "*"; + to: "subscriptions"; + isOneToOne: true; + isSetofReturn: false; + }; + }; + }; Enums: { app_permissions: | "roles.manage" @@ -4201,20 +4195,14 @@ export type Database = { | "members.manage" | "invites.manage" | "tasks.write" - | "tasks.delete" - billing_provider: "stripe" | "lemon-squeezy" | "paddle" - chat_role: "user" | "assistant" - notification_channel: "in_app" | "email" - notification_type: "info" | "warning" | "error" - payment_status: "pending" | "succeeded" | "failed" - social_type: - | "TIKTOK" - | "YOUTUBE" - | "INSTAGRAM" - | "TWITTER" - | "SPOTIFY" - | "APPLE" - subscription_item_type: "flat" | "per_seat" | "metered" + | "tasks.delete"; + billing_provider: "stripe" | "lemon-squeezy" | "paddle"; + chat_role: "user" | "assistant"; + notification_channel: "in_app" | "email"; + notification_type: "info" | "warning" | "error"; + payment_status: "pending" | "succeeded" | "failed"; + social_type: "TIKTOK" | "YOUTUBE" | "INSTAGRAM" | "TWITTER" | "SPOTIFY" | "APPLE"; + subscription_item_type: "flat" | "per_seat" | "metered"; subscription_status: | "active" | "trialing" @@ -4223,133 +4211,131 @@ export type Database = { | "unpaid" | "incomplete" | "incomplete_expired" - | "paused" - } + | "paused"; + }; CompositeTypes: { invitation: { - email: string | null - role: string | null - } - } - } -} + email: string | null; + role: string | null; + }; + }; + }; +}; -type DatabaseWithoutInternals = Omit +type DatabaseWithoutInternals = Omit; -type DefaultSchema = DatabaseWithoutInternals[Extract] +type DefaultSchema = DatabaseWithoutInternals[Extract]; export type Tables< DefaultSchemaTableNameOrOptions extends | keyof (DefaultSchema["Tables"] & DefaultSchema["Views"]) | { schema: keyof DatabaseWithoutInternals }, TableName extends DefaultSchemaTableNameOrOptions extends { - schema: keyof DatabaseWithoutInternals + schema: keyof DatabaseWithoutInternals; } ? keyof (DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] & DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Views"]) : never = never, > = DefaultSchemaTableNameOrOptions extends { - schema: keyof DatabaseWithoutInternals + schema: keyof DatabaseWithoutInternals; } ? (DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] & DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Views"])[TableName] extends { - Row: infer R + Row: infer R; } ? R : never - : DefaultSchemaTableNameOrOptions extends keyof (DefaultSchema["Tables"] & - DefaultSchema["Views"]) - ? (DefaultSchema["Tables"] & - DefaultSchema["Views"])[DefaultSchemaTableNameOrOptions] extends { - Row: infer R + : DefaultSchemaTableNameOrOptions extends keyof (DefaultSchema["Tables"] & DefaultSchema["Views"]) + ? (DefaultSchema["Tables"] & DefaultSchema["Views"])[DefaultSchemaTableNameOrOptions] extends { + Row: infer R; } ? R : never - : never + : never; export type TablesInsert< DefaultSchemaTableNameOrOptions extends | keyof DefaultSchema["Tables"] | { schema: keyof DatabaseWithoutInternals }, TableName extends DefaultSchemaTableNameOrOptions extends { - schema: keyof DatabaseWithoutInternals + schema: keyof DatabaseWithoutInternals; } ? keyof DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] : never = never, > = DefaultSchemaTableNameOrOptions extends { - schema: keyof DatabaseWithoutInternals + schema: keyof DatabaseWithoutInternals; } ? DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"][TableName] extends { - Insert: infer I + Insert: infer I; } ? I : never : DefaultSchemaTableNameOrOptions extends keyof DefaultSchema["Tables"] ? DefaultSchema["Tables"][DefaultSchemaTableNameOrOptions] extends { - Insert: infer I + Insert: infer I; } ? I : never - : never + : never; export type TablesUpdate< DefaultSchemaTableNameOrOptions extends | keyof DefaultSchema["Tables"] | { schema: keyof DatabaseWithoutInternals }, TableName extends DefaultSchemaTableNameOrOptions extends { - schema: keyof DatabaseWithoutInternals + schema: keyof DatabaseWithoutInternals; } ? keyof DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"] : never = never, > = DefaultSchemaTableNameOrOptions extends { - schema: keyof DatabaseWithoutInternals + schema: keyof DatabaseWithoutInternals; } ? DatabaseWithoutInternals[DefaultSchemaTableNameOrOptions["schema"]]["Tables"][TableName] extends { - Update: infer U + Update: infer U; } ? U : never : DefaultSchemaTableNameOrOptions extends keyof DefaultSchema["Tables"] ? DefaultSchema["Tables"][DefaultSchemaTableNameOrOptions] extends { - Update: infer U + Update: infer U; } ? U : never - : never + : never; export type Enums< DefaultSchemaEnumNameOrOptions extends | keyof DefaultSchema["Enums"] | { schema: keyof DatabaseWithoutInternals }, EnumName extends DefaultSchemaEnumNameOrOptions extends { - schema: keyof DatabaseWithoutInternals + schema: keyof DatabaseWithoutInternals; } ? keyof DatabaseWithoutInternals[DefaultSchemaEnumNameOrOptions["schema"]]["Enums"] : never = never, > = DefaultSchemaEnumNameOrOptions extends { - schema: keyof DatabaseWithoutInternals + schema: keyof DatabaseWithoutInternals; } ? DatabaseWithoutInternals[DefaultSchemaEnumNameOrOptions["schema"]]["Enums"][EnumName] : DefaultSchemaEnumNameOrOptions extends keyof DefaultSchema["Enums"] ? DefaultSchema["Enums"][DefaultSchemaEnumNameOrOptions] - : never + : never; export type CompositeTypes< PublicCompositeTypeNameOrOptions extends | keyof DefaultSchema["CompositeTypes"] | { schema: keyof DatabaseWithoutInternals }, CompositeTypeName extends PublicCompositeTypeNameOrOptions extends { - schema: keyof DatabaseWithoutInternals + schema: keyof DatabaseWithoutInternals; } ? keyof DatabaseWithoutInternals[PublicCompositeTypeNameOrOptions["schema"]]["CompositeTypes"] : never = never, > = PublicCompositeTypeNameOrOptions extends { - schema: keyof DatabaseWithoutInternals + schema: keyof DatabaseWithoutInternals; } ? DatabaseWithoutInternals[PublicCompositeTypeNameOrOptions["schema"]]["CompositeTypes"][CompositeTypeName] : PublicCompositeTypeNameOrOptions extends keyof DefaultSchema["CompositeTypes"] ? DefaultSchema["CompositeTypes"][PublicCompositeTypeNameOrOptions] - : never + : never; export const Constants = { public: { @@ -4368,14 +4354,7 @@ export const Constants = { notification_channel: ["in_app", "email"], notification_type: ["info", "warning", "error"], payment_status: ["pending", "succeeded", "failed"], - social_type: [ - "TIKTOK", - "YOUTUBE", - "INSTAGRAM", - "TWITTER", - "SPOTIFY", - "APPLE", - ], + social_type: ["TIKTOK", "YOUTUBE", "INSTAGRAM", "TWITTER", "SPOTIFY", "APPLE"], subscription_item_type: ["flat", "per_seat", "metered"], subscription_status: [ "active", @@ -4389,4 +4368,4 @@ export const Constants = { ], }, }, -} as const +} as const;