|
| 1 | +import { NextResponse, NextRequest } from "next/server"; |
| 2 | + |
| 3 | +import { createClient } from "~/utils/supabase/server"; |
| 4 | +import { getOrCreateEntity, ItemValidator } from "~/utils/supabase/dbUtils"; |
| 5 | +import { |
| 6 | + createApiResponse, |
| 7 | + handleRouteError, |
| 8 | + defaultOptionsHandler, |
| 9 | + asPostgrestFailure, |
| 10 | +} from "~/utils/supabase/apiUtils"; |
| 11 | +import { TablesInsert, Constants } from "@repo/database/types.gen.ts"; |
| 12 | + |
| 13 | +const { AgentType, Platform } = Constants.public.Enums; |
| 14 | + |
| 15 | +type PlatformAccountDataInput = TablesInsert<"PlatformAccount">; |
| 16 | + |
| 17 | +const accountValidator: ItemValidator<PlatformAccountDataInput> = (account: any) => { |
| 18 | + if (!account || typeof account !== "object") |
| 19 | + return "Invalid request body: expected a JSON object."; |
| 20 | + const { name, platform, account_local_id, write_permission, active, agent_type, metadata, dg_account } = account; |
| 21 | + |
| 22 | + if (!name || typeof name !== "string" || name.trim() === "") |
| 23 | + return "Missing or invalid name"; |
| 24 | + // This is not dry, to be rewritten with Drizzle/Zed. |
| 25 | + if (!Platform.includes(platform)) |
| 26 | + return "Missing or invalid platform"; |
| 27 | + if (agent_type !== undefined && !AgentType.includes(agent_type)) |
| 28 | + return "Invalid agent_type"; |
| 29 | + if (write_permission !== undefined && typeof write_permission != 'boolean') |
| 30 | + return "write_permission must be boolean"; |
| 31 | + if (active !== undefined && typeof active != 'boolean') |
| 32 | + return "active must be boolean"; |
| 33 | + if (metadata !== undefined) { |
| 34 | + if (typeof metadata != 'string') |
| 35 | + return "metadata should be a JSON string"; |
| 36 | + else try { |
| 37 | + JSON.parse(metadata) |
| 38 | + } catch (error) { |
| 39 | + return "metadata should be a JSON string"; |
| 40 | + } |
| 41 | + } |
| 42 | + if (!account_local_id || typeof account_local_id != "string" || account_local_id.trim() === "") |
| 43 | + return "Missing or invalid account_local_id"; |
| 44 | + if (dg_account != undefined) { |
| 45 | + if (typeof dg_account != "string") |
| 46 | + return "dg_account should be a UUID string"; |
| 47 | + const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; |
| 48 | + if (!uuidRegex.test(dg_account)) |
| 49 | + return "dg_account must be a valid UUID"; |
| 50 | + } |
| 51 | + const keys = [ 'name', 'platform', 'account_local_id', 'write_permission', 'active', 'agent_type', 'metadata', 'dg_account' ]; |
| 52 | + if (!Object.keys(account).every((key)=>keys.includes(key))) |
| 53 | + return "Invalid account object: extra keys"; |
| 54 | + return null; |
| 55 | +}; |
| 56 | + |
| 57 | +export const POST = async (request: NextRequest): Promise<NextResponse> => { |
| 58 | + const supabasePromise = createClient(); |
| 59 | + |
| 60 | + try { |
| 61 | + const body = await request.json(); |
| 62 | + const error = accountValidator(body); |
| 63 | + if (error !== null) |
| 64 | + return createApiResponse(request, asPostgrestFailure(error, "invalid")); |
| 65 | + |
| 66 | + const supabase = await supabasePromise; |
| 67 | + const result = await getOrCreateEntity<"PlatformAccount">({ |
| 68 | + supabase, |
| 69 | + tableName: "PlatformAccount", |
| 70 | + insertData: body as PlatformAccountDataInput, |
| 71 | + uniqueOn: ["account_local_id", "platform"], |
| 72 | + }); |
| 73 | + |
| 74 | + return createApiResponse(request, result); |
| 75 | + } catch (e: unknown) { |
| 76 | + return handleRouteError(request, e, "/api/supabase/platfor-account"); |
| 77 | + } |
| 78 | +}; |
| 79 | + |
| 80 | +export const OPTIONS = defaultOptionsHandler; |
0 commit comments