feat: openapi enhancements

This commit is contained in:
Henry
2024-11-03 21:05:58 +00:00
parent 82b682b400
commit d1e27b5b83
25 changed files with 231 additions and 116 deletions

BIN
bun.lockb

Binary file not shown.

View File

@@ -31,7 +31,7 @@
"@trpc/server": "^11.0.0-rc.566", "@trpc/server": "^11.0.0-rc.566",
"@vercel/postgres": "^0.7.2", "@vercel/postgres": "^0.7.2",
"drizzle-orm": "^0.28.5", "drizzle-orm": "^0.28.5",
"next": "^14.1.3", "next": "^15.0.2",
"nextjs-cors": "^2.2.0", "nextjs-cors": "^2.2.0",
"postgres": "^3.4.4", "postgres": "^3.4.4",
"react": "18.2.0", "react": "18.2.0",

View File

@@ -164,23 +164,25 @@ export const BoardProvider: React.FC<{ children: ReactNode }> = ({
}; };
const updateList = ({ const updateList = ({
boardId, listPublicId,
listId,
currentIndex, currentIndex,
newIndex, newIndex,
}: ReorderListInput) => { }: ReorderListInput) => {
updateListMutation.mutate({ updateListMutation.mutate({
boardId, listPublicId,
listId,
currentIndex, currentIndex,
newIndex, newIndex,
}); });
}; };
const updateCard = ({ cardId, newListId, newIndex }: ReorderCardInput) => { const updateCard = ({
cardPublicId,
newListPublicId,
newIndex,
}: ReorderCardInput) => {
updateCardMutation.mutate({ updateCardMutation.mutate({
cardId, cardPublicId,
newListId, newListPublicId,
newIndex, newIndex,
}); });
}; };

View File

