Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 0 additions & 70 deletions apps/website/app/api/supabase/account/route.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import {
makeDefaultDeleteHandler,
} from "~/utils/supabase/apiUtils";

export const GET = makeDefaultGetHandler("Account");
export const GET = makeDefaultGetHandler("AgentIdentifier");

export const OPTIONS = defaultOptionsHandler;

export const DELETE = makeDefaultDeleteHandler("Account");
export const DELETE = makeDefaultDeleteHandler("AgentIdentifier");
66 changes: 66 additions & 0 deletions apps/website/app/api/supabase/agent-identifier/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { NextResponse, NextRequest } from "next/server";

import { createClient } from "~/utils/supabase/server";
import { getOrCreateEntity, ItemValidator } from "~/utils/supabase/dbUtils";
import {
createApiResponse,
handleRouteError,
defaultOptionsHandler,
asPostgrestFailure,
} from "~/utils/supabase/apiUtils";
import { TablesInsert, Constants } from "@repo/database/types.gen.ts";

type AgentIdentifierDataInput = TablesInsert<"AgentIdentifier">;
const { AgentIdentifierType } = Constants.public.Enums;

const agentIdentifierValidator: ItemValidator<AgentIdentifierDataInput> = (agent_identifier: any) => {
if (!agent_identifier || typeof agent_identifier !== "object")
return "Invalid request body: expected a JSON object.";
const {
identifier_type,
account_id,
value,
trusted,
} = agent_identifier;

if (!AgentIdentifierType.includes(identifier_type))
return "Invalid identifier_type";
if (!value || typeof value !== "string" || value.trim() === "")
return "Missing or invalid value";
if (!account_id || Number.isNaN(Number.parseInt(account_id, 10)))
return "Missing or invalid account_id";
if (trusted !== undefined && !["true", "false", true, false].includes(trusted))
return "if included, trusted should be a boolean";

const keys = [ 'identifier_type', 'account_id', 'value', 'trusted' ];
if (!Object.keys(agent_identifier).every((key)=>keys.includes(key)))
return "Invalid agent_identifier object: extra keys";
return null;
};

export const POST = async (request: NextRequest): Promise<NextResponse> => {
const supabasePromise = createClient();

try {
const body = await request.json();
const error = agentIdentifierValidator(body);
if (error !== null)
return createApiResponse(request, asPostgrestFailure(error, "invalid"));

body.account_id = Number.parseInt(body.account_id, 10);
body.trusted = body.trusted === true || body.trusted === "true" || false;
const supabase = await supabasePromise;
const result = await getOrCreateEntity<"AgentIdentifier">({
supabase,
tableName: "AgentIdentifier",
insertData: body as AgentIdentifierDataInput,
uniqueOn: ["value", "identifier_type", "account_id"],
});

return createApiResponse(request, result);
} catch (e: unknown) {
return handleRouteError(request, e, "/api/supabase/agent-identifier");
}
};

export const OPTIONS = defaultOptionsHandler;
11 changes: 0 additions & 11 deletions apps/website/app/api/supabase/person/[id].ts

This file was deleted.

85 changes: 0 additions & 85 deletions apps/website/app/api/supabase/person/route.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import {
makeDefaultDeleteHandler,
} from "~/utils/supabase/apiUtils";

export const GET = makeDefaultGetHandler("Platform");
export const GET = makeDefaultGetHandler("PlatformAccount");

export const OPTIONS = defaultOptionsHandler;

export const DELETE = makeDefaultDeleteHandler("Platform");
export const DELETE = makeDefaultDeleteHandler("PlatformAccount");
80 changes: 80 additions & 0 deletions apps/website/app/api/supabase/platform-account/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { NextResponse, NextRequest } from "next/server";

import { createClient } from "~/utils/supabase/server";
import { getOrCreateEntity, ItemValidator } from "~/utils/supabase/dbUtils";
import {
createApiResponse,
handleRouteError,
defaultOptionsHandler,
asPostgrestFailure,
} from "~/utils/supabase/apiUtils";
import { TablesInsert, Constants } from "@repo/database/types.gen.ts";

const { AgentType, Platform } = Constants.public.Enums;

type PlatformAccountDataInput = TablesInsert<"PlatformAccount">;

const accountValidator: ItemValidator<PlatformAccountDataInput> = (account: any) => {
if (!account || typeof account !== "object")
return "Invalid request body: expected a JSON object.";
const { name, platform, account_local_id, write_permission, active, agent_type, metadata, dg_account } = account;

if (!name || typeof name !== "string" || name.trim() === "")
return "Missing or invalid name";
// This is not dry, to be rewritten with Drizzle/Zed.
if (!Platform.includes(platform))
return "Missing or invalid platform";
if (agent_type !== undefined && !AgentType.includes(agent_type))
return "Invalid agent_type";
if (write_permission !== undefined && typeof write_permission != 'boolean')
return "write_permission must be boolean";
if (active !== undefined && typeof active != 'boolean')
return "active must be boolean";
if (metadata !== undefined) {
if (typeof metadata != 'string')
return "metadata should be a JSON string";
else try {
JSON.parse(metadata)
} catch (error) {
return "metadata should be a JSON string";
}
}
if (!account_local_id || typeof account_local_id != "string" || account_local_id.trim() === "")
return "Missing or invalid account_local_id";
if (dg_account != undefined) {
if (typeof dg_account != "string")
return "dg_account should be a UUID string";
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
if (!uuidRegex.test(dg_account))
return "dg_account must be a valid UUID";
}
const keys = [ 'name', 'platform', 'account_local_id', 'write_permission', 'active', 'agent_type', 'metadata', 'dg_account' ];
if (!Object.keys(account).every((key)=>keys.includes(key)))
return "Invalid account object: extra keys";
return null;
};

export const POST = async (request: NextRequest): Promise<NextResponse> => {
const supabasePromise = createClient();

try {
const body = await request.json();
const error = accountValidator(body);
if (error !== null)
return createApiResponse(request, asPostgrestFailure(error, "invalid"));

const supabase = await supabasePromise;
const result = await getOrCreateEntity<"PlatformAccount">({
supabase,
tableName: "PlatformAccount",
insertData: body as PlatformAccountDataInput,
uniqueOn: ["account_local_id", "platform"],
});

return createApiResponse(request, result);
} catch (e: unknown) {
return handleRouteError(request, e, "/api/supabase/platfor-account");
}
};

export const OPTIONS = defaultOptionsHandler;
Loading