@@ -16,8 +16,12 @@ export const authRouter = createTRPCRouter({
.meta({ .meta({
openapi: { openapi: {
method: "GET", method: "GET",
path: "/auth/user", path: "/users/me",
summary: "Get user", summary: "Get user",
description:
"Retrieves the currently authenticated user's profile information",
tags: ["Users"],
protect: true,
}, },
}) })
.input(z.void()) .input(z.void())
@@ -52,8 +56,10 @@ export const authRouter = createTRPCRouter({
.meta({ .meta({
openapi: { openapi: {
method: "POST", method: "POST",
path: "/auth/email", path: "/auth/login/email",
summary: "Login with email", summary: "Login with email",
description: "Sends a login URL to the provided email address",
tags: ["Auth"],
}, },
}) })
.input(z.object({ email: z.string() })) .input(z.object({ email: z.string() }))
@@ -78,8 +84,11 @@ export const authRouter = createTRPCRouter({
.meta({ .meta({
openapi: { openapi: {
method: "POST", method: "POST",
path: "/auth/oauth", path: "/auth/login/oauth",
summary: "Login with OAuth", summary: "Login with OAuth",
description:
"Initiates the login process for a user with the given OAuth provider",
tags: ["Auth"],
}, },
}) })
.input(z.object({ provider: z.string() })) .input(z.object({ provider: z.string() }))

View File

@@ -13,8 +13,11 @@ export const boardRouter = createTRPCRouter({
.meta({ .meta({
openapi: { openapi: {
method: "GET", method: "GET",
path: "/board/{workspacePublicId}", path: "/workspaces/{workspacePublicId}/boards",
summary: "Get all boards", summary: "Get all boards",
description: "Retrieves all boards for a given workspace",
tags: ["Boards"],
protect: true,
}, },
}) })
.input(z.object({ workspacePublicId: z.string().min(12) })) .input(z.object({ workspacePublicId: z.string().min(12) }))
@@ -41,15 +44,18 @@ export const boardRouter = createTRPCRouter({
.meta({ .meta({
openapi: { openapi: {
method: "GET", method: "GET",
path: "/board/{boardPublicId}", path: "/boards/{boardPublicId}",
summary: "Get board by public ID", summary: "Get board by public ID",
description: "Retrieves a board by its public ID",
tags: ["Boards"],
protect: true,
}, },
}) })
.input( .input(
z.object({ z.object({
boardPublicId: z.string().min(12), boardPublicId: z.string().min(12),
members: z.array(z.string().min(12)), members: z.array(z.string().min(12)).optional(),
labels: z.array(z.string().min(12)), labels: z.array(z.string().min(12)).optional(),
}), }),
) )
.output(z.custom<Awaited<ReturnType<typeof boardRepo.getByPublicId>>>()) .output(z.custom<Awaited<ReturnType<typeof boardRepo.getByPublicId>>>())
@@ -58,8 +64,8 @@ export const boardRouter = createTRPCRouter({
ctx.db, ctx.db,
input.boardPublicId, input.boardPublicId,
{ {
members: input.members, members: input.members ?? [],
labels: input.labels, labels: input.labels ?? [],
}, },
); );
@@ -69,8 +75,11 @@ export const boardRouter = createTRPCRouter({
.meta({ .meta({
openapi: { openapi: {
method: "POST", method: "POST",
path: "/board", path: "/workspaces/{workspacePublicId}/boards",
summary: "Create board", summary: "Create board",
description: "Creates a new board for a given workspace",
tags: ["Boards"],
protect: true,
}, },
}) })
.input( .input(
@@ -118,8 +127,11 @@ export const boardRouter = createTRPCRouter({
.meta({ .meta({
openapi: { openapi: {
method: "PUT", method: "PUT",
path: "/board/{boardPublicId}", path: "/boards/{boardPublicId}",
summary: "Update board", summary: "Update board",
description: "Updates a board by its public ID",
tags: ["Boards"],
protect: true,
}, },
}) })
.input( .input(
@@ -147,8 +159,11 @@ export const boardRouter = createTRPCRouter({
.meta({ .meta({
openapi: { openapi: {
method: "DELETE", method: "DELETE",
path: "/board/{boardPublicId}", path: "/boards/{boardPublicId}",
summary: "Delete board", summary: "Delete board",
description: "Deletes a board by its public ID",
tags: ["Boards"],
protect: true,
}, },
}) })
.input( .input(

View File

@@ -14,7 +14,10 @@ export const cardRouter = createTRPCRouter({
openapi: { openapi: {
summary: "Create a card", summary: "Create a card",
method: "POST", method: "POST",
path: "/", path: "/cards",
description: "Creates a new card for a given list",
tags: ["Cards"],
protect: true,
}, },
}) })
.input( .input(
@@ -128,8 +131,11 @@ export const cardRouter = createTRPCRouter({
.meta({ .meta({
openapi: { openapi: {
summary: "Add or remove a label from a card", summary: "Add or remove a label from a card",
method: "POST", method: "PUT",
path: "/{cardPublicId}/label/{labelPublicId}", path: "/cards/{cardPublicId}/labels/{labelPublicId}",
description: "Adds or removes a label from a card",
tags: ["Cards"],
protect: true,
}, },
}) })
.input( .input(
@@ -184,8 +190,10 @@ export const cardRouter = createTRPCRouter({
.meta({ .meta({
openapi: { openapi: {
summary: "Add or remove a member from a card", summary: "Add or remove a member from a card",
method: "POST", method: "PUT",
path: "/{cardPublicId}/member/{workspaceMemberPublicId}", path: "/cards/{cardPublicId}/members/{workspaceMemberPublicId}",
description: "Adds or removes a member from a card",
tags: ["Cards"],
}, },
}) })
.input( .input(
@@ -242,12 +250,15 @@ export const cardRouter = createTRPCRouter({
byId: protectedProcedure byId: protectedProcedure
.meta({ .meta({
openapi: { openapi: {
summary: "Get a card by ID", summary: "Get a card by public ID",
method: "GET", method: "GET",
path: "/{id}", path: "/cards/{cardPublicId}",
description: "Retrieves a card by its public ID",
tags: ["Cards"],
protect: true,
}, },
}) })
.input(z.object({ id: z.string().min(12) })) .input(z.object({ cardPublicId: z.string().min(12) }))
.output( .output(
z.custom< z.custom<
Awaited<ReturnType<typeof cardRepo.getWithListAndMembersByPublicId>> Awaited<ReturnType<typeof cardRepo.getWithListAndMembersByPublicId>>
@@ -256,12 +267,12 @@ export const cardRouter = createTRPCRouter({
.query(async ({ ctx, input }) => { .query(async ({ ctx, input }) => {
const result = await cardRepo.getWithListAndMembersByPublicId( const result = await cardRepo.getWithListAndMembersByPublicId(
ctx.db, ctx.db,
input.id, input.cardPublicId,
); );
if (!result) if (!result)
throw new TRPCError({ throw new TRPCError({
message: `Card with ID ${input.id} not found`, message: `Card with public ID ${input.cardPublicId} not found`,
code: "NOT_FOUND", code: "NOT_FOUND",
}); });
@@ -272,12 +283,15 @@ export const cardRouter = createTRPCRouter({
openapi: { openapi: {
summary: "Update a card", summary: "Update a card",
method: "PUT", method: "PUT",
path: "/{cardId}", path: "/cards/{cardPublicId}",
description: "Updates a card by its public ID",
tags: ["Cards"],
protect: true,
}, },
}) })
.input( .input(
z.object({ z.object({
cardId: z.string().min(12), cardPublicId: z.string().min(12),
title: z.string().min(1), title: z.string().min(1),
description: z.string(), description: z.string(),
}), }),
@@ -295,7 +309,7 @@ export const cardRouter = createTRPCRouter({
const result = await cardRepo.update( const result = await cardRepo.update(
ctx.db, ctx.db,
{ title: input.title, description: input.description }, { title: input.title, description: input.description },
{ cardPublicId: input.cardId }, { cardPublicId: input.cardPublicId },
); );
if (!result) if (!result)
@@ -311,7 +325,10 @@ export const cardRouter = createTRPCRouter({
openapi: { openapi: {
summary: "Delete a card", summary: "Delete a card",
method: "DELETE", method: "DELETE",
path: "/{cardPublicId}", path: "/cards/{cardPublicId}",
description: "Deletes a card by its public ID",
tags: ["Cards"],
protect: true,
}, },
}) })
.input( .input(
@@ -359,14 +376,17 @@ export const cardRouter = createTRPCRouter({
.meta({ .meta({
openapi: { openapi: {
summary: "Reorder a card", summary: "Reorder a card",
method: "POST", method: "PUT",
path: "/{cardId}/reorder", path: "/cards/{cardPublicId}/reorder",
description: "Reorders the position of a card in a given list",
tags: ["Cards"],
protect: true,
}, },
}) })
.input( .input(
z.object({ z.object({
cardId: z.string().min(12), cardPublicId: z.string().min(12),
newListId: z.string().min(12), newListPublicId: z.string().min(12),
newIndex: z.number().optional(), newIndex: z.number().optional(),
}), }),
) )
@@ -382,12 +402,12 @@ export const cardRouter = createTRPCRouter({
const card = await cardRepo.getCardWithListByPublicId( const card = await cardRepo.getCardWithListByPublicId(
ctx.db, ctx.db,
input.cardId, input.cardPublicId,
); );
if (!card?.list) if (!card?.list)
throw new TRPCError({ throw new TRPCError({
message: `Card with public ID ${input.cardId} not found`, message: `Card with public ID ${input.cardPublicId} not found`,
code: "NOT_FOUND", code: "NOT_FOUND",
}); });
@@ -398,12 +418,12 @@ export const cardRouter = createTRPCRouter({
const newList = await listRepo.getWithCardsByPublicId( const newList = await listRepo.getWithCardsByPublicId(
ctx.db, ctx.db,
input.newListId, input.newListPublicId,
); );
if (!newList) if (!newList)
throw new TRPCError({ throw new TRPCError({
message: `List with public ID ${input.newListId} not found`, message: `List with public ID ${input.newListPublicId} not found`,
code: "NOT_FOUND", code: "NOT_FOUND",
}); });

View File

@@ -41,7 +41,10 @@ export const importRouter = createTRPCRouter({
openapi: { openapi: {
summary: "Get boards from Trello", summary: "Get boards from Trello",
method: "GET", method: "GET",
path: "/boards", path: "/imports/trello/boards",
description: "Retrieves all boards from Trello",
tags: ["Imports"],
protect: true,
}, },
}) })
.input( .input(
@@ -91,7 +94,10 @@ export const importRouter = createTRPCRouter({
openapi: { openapi: {
summary: "Import boards from Trello", summary: "Import boards from Trello",
method: "POST", method: "POST",
path: "/import", path: "/imports/trello/import",
description: "Imports boards from Trello",
tags: ["Imports"],
protect: true,
}, },
}) })
.input( .input(

View File

@@ -12,17 +12,20 @@ export const labelRouter = createTRPCRouter({
openapi: { openapi: {
summary: "Get a label by public ID", summary: "Get a label by public ID",
method: "GET", method: "GET",
path: "/{publicId}", path: "/labels/{labelPublicId}",
description: "Retrieves a label by its public ID",
tags: ["Labels"],
protect: true,
}, },
}) })
.input(z.object({ publicId: z.string().min(12) })) .input(z.object({ labelPublicId: z.string().min(12) }))
.output(z.custom<Awaited<ReturnType<typeof labelRepo.getByPublicId>>>()) .output(z.custom<Awaited<ReturnType<typeof labelRepo.getByPublicId>>>())
.query(async ({ ctx, input }) => { .query(async ({ ctx, input }) => {
const label = await labelRepo.getByPublicId(ctx.db, input.publicId); const label = await labelRepo.getByPublicId(ctx.db, input.labelPublicId);
if (!label) if (!label)
throw new TRPCError({ throw new TRPCError({
message: `Label with public ID ${input.publicId} not found`, message: `Label with public ID ${input.labelPublicId} not found`,
code: "NOT_FOUND", code: "NOT_FOUND",
}); });
@@ -33,7 +36,10 @@ export const labelRouter = createTRPCRouter({
openapi: { openapi: {
summary: "Create a label", summary: "Create a label",
method: "POST", method: "POST",
path: "/create", path: "/labels",
description: "Creates a new label",
tags: ["Labels"],
protect: true,
}, },
}) })
.input( .input(
@@ -84,12 +90,15 @@ export const labelRouter = createTRPCRouter({
openapi: { openapi: {
summary: "Update a label", summary: "Update a label",
method: "PUT", method: "PUT",
path: "/{publicId}", path: "/labels/{labelPublicId}",
description: "Updates a label by its public ID",
tags: ["Labels"],
protect: true,
}, },
}) })
.input( .input(
z.object({ z.object({
publicId: z.string().min(12), labelPublicId: z.string().min(12),
name: z.string().min(1).max(36), name: z.string().min(1).max(36),
colourCode: z.string().length(7), colourCode: z.string().length(7),
}), }),
@@ -105,17 +114,20 @@ export const labelRouter = createTRPCRouter({
openapi: { openapi: {
summary: "Delete a label", summary: "Delete a label",
method: "DELETE", method: "DELETE",
path: "/{publicId}", path: "/labels/{labelPublicId}",
description: "Deletes a label by its public ID",
tags: ["Labels"],
protect: true,
}, },
}) })
.input(z.object({ publicId: z.string().min(12) })) .input(z.object({ labelPublicId: z.string().min(12) }))
.output(z.object({ success: z.boolean() })) .output(z.object({ success: z.boolean() }))
.mutation(async ({ ctx, input }) => { .mutation(async ({ ctx, input }) => {
const label = await labelRepo.getByPublicId(ctx.db, input.publicId); const label = await labelRepo.getByPublicId(ctx.db, input.labelPublicId);
if (!label) if (!label)
throw new TRPCError({ throw new TRPCError({
message: `Label with public ID ${input.publicId} not found`, message: `Label with public ID ${input.labelPublicId} not found`,
code: "NOT_FOUND", code: "NOT_FOUND",
}); });

View File

@@ -13,7 +13,10 @@ export const listRouter = createTRPCRouter({
openapi: { openapi: {
summary: "Create a list", summary: "Create a list",
method: "POST", method: "POST",
path: "/list/create", path: "/lists",
description: "Creates a new list for a given board",
tags: ["Lists"],
protect: true,
}, },
}) })
.input( .input(
@@ -65,24 +68,26 @@ export const listRouter = createTRPCRouter({
openapi: { openapi: {
summary: "Reorder a list", summary: "Reorder a list",
method: "POST", method: "POST",
path: "/{listId}/reorder", path: "/lists/{listPublicId}/reorder",
description: "Reorders the position of a list",
tags: ["Lists"],
protect: true,
}, },
}) })
.input( .input(
z.object({ z.object({
boardId: z.string().min(12), listPublicId: z.string().min(12),
listId: z.string().min(12),
currentIndex: z.number(), currentIndex: z.number(),
newIndex: z.number(), newIndex: z.number(),
}), }),
) )
.output(z.custom<Awaited<ReturnType<typeof listRepo.reorder>>>()) .output(z.custom<Awaited<ReturnType<typeof listRepo.reorder>>>())
.mutation(async ({ ctx, input }) => { .mutation(async ({ ctx, input }) => {
const list = await listRepo.getByPublicId(ctx.db, input.listId); const list = await listRepo.getByPublicId(ctx.db, input.listPublicId);
if (!list) if (!list)
throw new TRPCError({ throw new TRPCError({
message: `List with public ID ${input.listId} not found`, message: `List with public ID ${input.listPublicId} not found`,
code: "NOT_FOUND", code: "NOT_FOUND",
}); });
@@ -106,7 +111,10 @@ export const listRouter = createTRPCRouter({
openapi: { openapi: {
summary: "Delete a list", summary: "Delete a list",
method: "DELETE", method: "DELETE",
path: "/{listPublicId}", path: "/lists/{listPublicId}",
description: "Deletes a list by its public ID",
tags: ["Lists"],
protect: true,
}, },
}) })
.input( .input(
@@ -158,7 +166,10 @@ export const listRouter = createTRPCRouter({
openapi: { openapi: {
summary: "Update a list", summary: "Update a list",
method: "PUT", method: "PUT",
path: "/list/{listPublicId}", path: "/lists/{listPublicId}",
description: "Updates a list by its public ID",
tags: ["Lists"],
protect: true,
}, },
}) })
.input( .input(

View File

@@ -15,7 +15,10 @@ export const memberRouter = createTRPCRouter({
openapi: { openapi: {
summary: "Invite a member to a workspace", summary: "Invite a member to a workspace",
method: "POST", method: "POST",
path: "/invite", path: "/workspaces/{workspacePublicId}/members/invite",
description: "Invites a member to a workspace",
tags: ["Members"],
protect: true,
}, },
}) })
.input( .input(
@@ -144,11 +147,15 @@ export const memberRouter = createTRPCRouter({
openapi: { openapi: {
summary: "Delete a member from a workspace", summary: "Delete a member from a workspace",
method: "DELETE", method: "DELETE",
path: "/{memberPublicId}", path: "/workspaces/{workspacePublicId}/members/{memberPublicId}",
description: "Deletes a member from a workspace",
tags: ["Members"],
protect: true,
}, },
}) })
.input( .input(
z.object({ z.object({
workspacePublicId: z.string().min(12),
memberPublicId: z.string().min(12), memberPublicId: z.string().min(12),
}), }),
) )
@@ -162,6 +169,17 @@ export const memberRouter = createTRPCRouter({
code: "UNAUTHORIZED", code: "UNAUTHORIZED",
}); });
const workspace = await workspaceRepo.getByPublicId(
ctx.db,
input.workspacePublicId,
);
if (!workspace)
throw new TRPCError({
message: `Workspace with public ID ${input.workspacePublicId} not found`,
code: "NOT_FOUND",
});
const member = await memberRepo.getByPublicId( const member = await memberRepo.getByPublicId(
ctx.db, ctx.db,
input.memberPublicId, input.memberPublicId,

View File

@@ -10,7 +10,10 @@ export const workspaceRouter = createTRPCRouter({
openapi: { openapi: {
summary: "Get all workspaces", summary: "Get all workspaces",
method: "GET", method: "GET",
path: "/", path: "/workspaces",
description: "Retrieves all workspaces for the authenticated user",
tags: ["Workspaces"],
protect: true,
}, },
}) })
.input(z.void()) .input(z.void())
@@ -35,10 +38,13 @@ export const workspaceRouter = createTRPCRouter({
openapi: { openapi: {
summary: "Get a workspace by public ID", summary: "Get a workspace by public ID",
method: "GET", method: "GET",
path: "/workspace/{publicId}", path: "/workspaces/{workspacePublicId}",
description: "Retrieves a workspace by its public ID",
tags: ["Workspaces"],
protect: true,
}, },
}) })
.input(z.object({ publicId: z.string().min(12) })) .input(z.object({ workspacePublicId: z.string().min(12) }))
.output( .output(
z.custom< z.custom<
Awaited<ReturnType<typeof workspaceRepo.getByPublicIdWithMembers>> Awaited<ReturnType<typeof workspaceRepo.getByPublicIdWithMembers>>
@@ -47,7 +53,7 @@ export const workspaceRouter = createTRPCRouter({
.query(async ({ ctx, input }) => { .query(async ({ ctx, input }) => {
const result = await workspaceRepo.getByPublicIdWithMembers( const result = await workspaceRepo.getByPublicIdWithMembers(
ctx.db, ctx.db,
input.publicId, input.workspacePublicId,
); );
if (!result) if (!result)
@@ -63,7 +69,10 @@ export const workspaceRouter = createTRPCRouter({
openapi: { openapi: {
summary: "Create a workspace", summary: "Create a workspace",
method: "POST", method: "POST",
path: "/workspace/create", path: "/workspaces",
description: "Creates a new workspace",
tags: ["Workspaces"],
protect: true,
}, },
}) })
.input( .input(
@@ -100,7 +109,10 @@ export const workspaceRouter = createTRPCRouter({
openapi: { openapi: {
summary: "Update a workspace", summary: "Update a workspace",
method: "PUT", method: "PUT",
path: "/workspace/{workspacePublicId}", path: "/workspaces/{workspacePublicId}",
description: "Updates a workspace by its public ID",
tags: ["Workspaces"],
protect: true,
}, },
}) })
.input( .input(
@@ -124,7 +136,10 @@ export const workspaceRouter = createTRPCRouter({
openapi: { openapi: {
summary: "Delete a workspace", summary: "Delete a workspace",
method: "DELETE", method: "DELETE",
path: "/workspace/{workspacePublicId}", path: "/workspaces/{workspacePublicId}",
description: "Deletes a workspace by its public ID",
tags: ["Workspaces"],
protect: true,
}, },
}) })
.input(z.object({ workspacePublicId: z.string().min(12) })) .input(z.object({ workspacePublicId: z.string().min(12) }))

View File

@@ -79,16 +79,22 @@ export const createTRPCContext = async ({
return createInnerTRPCContext({ db, adminDb, user }); return createInnerTRPCContext({ db, adminDb, user });
}; };
export const createRESTContext = async ({ export const createRESTContext = async ({ req }: CreateNextContextOptions) => {
req, const db = createNextApiClient(req);
res,
}: CreateNextContextOptions) => {
const db = createNextApiClient(req, res);
const adminDb = createTRPCAdminClient(); const adminDb = createTRPCAdminClient();
const authHeader = req.headers.authorization;
const accessToken = authHeader?.startsWith("Bearer ")
? authHeader.substring(7)
: null;
if (!accessToken) {
return createInnerTRPCContext({ db, adminDb, user: null });
}
const { const {
data: { user }, data: { user },
} = await db.auth.getUser(); } = await db.auth.getUser(accessToken);
return createInnerTRPCContext({ db, adminDb, user }); return createInnerTRPCContext({ db, adminDb, user });
}; };

View File

@@ -84,14 +84,12 @@ export const getByPublicId = async (
query = query.in("lists.cards.members.publicId", filters.members); query = query.in("lists.cards.members.publicId", filters.members);
} }
const { data, error } = await query const { data } = await query
.order("index", { foreignTable: "list", ascending: true }) .order("index", { foreignTable: "list", ascending: true })
.order("index", { foreignTable: "list.card", ascending: true }) .order("index", { foreignTable: "list.card", ascending: true })
.limit(1) .limit(1)
.single(); .single();
console.log(error);
return data; return data;
}; };

View File

@@ -63,7 +63,7 @@ export const getByPublicId = async (
export const update = async ( export const update = async (
db: SupabaseClient<Database>, db: SupabaseClient<Database>,
labelInput: { labelInput: {
publicId: string; labelPublicId: string;
name: string; name: string;
colourCode: string; colourCode: string;
}, },
@@ -74,7 +74,7 @@ export const update = async (
name: labelInput.name, name: labelInput.name,
colourCode: labelInput.colourCode, colourCode: labelInput.colourCode,
}) })
.eq("publicId", labelInput.publicId); .eq("publicId", labelInput.labelPublicId);
return data; return data;
}; };

View File

@@ -6,7 +6,7 @@ import {
import { RequestCookies } from "@edge-runtime/cookies"; import { RequestCookies } from "@edge-runtime/cookies";
import { type Database } from "~/types/database.types"; import { type Database } from "~/types/database.types";
import { type NextApiRequest, type NextApiResponse } from "next"; import { type NextApiRequest } from "next";
import { type NextRequest, type NextResponse } from "next/server"; import { type NextRequest, type NextResponse } from "next/server";
export function createNextClient(req: NextRequest, res: NextResponse) { export function createNextClient(req: NextRequest, res: NextResponse) {
@@ -31,26 +31,25 @@ export function createNextClient(req: NextRequest, res: NextResponse) {
return supabase; return supabase;
} }
export function createNextApiClient( export function createNextApiClient(req: NextApiRequest) {
_req: NextApiRequest, const authHeader = req.headers.authorization;
_res: NextApiResponse, const accessToken = authHeader?.startsWith("Bearer ")
) { ? authHeader.substring(7)
: null;
const supabase = createServerClient<Database>( const supabase = createServerClient<Database>(
process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.SUPABASE_SERVICE_API_KEY!, process.env.SUPABASE_SERVICE_API_KEY!,
{ {
cookies: { auth: {
get(_name: string) { persistSession: false,
// return req.cookies.get(name)?.value; ...(accessToken && {
return ""; autoRefreshToken: false,
}, detectSessionInUrl: false,
set(_name: string, _value: string, _options: CookieOptions) { access_token: accessToken,
// res.headers.append("Set-Cookie", serialize(name, value, options)); }),
},
remove(_name: string, _options: CookieOptions) {
// res.headers.append("Set-Cookie", serialize(name, "", options));
},
}, },
cookies: {},
}, },
); );

View File

@@ -104,8 +104,7 @@ export default function BoardPage() {
} }
updateList({ updateList({
boardId, listPublicId: draggableId,
listId: draggableId,
currentIndex: source.index, currentIndex: source.index,
newIndex: destination.index, newIndex: destination.index,
}); });
@@ -128,8 +127,8 @@ export default function BoardPage() {
} }
updateCard({ updateCard({
cardId: draggableId, cardPublicId: draggableId,
newListId: destination.droppableId, newListPublicId: destination.droppableId,
newIndex: destination.index, newIndex: destination.index,
}); });
} }

View File

@@ -15,7 +15,7 @@ export function DeleteLabelConfirmation({
const { closeModal } = useModal(); const { closeModal } = useModal();
const { showPopup } = usePopup(); const { showPopup } = usePopup();
const refetchCard = () => utils.card.byId.refetch({ id: cardPublicId }); const refetchCard = () => utils.card.byId.refetch({ cardPublicId });
const deleteLabelMutation = api.label.delete.useMutation({ const deleteLabelMutation = api.label.delete.useMutation({
onSuccess: () => refetchCard(), onSuccess: () => refetchCard(),
@@ -29,7 +29,7 @@ export function DeleteLabelConfirmation({
const handleDeleteLabel = () => { const handleDeleteLabel = () => {
closeModal(); closeModal();
deleteLabelMutation.mutate({ deleteLabelMutation.mutate({
publicId: labelPublicId, labelPublicId,
}); });
}; };

View File

@@ -44,7 +44,7 @@ export function LabelForm({
const label = api.label.byPublicId.useQuery( const label = api.label.byPublicId.useQuery(
{ {
publicId: entityId, labelPublicId: entityId,
}, },
{ {
enabled: isEdit && !!entityId, enabled: isEdit && !!entityId,
@@ -62,7 +62,7 @@ export function LabelForm({
}, },
}); });
const refetchCard = () => utils.card.byId.refetch({ id: cardPublicId }); const refetchCard = () => utils.card.byId.refetch({ cardPublicId });
const isCreateAnotherEnabled = watch("isCreateAnotherEnabled"); const isCreateAnotherEnabled = watch("isCreateAnotherEnabled");
@@ -101,7 +101,7 @@ export function LabelForm({
if (isEdit) { if (isEdit) {
updateLabel.mutate({ updateLabel.mutate({
publicId: label.data?.publicId ?? "", labelPublicId: label.data?.publicId ?? "",
name: values.name, name: values.name,
colourCode: values.colour.code, colourCode: values.colour.code,
}); });

View File

@@ -27,7 +27,7 @@ export default function LabelSelector({
const { openModal } = useModal(); const { openModal } = useModal();
const utils = api.useUtils(); const utils = api.useUtils();
const refetchCard = () => utils.card.byId.refetch({ id: cardPublicId }); const refetchCard = () => utils.card.byId.refetch({ cardPublicId });
const addOrRemoveLabel = api.card.addOrRemoveLabel.useMutation({ const addOrRemoveLabel = api.card.addOrRemoveLabel.useMutation({
onSuccess: async () => { onSuccess: async () => {

View File

@@ -20,7 +20,7 @@ export default function ListSelector({
}: ListSelectorProps) { }: ListSelectorProps) {
const utils = api.useUtils(); const utils = api.useUtils();
const refetchCard = () => utils.card.byId.refetch({ id: cardPublicId }); const refetchCard = () => utils.card.byId.refetch({ cardPublicId });
const updateCardList = api.card.reorder.useMutation({ const updateCardList = api.card.reorder.useMutation({
onSuccess: async () => { onSuccess: async () => {
@@ -78,8 +78,8 @@ export default function ListSelector({
setValue(list.publicId, newValue); setValue(list.publicId, newValue);
updateCardList.mutate({ updateCardList.mutate({
cardId: cardPublicId, cardPublicId,
newListId: list.publicId, newListPublicId: list.publicId,
}); });
handleSubmit(onSubmit); handleSubmit(onSubmit);

View File

@@ -24,7 +24,7 @@ export default function MemberSelector({
}: MemberSelectorProps) { }: MemberSelectorProps) {
const utils = api.useUtils(); const utils = api.useUtils();
const refetchCard = () => utils.card.byId.refetch({ id: cardPublicId }); const refetchCard = () => utils.card.byId.refetch({ cardPublicId });
const addOrRemoveMember = api.card.addOrRemoveMember.useMutation({ const addOrRemoveMember = api.card.addOrRemoveMember.useMutation({
onSuccess: async () => { onSuccess: async () => {

View File

@@ -32,7 +32,9 @@ export default function CardPage() {
? params.cardId[0] ? params.cardId[0]
: params?.cardId; : params?.cardId;
const { data, isLoading } = api.card.byId.useQuery({ id: cardId ?? "" }); const { data, isLoading } = api.card.byId.useQuery({
cardPublicId: cardId ?? "",
});
const board = data?.list?.board; const board = data?.list?.board;
const boardId = board?.publicId; const boardId = board?.publicId;
@@ -85,7 +87,7 @@ export default function CardPage() {
const onSubmit = (values: FormValues) => { const onSubmit = (values: FormValues) => {
updateCard.mutate({ updateCard.mutate({
cardId: values.cardId, cardPublicId: values.cardId,
title: values.title, title: values.title,
description: values.description, description: values.description,
}); });

View File

@@ -1,12 +1,14 @@
import { api } from "~/utils/api"; import { api } from "~/utils/api";
import { useModal } from "~/providers/modal"; import { useModal } from "~/providers/modal";
import { usePopup } from "~/providers/popup"; import { usePopup } from "~/providers/popup";
import { useWorkspace } from "~/providers/workspace";
import Button from "~/components/Button"; import Button from "~/components/Button";
export function DeleteMemberConfirmation() { export function DeleteMemberConfirmation() {
const utils = api.useUtils(); const utils = api.useUtils();
const { closeModal, entityLabel, entityId } = useModal(); const { closeModal, entityLabel, entityId } = useModal();
const { workspace } = useWorkspace();
const { showPopup } = usePopup(); const { showPopup } = usePopup();
const deleteMember = api.member.delete.useMutation({ const deleteMember = api.member.delete.useMutation({
@@ -31,6 +33,7 @@ export function DeleteMemberConfirmation() {
if (entityId) if (entityId)
deleteMember.mutate({ deleteMember.mutate({
memberPublicId: entityId, memberPublicId: entityId,
workspacePublicId: workspace.publicId,
}); });
}; };

View File

@@ -18,7 +18,7 @@ export default function MembersPage() {
const { workspace } = useWorkspace(); const { workspace } = useWorkspace();
const { data, isLoading } = api.workspace.byId.useQuery( const { data, isLoading } = api.workspace.byId.useQuery(
{ publicId: workspace.publicId }, { workspacePublicId: workspace.publicId },
// { enabled: workspace?.publicId ? true : false }, // { enabled: workspace?.publicId ? true : false },
); );