feat: monorepo

This commit is contained in:
Henry
2024-12-12 14:34:10 +00:00
parent b8eed7a90c
commit 0c8d17dce5
370 changed files with 10280 additions and 39805 deletions

View File

@@ -0,0 +1,9 @@
import { sql } from "@vercel/postgres";
import { drizzle } from "drizzle-orm/vercel-postgres";
import * as schema from "./schema";
export const db = drizzle({
client: sql,
schema,
});

View File

@@ -0,0 +1,15 @@
import "dotenv/config";
import { drizzle } from "drizzle-orm/postgres-js";
import { migrate } from "drizzle-orm/postgres-js/migrator";
import postgres from "postgres";
const postgresUrl = process.env.POSTGRES_URL;
if (!postgresUrl) {
throw new Error("POSTGRES_URL environment variable is not set");
}
const migrationClient = postgres(postgresUrl, { max: 1 });
migrate(drizzle(migrationClient), {
migrationsFolder: "./src/server/db/migrations",
}).catch((e) => console.log(e));

View File

@@ -0,0 +1,191 @@
import type { SupabaseClient } from "@supabase/supabase-js";
import type { Database } from "@kan/db/types/database.types";
import { generateUID } from "@kan/utils";
export const getAllByWorkspaceId = async (
db: SupabaseClient<Database>,
workspaceId: number,
) => {
const { data } = await db
.from("board")
.select(`publicId, name`)
.is("deletedAt", null)
.eq("workspaceId", workspaceId);
return data ?? [];
};
export const getByPublicId = async (
db: SupabaseClient<Database>,
boardPublicId: string,
filters: {
members: string[];
labels: string[];
},
) => {
let query = db
.from("board")
.select(
`
publicId,
name,
workspace (
publicId,
members:workspace_members (
publicId,
user!workspace_members_userId_user_id_fk (
name
)
)
),
labels:label (
publicId,
name,
colourCode
),
lists:list (
publicId,
name,
boardId,
index,
cards:card (
publicId,
title,
description,
listId,
index,
labels:label${filters.labels.length > 0 ? "!inner" : ""} (
publicId,
name,
colourCode
),
members:workspace_members${filters.members.length > 0 ? "!inner" : ""} (
publicId,
user!workspace_members_userId_user_id_fk (
name
)
)
)
)
`,
)
.eq("publicId", boardPublicId)
.is("deletedAt", null)
.is("lists.deletedAt", null)
.is("lists.cards.deletedAt", null)
.is("workspace.members.deletedAt", null)
.is("lists.cards.members.deletedAt", null);
if (filters.labels.length > 0) {
query = query.in("lists.cards.labels.publicId", filters.labels);
}
if (filters.members.length > 0) {
query = query.in("lists.cards.members.publicId", filters.members);
}
const { data } = await query
.order("index", { foreignTable: "list", ascending: true })
.order("index", { foreignTable: "list.card", ascending: true })
.limit(1)
.single();
return data;
};
export const getWithListIdsByPublicId = async (
db: SupabaseClient<Database>,
boardPublicId: string,
) => {
const { data } = await db
.from("board")
.select(`id, lists:list (id)`)
.eq("publicId", boardPublicId)
.limit(1)
.single();
return data;
};
export const getWithLatestListIndexByPublicId = async (
db: SupabaseClient<Database>,
boardPublicId: string,
) => {
const { data } = await db
.from("board")
.select(`id, lists:list (index)`)
.eq("publicId", boardPublicId)
.order("index", { foreignTable: "list", ascending: false })
.is("list.deletedAt", null)
.limit(1)
.single();
return data;
};
export const create = async (
db: SupabaseClient<Database>,
boardInput: {
name: string;
createdBy: string;
workspaceId: number;
importId?: number;
},
) => {
const { data } = await db
.from("board")
.insert({
publicId: generateUID(),
name: boardInput.name,
createdBy: boardInput.createdBy,
workspaceId: boardInput.workspaceId,
importId: boardInput.importId,
})
.select(`id, publicId, name`)
.limit(1)
.single();
return data;
};
export const update = async (
db: SupabaseClient<Database>,
boardInput: { name: string; boardPublicId: string },
) => {
const { data } = await db
.from("board")
.update({ name: boardInput.name })
.eq("publicId", boardInput.boardPublicId)
.select(`publicId, name`)
.limit(1)
.single();
return data;
};
export const softDelete = async (
db: SupabaseClient<Database>,
args: {
boardId: number;
deletedAt: string;
deletedBy: string;
},
) => {
const result = db
.from("board")
.update({ deletedAt: args.deletedAt, deletedBy: args.deletedBy })
.eq("id", args.boardId)
.is("deletedAt", null);
return result;
};
export const hardDelete = async (
db: SupabaseClient<Database>,
workspaceId: number,
) => {
const result = db.from("board").delete().eq("workspaceId", workspaceId);
return result;
};

View File

@@ -0,0 +1,426 @@
import type { SupabaseClient } from "@supabase/supabase-js";
import type { Database } from "@kan/db/types/database.types";
import { generateUID } from "@kan/utils";
export const create = async (
db: SupabaseClient<Database>,
cardInput: {
title: string;
description: string;
createdBy: string;
listId: number;
index: number;
},
) => {
const { data } = await db
.from("card")
.insert({
publicId: generateUID(),
title: cardInput.title,
description: cardInput.description,
createdBy: cardInput.createdBy,
listId: cardInput.listId,
index: cardInput.index,
})
.select(`id`)
.limit(1)
.single();
return data;
};
export const bulkCreateCardLabelRelationships = async (
db: SupabaseClient<Database>,
cardLabelRelationshipInput: {
cardId: number;
labelId: number;
}[],
) => {
const { data } = await db
.from("_card_labels")
.insert(cardLabelRelationshipInput)
.select();
return data;
};
export const bulkCreateCardWorkspaceMemberRelationships = async (
db: SupabaseClient<Database>,
cardWorkspaceMemberRelationshipInput: {
cardId: number;
workspaceMemberId: number;
}[],
) => {
const { data } = await db
.from("_card_workspace_members")
.insert(cardWorkspaceMemberRelationshipInput)
.select();
return data;
};
export const update = async (
db: SupabaseClient<Database>,
cardInput: {
title: string;
description: string;
},
args: {
cardPublicId: string;
},
) => {
const { data } = await db
.from("card")
.update({ title: cardInput.title, description: cardInput.description })
.eq("publicId", args.cardPublicId)
.is("deletedAt", null)
.select(`id, publicId, title, description`)
.order("id", { ascending: true })
.limit(1)
.single();
return data;
};
export const getCardWithListByPublicId = async (
db: SupabaseClient<Database>,
cardPublicId: string,
) => {
const { data } = await db
.from("card")
.select(`id, index, list (id, boardId)`)
.eq("publicId", cardPublicId)
.is("deletedAt", null)
.limit(1)
.single();
return data;
};
export const getByPublicId = async (
db: SupabaseClient<Database>,
cardPublicId: string,
) => {
const { data } = await db
.from("card")
.select(`id, publicId, title, description`)
.eq("publicId", cardPublicId)
.limit(1)
.single();
return data;
};
export const getCardLabelRelationship = async (
db: SupabaseClient<Database>,
args: { cardId: number; labelId: number },
) => {
const { data } = await db
.from("_card_labels")
.select()
.eq("cardId", args.cardId)
.eq("labelId", args.labelId)
.limit(1)
.single();
return data;
};
export const bulkCreate = async (
db: SupabaseClient<Database>,
cardInput: {
publicId: string;
title: string;
description: string;
createdBy: string;
listId: number;
index: number;
importId?: number;
}[],
) => {
const { data } = await db.from("card").insert(cardInput).select(`id`);
return data;
};
export const createCardLabelRelationship = async (
db: SupabaseClient<Database>,
cardLabelRelationshipInput: { cardId: number; labelId: number },
) => {
const { data } = await db
.from("_card_labels")
.insert({
cardId: cardLabelRelationshipInput.cardId,
labelId: cardLabelRelationshipInput.labelId,
})
.select()
.limit(1)
.single();
return data;
};
export const getCardMemberRelationship = async (
db: SupabaseClient<Database>,
args: { cardId: number; memberId: number },
) => {
const { data } = await db
.from("_card_workspace_members")
.select()
.eq("cardId", args.cardId)
.eq("workspaceMemberId", args.memberId)
.limit(1)
.single();
return data;
};
export const createCardMemberRelationship = async (
db: SupabaseClient<Database>,
cardMemberRelationshipInput: { cardId: number; memberId: number },
) => {
const { error } = await db.from("_card_workspace_members").insert({
cardId: cardMemberRelationshipInput.cardId,
workspaceMemberId: cardMemberRelationshipInput.memberId,
});
return { success: !error };
};
export const getWithListAndMembersByPublicId = async (
db: SupabaseClient<Database>,
cardPublicId: string,
) => {
const { data } = await db
.from("card")
.select(
`
publicId,
title,
description,
labels:label (
publicId,
name,
colourCode
),
list (
publicId,
name,
board (
publicId,
name,
labels:label (
publicId,
colourCode,
name
),
lists:list (
publicId,
name
),
workspace (
publicId,
members:workspace_members (
publicId,
user!workspace_members_userId_user_id_fk (
id,
name
)
)
)
)
),
members:workspace_members (
publicId,
user!workspace_members_userId_user_id_fk (
id,
name
)
),
activities:card_activity (
publicId,
type,
createdAt,
fromIndex,
toIndex,
fromTitle,
toTitle,
fromDescription,
toDescription,
fromList:list!card_activity_fromListId_list_id_fk (
publicId,
name,
index
),
toList:list!card_activity_toListId_list_id_fk (
publicId,
name,
index
),
label!card_activity_labelId_label_id_fk (
publicId,
name
),
member:workspace_members!card_activity_workspaceMemberId_workspace_members_id_fk (
publicId,
user!workspace_members_userId_user_id_fk (
id,
name,
email
)
),
user!card_activity_createdBy_user_id_fk (
id,
name,
email
),
comment:card_comments!card_activity_commentId_card_comments_id_fk (
publicId,
comment,
createdBy,
updatedAt
)
)
`,
)
.eq("publicId", cardPublicId)
.is("deletedAt", null)
.is("list.board.lists.deletedAt", null)
.is("list.board.workspace.members.deletedAt", null)
.is("members.deletedAt", null)
.limit(1)
.single();
return data;
};
export const reorder = async (
db: SupabaseClient<Database>,
args: {
currentListId: number;
newListId: number;
currentIndex: number;
newIndex: number;
cardId: number;
},
) => {
const { error } = await db.rpc("reorder_cards", {
current_list_id: args.currentListId,
new_list_id: args.newListId,
current_index: args.currentIndex,
new_index: args.newIndex,
card_id: args.cardId,
});
return { success: !error };
};
export const shiftIndex = async (
db: SupabaseClient<Database>,
args: {
listId: number;
cardIndex: number;
},
) => {
const { data } = await db.rpc("shift_card_index", {
list_id: args.listId,
card_index: args.cardIndex,
});
return data;
};
export const pushIndex = async (
db: SupabaseClient<Database>,
args: {
listId: number;
cardIndex: number;
},
) => {
const { data } = await db.rpc("push_card_index", {
list_id: args.listId,
card_index: args.cardIndex,
});
return data;
};
export const softDelete = async (
db: SupabaseClient<Database>,
args: {
cardId: number;
deletedAt: string;
deletedBy: string;
},
) => {
const { data } = await db
.from("card")
.update({ deletedAt: args.deletedAt, deletedBy: args.deletedBy })
.eq("id", args.cardId)
.select(`id`)
.order("id", { ascending: true })
.limit(1)
.single();
return data;
};
export const softDeleteAllByListIds = async (
db: SupabaseClient<Database>,
args: {
listIds: number[];
deletedAt: string;
deletedBy: string;
},
) => {
const { data } = await db
.from("card")
.update({ deletedAt: args.deletedAt, deletedBy: args.deletedBy })
.in("listId", args.listIds)
.is("deletedAt", null)
.select(`id`);
return data;
};
export const hardDeleteCardMemberRelationship = async (
db: SupabaseClient<Database>,
args: { cardId: number; memberId: number },
) => {
const { error } = await db
.from("_card_workspace_members")
.delete()
.eq("cardId", args.cardId)
.eq("workspaceMemberId", args.memberId)
.select()
.order("cardId", { ascending: true })
.limit(1)
.single();
return { success: !error };
};
export const hardDeleteCardLabelRelationship = async (
db: SupabaseClient<Database>,
args: { cardId: number; labelId: number },
) => {
const { data } = await db
.from("_card_labels")
.delete()
.eq("cardId", args.cardId)
.eq("labelId", args.labelId)
.select()
.single();
return { data };
};
export const hardDeleteAllCardLabelRelationships = async (
db: SupabaseClient<Database>,
labelId: number,
) => {
const result = await db.from("_card_labels").delete().eq("labelId", labelId);
return result;
};

View File

@@ -0,0 +1,84 @@
import type { SupabaseClient } from "@supabase/supabase-js";
import type { Database } from "@kan/db/types/database.types";
import { generateUID } from "@kan/utils";
export const create = async (
db: SupabaseClient<Database>,
activityInput: {
type: Database["public"]["Enums"]["card_activity_type"];
cardId: number;
fromIndex?: number;
toIndex?: number;
fromListId?: number;
toListId?: number;
labelId?: number;
workspaceMemberId?: number;
fromTitle?: string;
toTitle?: string;
fromDescription?: string;
toDescription?: string;
createdBy: string;
commentId?: number;
fromComment?: string;
toComment?: string;
},
) => {
const { data } = await db
.from("card_activity")
.insert({
publicId: generateUID(),
type: activityInput.type,
cardId: activityInput.cardId,
fromListId: activityInput.fromListId,
toListId: activityInput.toListId,
fromIndex: activityInput.fromIndex,
toIndex: activityInput.toIndex,
labelId: activityInput.labelId,
workspaceMemberId: activityInput.workspaceMemberId,
fromTitle: activityInput.fromTitle,
toTitle: activityInput.toTitle,
fromDescription: activityInput.fromDescription,
toDescription: activityInput.toDescription,
createdBy: activityInput.createdBy,
commentId: activityInput.commentId,
fromComment: activityInput.fromComment,
toComment: activityInput.toComment,
})
.select(`id`)
.limit(1)
.single();
return data;
};
export const bulkCreate = async (
db: SupabaseClient<Database>,
activityInputs: {
type: Database["public"]["Enums"]["card_activity_type"];
cardId: number;
fromIndex?: number;
toIndex?: number;
fromListId?: number;
toListId?: number;
labelId?: number;
workspaceMemberId?: number;
fromTitle?: string;
toTitle?: string;
fromDescription?: string;
toDescription?: string;
createdBy: string;
}[],
) => {
const activitiesWithPublicIds = activityInputs.map((activity) => ({
...activity,
publicId: generateUID(),
}));
const { data } = await db
.from("card_activity")
.insert(activitiesWithPublicIds)
.select("id");
return data;
};

View File

@@ -0,0 +1,63 @@
import type { SupabaseClient } from "@supabase/supabase-js";
import type { Database } from "@kan/db/types/database.types";
import { generateUID } from "@kan/utils";
export const create = async (
db: SupabaseClient<Database>,
commentInput: {
cardId: number;
comment: string;
createdBy: string;
},
) => {
const { data } = await db
.from("card_comments")
.insert({
publicId: generateUID(),
comment: commentInput.comment,
createdBy: commentInput.createdBy,
cardId: commentInput.cardId,
})
.select(`id, publicId, comment`)
.limit(1)
.single();
return data;
};
export const getByPublicId = async (
db: SupabaseClient<Database>,
publicId: string,
) => {
const { data } = await db
.from("card_comments")
.select(`id, publicId, comment, createdBy`)
.eq("publicId", publicId)
.limit(1)
.single();
return data;
};
export const update = async (
db: SupabaseClient<Database>,
commentInput: {
id: number;
comment: string;
},
) => {
const { data } = await db
.from("card_comments")
.update({
comment: commentInput.comment,
updatedAt: new Date().toISOString(),
})
.eq("id", commentInput.id)
.select(`id, publicId, comment`)
.limit(1)
.order("id", { ascending: false })
.single();
return data;
};

View File

@@ -0,0 +1,38 @@
import type { SupabaseClient } from "@supabase/supabase-js";
import type { Database } from "@kan/db/types/database.types";
import { generateUID } from "@kan/utils";
export const create = async (
db: SupabaseClient<Database>,
importInput: { source: string; createdBy: string },
) => {
const { data } = await db
.from("import")
.insert({
publicId: generateUID(),
source: "trello",
createdBy: importInput.createdBy,
status: "started",
})
.select(`id`)
.limit(1)
.single();
return data;
};
export const update = async (
db: SupabaseClient<Database>,
importInput: { status: "started" | "success" | "failed" },
args: { importId: number },
) => {
const { data } = await db
.from("import")
.update({ status: importInput.status })
.eq("importId", args.importId)
.limit(1)
.single();
return data;
};

View File

@@ -0,0 +1,90 @@
import type { SupabaseClient } from "@supabase/supabase-js";
import type { Database } from "@kan/db/types/database.types";
import { generateUID } from "@kan/utils";
export const create = async (
db: SupabaseClient<Database>,
labelInput: {
name: string;
colourCode: string;
createdBy: string;
boardId: number;
cardId?: number;
},
) => {
const { data } = await db
.from("label")
.insert({
publicId: generateUID(),
name: labelInput.name,
colourCode: labelInput.colourCode,
createdBy: labelInput.createdBy,
boardId: labelInput.boardId,
})
.select(`id`)
.limit(1)
.single();
if (labelInput.cardId && data)
await db.from("_card_labels").insert({
cardId: labelInput.cardId,
labelId: data.id,
});
return data;
};
export const getAllByPublicIds = async (
db: SupabaseClient<Database>,
labelPublicIds: string[],
) => {
const { data } = await db
.from("label")
.select(`id`)
.in("publicId", labelPublicIds);
return data;
};
export const getByPublicId = async (
db: SupabaseClient<Database>,
labelPublicId: string,
) => {
const { data } = await db
.from("label")
.select(`id, publicId, name, colourCode`)
.eq("publicId", labelPublicId)
.limit(1)
.single();
return data;
};
export const update = async (
db: SupabaseClient<Database>,
labelInput: {
labelPublicId: string;
name: string;
colourCode: string;
},
) => {
const { data } = await db
.from("label")
.update({
name: labelInput.name,
colourCode: labelInput.colourCode,
})
.eq("publicId", labelInput.labelPublicId);
return data;
};
export const hardDelete = async (
db: SupabaseClient<Database>,
labelId: number,
) => {
const { data } = await db.from("label").delete().eq("id", labelId);
return data;
};

View File

@@ -0,0 +1,161 @@
import type { SupabaseClient } from "@supabase/supabase-js";
import type { Database } from "@kan/db/types/database.types";
import { generateUID } from "@kan/utils";
export const create = async (
db: SupabaseClient<Database>,
listInput: {
name: string;
createdBy: string;
boardId: number;
index: number;
importId?: number;
},
) => {
const { data } = await db
.from("list")
.insert({
publicId: generateUID(),
name: listInput.name,
createdBy: listInput.createdBy,
boardId: listInput.boardId,
index: listInput.index,
importId: listInput.importId,
})
.select(
`
id,
publicId,
name
`,
)
.limit(1)
.single();
return data;
};
export const getByPublicId = async (
db: SupabaseClient<Database>,
listPublicId: string,
) => {
const { data } = await db
.from("list")
.select(`id, boardId, index`)
.eq("publicId", listPublicId)
.limit(1)
.single();
return data;
};
export const getWithCardsByPublicId = async (
db: SupabaseClient<Database>,
listPublicId: string,
) => {
const { data } = await db
.from("list")
.select(`id, cards:card (index)`)
.eq("publicId", listPublicId)
.is("deletedAt", null)
.is("card.deletedAt", null)
.order("index", { foreignTable: "card", ascending: false })
.limit(1)
.single();
return data;
};
export const update = async (
db: SupabaseClient<Database>,
listInput: {
name: string;
},
args: {
listPublicId: string;
},
) => {
const { data } = await db
.from("list")
.update({ name: listInput.name })
.eq("publicId", args.listPublicId)
.is("deletedAt", null)
.select(`publicId, name`);
return data;
};
export const reorder = async (
db: SupabaseClient<Database>,
args: {
boardPublicId: number;
listPublicId: number;
currentIndex: number;
newIndex: number;
},
) => {
const { data } = await db.rpc("reorder_lists", {
board_id: args.boardPublicId,
list_id: args.listPublicId,
current_index: args.currentIndex,
new_index: args.newIndex,
});
return data;
};
export const shiftIndex = async (
db: SupabaseClient<Database>,
args: {
boardId: number;
listIndex: number;
},
) => {
const { data } = await db.rpc("shift_list_index", {
board_id: args.boardId,
list_index: args.listIndex,
});
return data;
};
export const softDeleteAllByBoardId = async (
db: SupabaseClient<Database>,
args: {
boardId: number;
deletedAt: string;
deletedBy: string;
},
) => {
const { data } = await db
.from("list")
.update({ deletedAt: args.deletedAt, deletedBy: args.deletedBy })
.eq("boardId", args.boardId)
.is("deletedAt", null)
.select(`id`)
.order("id", { ascending: true });
return data;
};
export const softDeleteById = async (
db: SupabaseClient<Database>,
args: {
listId: number;
deletedAt: string;
deletedBy: string;
},
) => {
const { data } = await db
.from("list")
.update({ deletedAt: args.deletedAt, deletedBy: args.deletedBy })
.eq("id", args.listId)
.is("deletedAt", null)
.select(`id`)
.order("id", { ascending: true })
.limit(1)
.single();
return data;
};

View File

@@ -0,0 +1,74 @@
import type { SupabaseClient } from "@supabase/supabase-js";
import type { Database } from "@kan/db/types/database.types";
import { generateUID } from "@kan/utils";
export const create = async (
db: SupabaseClient<Database>,
memberInput: {
userId: string;
workspaceId: number;
createdBy: string;
role: "admin" | "member" | "guest";
status: "invited" | "active" | "removed";
},
) => {
const { data } = await db
.from("workspace_members")
.insert({
publicId: generateUID(),
userId: memberInput.userId,
workspaceId: memberInput.workspaceId,
createdBy: memberInput.createdBy,
role: memberInput.role,
status: memberInput.status,
})
.select(`id, publicId`)
.limit(1)
.single();
return data;
};
export const getByPublicId = async (
db: SupabaseClient<Database>,
publicId: string,
) => {
const { data } = await db
.from("workspace_members")
.select()
.eq("publicId", publicId)
.limit(1)
.single();
return data;
};
export const acceptInvite = async (
db: SupabaseClient<Database>,
id: number,
) => {
const { data } = await db
.from("workspace_members")
.update({ status: "active" })
.eq("id", id);
return data;
};
export const softDelete = async (
db: SupabaseClient<Database>,
args: {
memberId: number;
deletedAt: string;
deletedBy: string;
},
) => {
const result = await db
.from("workspace_members")
.update({ deletedAt: args.deletedAt, deletedBy: args.deletedBy })
.eq("id", args.memberId)
.is("deletedAt", null);
return result;
};

View File

@@ -0,0 +1,42 @@
import type { SupabaseClient } from "@supabase/supabase-js";
import type { Database } from "@kan/db/types/database.types";
export const getById = async (db: SupabaseClient<Database>, userId: string) => {
const { data } = await db
.from("user")
.select(`id, name, email`)
.eq("id", userId)
.limit(1)
.single();
return data;
};
export const getByEmail = async (
db: SupabaseClient<Database>,
email: string,
) => {
const { data } = await db
.from("user")
.select(`id, name, email`)
.eq("email", email)
.limit(1)
.single();
return data;
};
export const create = async (
db: SupabaseClient<Database>,
user: { id: string; email: string },
) => {
const { data } = await db
.from("user")
.insert({ id: user.id, email: user.email })
.select()
.limit(1)
.single();
return data;
};

View File

@@ -0,0 +1,159 @@
import type { SupabaseClient } from "@supabase/supabase-js";
import type { Database } from "@kan/db/types/database.types";
import { generateUID } from "@kan/utils";
export const create = async (
db: SupabaseClient<Database>,
workspaceInput: {
name: string;
slug: string;
createdBy: string;
},
) => {
const { data } = await db
.from("workspace")
.insert({
publicId: generateUID(),
name: workspaceInput.name,
slug: workspaceInput.name.toLowerCase(),
createdBy: workspaceInput.createdBy,
})
.select(`id, publicId, name`)
.limit(1)
.single();
if (data)
await db.from("workspace_members").insert({
publicId: generateUID(),
userId: workspaceInput.createdBy,
workspaceId: data.id,
createdBy: workspaceInput.createdBy,
role: "admin",
});
const newWorkspace = { ...data };
delete newWorkspace.id;
return newWorkspace;
};
export const update = async (
db: SupabaseClient<Database>,
workspacePublicId: string,
name: string,
) => {
const { data } = await db
.from("workspace")
.update({ name })
.eq("publicId", workspacePublicId)
.is("deletedAt", null);
return data;
};
export const getByPublicId = async (
db: SupabaseClient<Database>,
workspacePublicId: string,
) => {
const { data } = await db
.from("workspace")
.select(`id, publicId, name`)
.is("deletedAt", null)
.eq("publicId", workspacePublicId)
.limit(1)
.single();
return data;
};
export const getByPublicIdWithMembers = async (
db: SupabaseClient<Database>,
workspacePublicId: string,
) => {
const { data } = await db
.from("workspace")
.select(
`
id,
publicId,
members: workspace_members (
publicId,
role,
status,
user!workspace_members_userId_user_id_fk (
id,
name,
email
)
)
`,
)
.eq("publicId", workspacePublicId)
.is("deletedAt", null)
.is("members.deletedAt", null)
.limit(1)
.single();
return data;
};
export const getAllByUserId = async (
db: SupabaseClient<Database>,
userId: string,
) => {
const { data } = await db
.from("workspace_members")
.select(
`
role,
workspace (
publicId,
name
)
`,
)
.eq("userId", userId)
.is("deletedAt", null);
return data ?? [];
};
export const getMemberByPublicId = async (
db: SupabaseClient<Database>,
memberPublicId: string,
) => {
const { data } = await db
.from("workspace_members")
.select(`id`)
.eq("publicId", memberPublicId)
.limit(1)
.single();
return data;
};
export const getAllMembersByPublicIds = async (
db: SupabaseClient<Database>,
memberPublicIds: string[],
) => {
const { data } = await db
.from("workspace_members")
.select(`id`)
.eq("publicId", memberPublicIds);
return data;
};
export const hardDelete = async (
db: SupabaseClient<Database>,
workspacePublicId: string,
) => {
const result = db
.from("workspace")
.delete()
.eq("publicId", workspacePublicId);
return result;
};

432
packages/db/src/schema.ts Normal file
View File

@@ -0,0 +1,432 @@
import { relations } from "drizzle-orm";
import {
integer,
bigserial,
uuid,
pgEnum,
pgTable,
primaryKey,
text,
timestamp,
varchar,
bigint,
} from "drizzle-orm/pg-core";
export const importSourceEnum = pgEnum("source", ["trello"]);
export const importStatusEnum = pgEnum("status", [
"started",
"success",
"failed",
]);
export const memberRoleEnum = pgEnum("role", ["admin", "member", "guest"]);
export const memberStatusEnum = pgEnum("member_status", [
"invited",
"active",
"removed",
]);
export const activityTypeEnum = pgEnum("card_activity_type", [
"card.created",
"card.updated.title",
"card.updated.description",
"card.updated.index",
"card.updated.list",
"card.updated.label.added",
"card.updated.label.removed",
"card.updated.member.added",
"card.updated.member.removed",
"card.updated.comment.added",
"card.updated.comment.updated",
"card.updated.comment.deleted",
"card.archived",
]);
export const boards = pgTable("board", {
id: bigserial("id", { mode: "number" }).primaryKey(),
publicId: varchar("publicId", { length: 12 }).notNull().unique(),
name: varchar("name", { length: 255 }).notNull(),
createdBy: uuid("createdBy")
.notNull()
.references(() => users.id),
createdAt: timestamp("createdAt").defaultNow().notNull(),
updatedAt: timestamp("updatedAt"),
deletedAt: timestamp("deletedAt"),
deletedBy: uuid("deletedBy").references(() => users.id),
importId: bigint("importId", { mode: "number" }).references(() => imports.id),
workspaceId: bigint("workspaceId", { mode: "number" })
.notNull()
.references(() => workspaces.id, { onDelete: "cascade" }),
});
export const boardsRelations = relations(boards, ({ one, many }) => ({
createdBy: one(users, {
fields: [boards.createdBy],
references: [users.id],
}),
lists: many(lists),
labels: many(labels),
deletedBy: one(users, {
fields: [boards.deletedBy],
references: [users.id],
}),
import: one(imports, {
fields: [boards.importId],
references: [imports.id],
}),
workspace: one(workspaces, {
fields: [boards.workspaceId],
references: [workspaces.id],
}),
}));
export const imports = pgTable("import", {
id: bigserial("id", { mode: "number" }).primaryKey(),
publicId: varchar("publicId", { length: 12 }).notNull().unique(),
source: importSourceEnum("source").notNull(),
status: importStatusEnum("status").notNull(),
createdBy: uuid("createdBy")
.notNull()
.references(() => users.id),
createdAt: timestamp("createdAt").defaultNow().notNull(),
});
export const importsRelations = relations(imports, ({ one, many }) => ({
createdBy: one(users, {
fields: [imports.createdBy],
references: [users.id],
}),
boards: many(boards),
cards: many(cards),
lists: many(lists),
labels: many(labels),
}));
export const labels = pgTable("label", {
id: bigserial("id", { mode: "number" }).primaryKey(),
publicId: varchar("publicId", { length: 12 }).notNull().unique(),
name: varchar("name", { length: 255 }).notNull(),
colourCode: varchar("colourCode", { length: 12 }),
createdBy: uuid("createdBy")
.notNull()
.references(() => users.id),
createdAt: timestamp("createdAt").defaultNow().notNull(),
updatedAt: timestamp("updatedAt"),
boardId: bigint("boardId", { mode: "number" })
.notNull()
.references(() => boards.id, { onDelete: "cascade" }),
importId: bigint("importId", { mode: "number" }).references(() => imports.id),
});
export const labelsRelations = relations(labels, ({ one, many }) => ({
createdBy: one(users, {
fields: [labels.createdBy],
references: [users.id],
}),
board: one(boards, {
fields: [labels.boardId],
references: [boards.id],
}),
cards: many(cardsToLabels),
import: one(imports, {
fields: [labels.importId],
references: [imports.id],
}),
}));
export const cardsToLabels = pgTable(
"_card_labels",
{
cardId: bigint("cardId", { mode: "number" })
.notNull()
.references(() => cards.id),
labelId: bigint("labelId", { mode: "number" })
.notNull()
.references(() => labels.id, { onDelete: "cascade" }),
},
(t) => ({
pk: primaryKey(t.cardId, t.labelId),
}),
);
export const cardToLabelsRelations = relations(cardsToLabels, ({ one }) => ({
card: one(cards, {
fields: [cardsToLabels.cardId],
references: [cards.id],
}),
label: one(labels, {
fields: [cardsToLabels.labelId],
references: [labels.id],
}),
}));
export const cardToWorkspaceMembers = pgTable(
"_card_workspace_members",
{
cardId: bigint("cardId", { mode: "number" })
.notNull()
.references(() => cards.id),
workspaceMemberId: bigint("workspaceMemberId", { mode: "number" })
.notNull()
.references(() => workspaceMembers.id, { onDelete: "cascade" }),
},
(t) => ({
pk: primaryKey(t.cardId, t.workspaceMemberId),
}),
);
export const cardToWorkspaceMembersRelations = relations(
cardToWorkspaceMembers,
({ one }) => ({
card: one(cards, {
fields: [cardToWorkspaceMembers.cardId],
references: [cards.id],
}),
member: one(workspaceMembers, {
fields: [cardToWorkspaceMembers.workspaceMemberId],
references: [workspaceMembers.id],
}),
}),
);
export const lists = pgTable("list", {
id: bigserial("id", { mode: "number" }).primaryKey(),
publicId: varchar("publicId", { length: 12 }).notNull().unique(),
name: varchar("name", { length: 255 }).notNull(),
index: integer("index").notNull(),
createdBy: uuid("createdBy")
.notNull()
.references(() => users.id),
createdAt: timestamp("createdAt").defaultNow().notNull(),
updatedAt: timestamp("updatedAt"),
deletedAt: timestamp("deletedAt"),
deletedBy: uuid("deletedBy").references(() => users.id),
boardId: bigint("boardId", { mode: "number" })
.notNull()
.references(() => boards.id, { onDelete: "cascade" }),
importId: bigint("importId", { mode: "number" }).references(() => imports.id),
});
export const listsRelations = relations(lists, ({ one, many }) => ({
createdBy: one(users, {
fields: [lists.createdBy],
references: [users.id],
}),
board: one(boards, {
fields: [lists.boardId],
references: [boards.id],
}),
cards: many(cards),
deletedBy: one(users, {
fields: [lists.deletedBy],
references: [users.id],
}),
import: one(imports, {
fields: [lists.importId],
references: [imports.id],
}),
}));
export const cards = pgTable("card", {
id: bigserial("id", { mode: "number" }).primaryKey(),
publicId: varchar("publicId", { length: 12 }).notNull().unique(),
title: varchar("title", { length: 255 }).notNull(),
description: text("description"),
index: integer("index").notNull(),
createdBy: uuid("createdBy")
.notNull()
.references(() => users.id),
createdAt: timestamp("createdAt").defaultNow().notNull(),
updatedAt: timestamp("updatedAt"),
deletedAt: timestamp("deletedAt"),
deletedBy: uuid("deletedBy").references(() => users.id),
listId: bigint("listId", { mode: "number" })
.notNull()
.references(() => lists.id, { onDelete: "cascade" }),
importId: bigint("importId", { mode: "number" }).references(() => imports.id),
});
export const cardsRelations = relations(cards, ({ one, many }) => ({
createdBy: one(users, {
fields: [cards.createdBy],
references: [users.id],
}),
list: one(lists, {
fields: [cards.listId],
references: [lists.id],
}),
deletedBy: one(users, {
fields: [cards.deletedBy],
references: [users.id],
}),
labels: many(cardsToLabels),
members: many(cardToWorkspaceMembers),
import: one(imports, {
fields: [cards.importId],
references: [imports.id],
}),
comments: many(comments),
}));
export const users = pgTable("user", {
id: uuid("id").notNull().primaryKey(),
name: varchar("name", { length: 255 }),
email: varchar("email", { length: 255 }).notNull().unique(),
emailVerified: timestamp("emailVerified", { mode: "date" }),
image: varchar("image", { length: 255 }),
});
export const usersRelations = relations(users, ({ many }) => ({
boards: many(boards),
cards: many(cards),
imports: many(imports),
lists: many(lists),
workspaces: many(workspaces),
}));
export const workspaces = pgTable("workspace", {
id: bigserial("id", { mode: "number" }).primaryKey(),
publicId: varchar("publicId", { length: 12 }).notNull().unique(),
name: varchar("name", { length: 255 }).notNull(),
slug: varchar("slug", { length: 255 }).notNull().unique(),
createdBy: uuid("createdBy")
.notNull()
.references(() => users.id),
createdAt: timestamp("createdAt").defaultNow().notNull(),
updatedAt: timestamp("updatedAt"),
deletedAt: timestamp("deletedAt"),
deletedBy: uuid("deletedBy").references(() => users.id),
});
export const workspaceRelations = relations(workspaces, ({ one, many }) => ({
user: one(users, { fields: [workspaces.createdBy], references: [users.id] }),
members: many(workspaceMembers),
}));
export const workspaceMembers = pgTable("workspace_members", {
id: bigserial("id", { mode: "number" }).primaryKey(),
publicId: varchar("publicId", { length: 12 }).notNull().unique(),
userId: uuid("userId")
.notNull()
.references(() => users.id),
workspaceId: bigint("workspaceId", { mode: "number" })
.notNull()
.references(() => workspaces.id, { onDelete: "cascade" }),
createdBy: uuid("createdBy").notNull(),
createdAt: timestamp("createdAt").defaultNow().notNull(),
updatedAt: timestamp("updatedAt"),
deletedAt: timestamp("deletedAt"),
deletedBy: uuid("deletedBy").references(() => users.id),
role: memberRoleEnum("role").notNull(),
status: memberStatusEnum("status").default("invited").notNull(),
});
export const usersToWorkspacesRelations = relations(
workspaceMembers,
({ one }) => ({
addedBy: one(users, {
fields: [workspaceMembers.createdBy],
references: [users.id],
}),
deletedBy: one(users, {
fields: [workspaceMembers.deletedBy],
references: [users.id],
}),
user: one(users, {
fields: [workspaceMembers.userId],
references: [users.id],
}),
workspace: one(workspaces, {
fields: [workspaceMembers.workspaceId],
references: [workspaces.id],
}),
}),
);
export const cardActivities = pgTable("card_activity", {
id: bigserial("id", { mode: "number" }).primaryKey(),
publicId: varchar("publicId", { length: 12 }).notNull().unique(),
type: activityTypeEnum("type").notNull(),
cardId: bigint("cardId", { mode: "number" })
.notNull()
.references(() => cards.id, { onDelete: "cascade" }),
fromIndex: integer("fromIndex"),
toIndex: integer("toIndex"),
fromListId: bigint("fromListId", { mode: "number" }).references(
() => lists.id,
),
toListId: bigint("toListId", { mode: "number" }).references(() => lists.id),
labelId: bigint("labelId", { mode: "number" }).references(() => labels.id),
workspaceMemberId: bigint("workspaceMemberId", { mode: "number" }).references(
() => workspaceMembers.id,
),
fromTitle: varchar("fromTitle", { length: 255 }),
toTitle: varchar("toTitle", { length: 255 }),
fromDescription: text("fromDescription"),
toDescription: text("toDescription"),
createdBy: uuid("createdBy")
.notNull()
.references(() => users.id),
createdAt: timestamp("createdAt").defaultNow().notNull(),
commentId: bigint("commentId", { mode: "number" }).references(
() => comments.id,
),
fromComment: text("fromComment"),
toComment: text("toComment"),
});
export const cardActivitiesRelations = relations(cardActivities, ({ one }) => ({
card: one(cards, {
fields: [cardActivities.cardId],
references: [cards.id],
}),
fromList: one(lists, {
fields: [cardActivities.fromListId],
references: [lists.id],
}),
toList: one(lists, {
fields: [cardActivities.toListId],
references: [lists.id],
}),
label: one(labels, {
fields: [cardActivities.labelId],
references: [labels.id],
}),
workspaceMember: one(workspaceMembers, {
fields: [cardActivities.workspaceMemberId],
references: [workspaceMembers.id],
}),
createdBy: one(users, {
fields: [cardActivities.createdBy],
references: [users.id],
}),
}));
export const comments = pgTable("card_comments", {
id: bigserial("id", { mode: "number" }).primaryKey(),
publicId: varchar("publicId", { length: 12 }).notNull().unique(),
comment: text("comment").notNull(),
cardId: bigint("cardId", { mode: "number" })
.notNull()
.references(() => cards.id, { onDelete: "cascade" }),
createdBy: uuid("createdBy")
.notNull()
.references(() => users.id),
createdAt: timestamp("createdAt").defaultNow().notNull(),
updatedAt: timestamp("updatedAt"),
deletedAt: timestamp("deletedAt"),
deletedBy: uuid("deletedBy").references(() => users.id),
});
export const commentsRelations = relations(comments, ({ one }) => ({
card: one(cards, {
fields: [comments.cardId],
references: [cards.id],
}),
createdBy: one(users, {
fields: [comments.createdBy],
references: [users.id],
}),
deletedBy: one(users, {
fields: [comments.deletedBy],
references: [users.id],
}),
}));

View File

@@ -0,0 +1,868 @@
/* eslint-disable @typescript-eslint/no-redundant-type-constituents */
export type Json =
| string
| number
| boolean
| null
| { [key: string]: Json | undefined }
| Json[];
export type Database = {
public: {
Tables: {
_card_labels: {
Row: {
cardId: number;
labelId: number;
};
Insert: {
cardId: number;
labelId: number;
};
Update: {
cardId?: number;
labelId?: number;
};
Relationships: [
{
foreignKeyName: "_card_labels_cardId_card_id_fk";
columns: ["cardId"];
isOneToOne: false;
referencedRelation: "card";
referencedColumns: ["id"];
},
{
foreignKeyName: "_card_labels_labelId_label_id_fk";
columns: ["labelId"];
isOneToOne: false;
referencedRelation: "label";
referencedColumns: ["id"];
},
];
};
_card_workspace_members: {
Row: {
cardId: number;
workspaceMemberId: number;
};
Insert: {
cardId: number;
workspaceMemberId: number;
};
Update: {
cardId?: number;
workspaceMemberId?: number;
};
Relationships: [
{
foreignKeyName: "_card_workspace_members_cardId_card_id_fk";
columns: ["cardId"];
isOneToOne: false;
referencedRelation: "card";
referencedColumns: ["id"];
},
{
foreignKeyName: "_card_workspace_members_workspaceMemberId_workspace_members_id_";
columns: ["workspaceMemberId"];
isOneToOne: false;
referencedRelation: "workspace_members";
referencedColumns: ["id"];
},
];
};
board: {
Row: {
createdAt: string;
createdBy: string;
deletedAt: string | null;
deletedBy: string | null;
id: number;
importId: number | null;
name: string;
publicId: string;
updatedAt: string | null;
workspaceId: number;
};
Insert: {
createdAt?: string;
createdBy: string;
deletedAt?: string | null;
deletedBy?: string | null;
id?: number;
importId?: number | null;
name: string;
publicId: string;
updatedAt?: string | null;
workspaceId: number;
};
Update: {
createdAt?: string;
createdBy?: string;
deletedAt?: string | null;
deletedBy?: string | null;
id?: number;
importId?: number | null;
name?: string;
publicId?: string;
updatedAt?: string | null;
workspaceId?: number;
};
Relationships: [
{
foreignKeyName: "board_createdBy_user_id_fk";
columns: ["createdBy"];
isOneToOne: false;
referencedRelation: "user";
referencedColumns: ["id"];
},
{
foreignKeyName: "board_deletedBy_user_id_fk";
columns: ["deletedBy"];
isOneToOne: false;
referencedRelation: "user";
referencedColumns: ["id"];
},
{
foreignKeyName: "board_importId_import_id_fk";
columns: ["importId"];
isOneToOne: false;
referencedRelation: "import";
referencedColumns: ["id"];
},
{
foreignKeyName: "board_workspaceId_workspace_id_fk";
columns: ["workspaceId"];
isOneToOne: false;
referencedRelation: "workspace";
referencedColumns: ["id"];
},
];
};
card: {
Row: {
createdAt: string;
createdBy: string;
deletedAt: string | null;
deletedBy: string | null;
description: string | null;
id: number;
importId: number | null;
index: number;
listId: number;
publicId: string;
title: string;
updatedAt: string | null;
};
Insert: {
createdAt?: string;
createdBy: string;
deletedAt?: string | null;
deletedBy?: string | null;
description?: string | null;
id?: number;
importId?: number | null;
index: number;
listId: number;
publicId: string;
title: string;
updatedAt?: string | null;
};
Update: {
createdAt?: string;
createdBy?: string;
deletedAt?: string | null;
deletedBy?: string | null;
description?: string | null;
id?: number;
importId?: number | null;
index?: number;
listId?: number;
publicId?: string;
title?: string;
updatedAt?: string | null;
};
Relationships: [
{
foreignKeyName: "card_createdBy_user_id_fk";
columns: ["createdBy"];
isOneToOne: false;
referencedRelation: "user";
referencedColumns: ["id"];
},
{
foreignKeyName: "card_deletedBy_user_id_fk";
columns: ["deletedBy"];
isOneToOne: false;
referencedRelation: "user";
referencedColumns: ["id"];
},
{
foreignKeyName: "card_importId_import_id_fk";
columns: ["importId"];
isOneToOne: false;
referencedRelation: "import";
referencedColumns: ["id"];
},
{
foreignKeyName: "card_listId_list_id_fk";
columns: ["listId"];
isOneToOne: false;
referencedRelation: "list";
referencedColumns: ["id"];
},
];
};
card_activity: {
Row: {
cardId: number;
commentId: number | null;
createdAt: string;
createdBy: string;
fromComment: string | null;
fromDescription: string | null;
fromIndex: number | null;
fromListId: number | null;
fromTitle: string | null;
id: number;
labelId: number | null;
publicId: string;
toComment: string | null;
toDescription: string | null;
toIndex: number | null;
toListId: number | null;
toTitle: string | null;
type: Database["public"]["Enums"]["card_activity_type"];
workspaceMemberId: number | null;
};
Insert: {
cardId: number;
commentId?: number | null;
createdAt?: string;
createdBy: string;
fromComment?: string | null;
fromDescription?: string | null;
fromIndex?: number | null;
fromListId?: number | null;
fromTitle?: string | null;
id?: number;
labelId?: number | null;
publicId: string;
toComment?: string | null;
toDescription?: string | null;
toIndex?: number | null;
toListId?: number | null;
toTitle?: string | null;
type: Database["public"]["Enums"]["card_activity_type"];
workspaceMemberId?: number | null;
};
Update: {
cardId?: number;
commentId?: number | null;
createdAt?: string;
createdBy?: string;
fromComment?: string | null;
fromDescription?: string | null;
fromIndex?: number | null;
fromListId?: number | null;
fromTitle?: string | null;
id?: number;
labelId?: number | null;
publicId?: string;
toComment?: string | null;
toDescription?: string | null;
toIndex?: number | null;
toListId?: number | null;
toTitle?: string | null;
type?: Database["public"]["Enums"]["card_activity_type"];
workspaceMemberId?: number | null;
};
Relationships: [
{
foreignKeyName: "card_activity_cardId_card_id_fk";
columns: ["cardId"];
isOneToOne: false;
referencedRelation: "card";
referencedColumns: ["id"];
},
{
foreignKeyName: "card_activity_commentId_card_comments_id_fk";
columns: ["commentId"];
isOneToOne: false;
referencedRelation: "card_comments";
referencedColumns: ["id"];
},
{
foreignKeyName: "card_activity_createdBy_user_id_fk";
columns: ["createdBy"];
isOneToOne: false;
referencedRelation: "user";
referencedColumns: ["id"];
},
{
foreignKeyName: "card_activity_fromListId_list_id_fk";
columns: ["fromListId"];
isOneToOne: false;
referencedRelation: "list";
referencedColumns: ["id"];
},
{
foreignKeyName: "card_activity_labelId_label_id_fk";
columns: ["labelId"];
isOneToOne: false;
referencedRelation: "label";
referencedColumns: ["id"];
},
{
foreignKeyName: "card_activity_toListId_list_id_fk";
columns: ["toListId"];
isOneToOne: false;
referencedRelation: "list";
referencedColumns: ["id"];
},
{
foreignKeyName: "card_activity_workspaceMemberId_workspace_members_id_fk";
columns: ["workspaceMemberId"];
isOneToOne: false;
referencedRelation: "workspace_members";
referencedColumns: ["id"];
},
];
};
card_comments: {
Row: {
cardId: number;
comment: string;
createdAt: string;
createdBy: string;
deletedAt: string | null;
deletedBy: string | null;
id: number;
publicId: string;
updatedAt: string | null;
};
Insert: {
cardId: number;
comment: string;
createdAt?: string;
createdBy: string;
deletedAt?: string | null;
deletedBy?: string | null;
id?: number;
publicId: string;
updatedAt?: string | null;
};
Update: {
cardId?: number;
comment?: string;
createdAt?: string;
createdBy?: string;
deletedAt?: string | null;
deletedBy?: string | null;
id?: number;
publicId?: string;
updatedAt?: string | null;
};
Relationships: [
{
foreignKeyName: "card_comments_cardId_card_id_fk";
columns: ["cardId"];
isOneToOne: false;
referencedRelation: "card";
referencedColumns: ["id"];
},
{
foreignKeyName: "card_comments_createdBy_user_id_fk";
columns: ["createdBy"];
isOneToOne: false;
referencedRelation: "user";
referencedColumns: ["id"];
},
{
foreignKeyName: "card_comments_deletedBy_user_id_fk";
columns: ["deletedBy"];
isOneToOne: false;
referencedRelation: "user";
referencedColumns: ["id"];
},
];
};
import: {
Row: {
createdAt: string;
createdBy: string;
id: number;
publicId: string;
source: Database["public"]["Enums"]["source"];
status: Database["public"]["Enums"]["status"];
};
Insert: {
createdAt?: string;
createdBy: string;
id?: number;
publicId: string;
source: Database["public"]["Enums"]["source"];
status: Database["public"]["Enums"]["status"];
};
Update: {
createdAt?: string;
createdBy?: string;
id?: number;
publicId?: string;
source?: Database["public"]["Enums"]["source"];
status?: Database["public"]["Enums"]["status"];
};
Relationships: [
{
foreignKeyName: "import_createdBy_user_id_fk";
columns: ["createdBy"];
isOneToOne: false;
referencedRelation: "user";
referencedColumns: ["id"];
},
];
};
label: {
Row: {
boardId: number;
colourCode: string | null;
createdAt: string;
createdBy: string;
id: number;
importId: number | null;
name: string;
publicId: string;
updatedAt: string | null;
};
Insert: {
boardId: number;
colourCode?: string | null;
createdAt?: string;
createdBy: string;
id?: number;
importId?: number | null;
name: string;
publicId: string;
updatedAt?: string | null;
};
Update: {
boardId?: number;
colourCode?: string | null;
createdAt?: string;
createdBy?: string;
id?: number;
importId?: number | null;
name?: string;
publicId?: string;
updatedAt?: string | null;
};
Relationships: [
{
foreignKeyName: "label_boardId_board_id_fk";
columns: ["boardId"];
isOneToOne: false;
referencedRelation: "board";
referencedColumns: ["id"];
},
{
foreignKeyName: "label_createdBy_user_id_fk";
columns: ["createdBy"];
isOneToOne: false;
referencedRelation: "user";
referencedColumns: ["id"];
},
{
foreignKeyName: "label_importId_import_id_fk";
columns: ["importId"];
isOneToOne: false;
referencedRelation: "import";
referencedColumns: ["id"];
},
];
};
list: {
Row: {
boardId: number;
createdAt: string;
createdBy: string;
deletedAt: string | null;
deletedBy: string | null;
id: number;
importId: number | null;
index: number;
name: string;
publicId: string;
updatedAt: string | null;
};
Insert: {
boardId: number;
createdAt?: string;
createdBy: string;
deletedAt?: string | null;
deletedBy?: string | null;
id?: number;
importId?: number | null;
index: number;
name: string;
publicId: string;
updatedAt?: string | null;
};
Update: {
boardId?: number;
createdAt?: string;
createdBy?: string;
deletedAt?: string | null;
deletedBy?: string | null;
id?: number;
importId?: number | null;
index?: number;
name?: string;
publicId?: string;
updatedAt?: string | null;
};
Relationships: [
{
foreignKeyName: "list_boardId_board_id_fk";
columns: ["boardId"];
isOneToOne: false;
referencedRelation: "board";
referencedColumns: ["id"];
},
{
foreignKeyName: "list_createdBy_user_id_fk";
columns: ["createdBy"];
isOneToOne: false;
referencedRelation: "user";
referencedColumns: ["id"];
},
{
foreignKeyName: "list_deletedBy_user_id_fk";
columns: ["deletedBy"];
isOneToOne: false;
referencedRelation: "user";
referencedColumns: ["id"];
},
{
foreignKeyName: "list_importId_import_id_fk";
columns: ["importId"];
isOneToOne: false;
referencedRelation: "import";
referencedColumns: ["id"];
},
];
};
user: {
Row: {
email: string;
emailVerified: string | null;
id: string;
image: string | null;
name: string | null;
};
Insert: {
email: string;
emailVerified?: string | null;
id: string;
image?: string | null;
name?: string | null;
};
Update: {
email?: string;
emailVerified?: string | null;
id?: string;
image?: string | null;
name?: string | null;
};
Relationships: [];
};
workspace: {
Row: {
createdAt: string;
createdBy: string;
deletedAt: string | null;
deletedBy: string | null;
id: number;
name: string;
publicId: string;
slug: string;
updatedAt: string | null;
};
Insert: {
createdAt?: string;
createdBy: string;
deletedAt?: string | null;
deletedBy?: string | null;
id?: number;
name: string;
publicId: string;
slug: string;
updatedAt?: string | null;
};
Update: {
createdAt?: string;
createdBy?: string;
deletedAt?: string | null;
deletedBy?: string | null;
id?: number;
name?: string;
publicId?: string;
slug?: string;
updatedAt?: string | null;
};
Relationships: [
{
foreignKeyName: "workspace_createdBy_user_id_fk";
columns: ["createdBy"];
isOneToOne: false;
referencedRelation: "user";
referencedColumns: ["id"];
},
{
foreignKeyName: "workspace_deletedBy_user_id_fk";
columns: ["deletedBy"];
isOneToOne: false;
referencedRelation: "user";
referencedColumns: ["id"];
},
];
};
workspace_members: {
Row: {
createdAt: string;
createdBy: string;
deletedAt: string | null;
deletedBy: string | null;
id: number;
publicId: string;
role: Database["public"]["Enums"]["role"];
status: Database["public"]["Enums"]["member_status"];
updatedAt: string | null;
userId: string;
workspaceId: number;
};
Insert: {
createdAt?: string;
createdBy: string;
deletedAt?: string | null;
deletedBy?: string | null;
id?: number;
publicId: string;
role: Database["public"]["Enums"]["role"];
status?: Database["public"]["Enums"]["member_status"];
updatedAt?: string | null;
userId: string;
workspaceId: number;
};
Update: {
createdAt?: string;
createdBy?: string;
deletedAt?: string | null;
deletedBy?: string | null;
id?: number;
publicId?: string;
role?: Database["public"]["Enums"]["role"];
status?: Database["public"]["Enums"]["member_status"];
updatedAt?: string | null;
userId?: string;
workspaceId?: number;
};
Relationships: [
{
foreignKeyName: "workspace_members_deletedBy_user_id_fk";
columns: ["deletedBy"];
isOneToOne: false;
referencedRelation: "user";
referencedColumns: ["id"];
},
{
foreignKeyName: "workspace_members_userId_user_id_fk";
columns: ["userId"];
isOneToOne: false;
referencedRelation: "user";
referencedColumns: ["id"];
},
{
foreignKeyName: "workspace_members_workspaceId_workspace_id_fk";
columns: ["workspaceId"];
isOneToOne: false;
referencedRelation: "workspace";
referencedColumns: ["id"];
},
];
};
};
Views: {
[_ in never]: never;
};
Functions: {
is_workspace_admin: {
Args: {
user_id: string;
workspace_id: number;
};
Returns: boolean;
};
push_card_index: {
Args: {
list_id: number;
card_index: number;
};
Returns: undefined;
};
reorder_cards: {
Args: {
card_id: number;
current_list_id: number;
new_list_id: number;
current_index: number;
new_index: number;
};
Returns: undefined;
};
reorder_lists: {
Args: {
board_id: number;
list_id: number;
current_index: number;
new_index: number;
};
Returns: undefined;
};
shift_card_index: {
Args: {
list_id: number;
card_index: number;
};
Returns: undefined;
};
shift_list_index: {
Args: {
board_id: number;
list_index: number;
};
Returns: undefined;
};
};
Enums: {
card_activity_type:
| "card.created"
| "card.updated.title"
| "card.updated.description"
| "card.updated.index"
| "card.updated.list"
| "card.updated.label.added"
| "card.updated.label.removed"
| "card.updated.member.added"
| "card.updated.member.removed"
| "card.archived"
| "card.updated.comment.added"
| "card.updated.comment.updated"
| "card.updated.comment.deleted";
member_status: "invited" | "active" | "removed";
role: "admin" | "member" | "guest";
source: "trello";
status: "started" | "success" | "failed";
workspace_invite_status: "pending" | "accepted" | "cancelled";
};
CompositeTypes: {
[_ in never]: never;
};
};
};
type PublicSchema = Database[Extract<keyof Database, "public">];
export type Tables<
PublicTableNameOrOptions extends
| keyof (PublicSchema["Tables"] & PublicSchema["Views"])
| { schema: keyof Database },
TableName extends PublicTableNameOrOptions extends { schema: keyof Database }
? keyof (Database[PublicTableNameOrOptions["schema"]]["Tables"] &
Database[PublicTableNameOrOptions["schema"]]["Views"])
: never = never,
> = PublicTableNameOrOptions extends { schema: keyof Database }
? (Database[PublicTableNameOrOptions["schema"]]["Tables"] &
Database[PublicTableNameOrOptions["schema"]]["Views"])[TableName] extends {
Row: infer R;
}
? R
: never
: PublicTableNameOrOptions extends keyof (PublicSchema["Tables"] &
PublicSchema["Views"])
? (PublicSchema["Tables"] &
PublicSchema["Views"])[PublicTableNameOrOptions] extends {
Row: infer R;
}
? R
: never
: never;
export type TablesInsert<
PublicTableNameOrOptions extends
| keyof PublicSchema["Tables"]
| { schema: keyof Database },
TableName extends PublicTableNameOrOptions extends { schema: keyof Database }
? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"]
: never = never,
> = PublicTableNameOrOptions extends { schema: keyof Database }
? Database[PublicTableNameOrOptions["schema"]]["Tables"][TableName] extends {
Insert: infer I;
}
? I
: never
: PublicTableNameOrOptions extends keyof PublicSchema["Tables"]
? PublicSchema["Tables"][PublicTableNameOrOptions] extends {
Insert: infer I;
}
? I
: never
: never;
export type TablesUpdate<
PublicTableNameOrOptions extends
| keyof PublicSchema["Tables"]
| { schema: keyof Database },
TableName extends PublicTableNameOrOptions extends { schema: keyof Database }
? keyof Database[PublicTableNameOrOptions["schema"]]["Tables"]
: never = never,
> = PublicTableNameOrOptions extends { schema: keyof Database }
? Database[PublicTableNameOrOptions["schema"]]["Tables"][TableName] extends {
Update: infer U;
}
? U
: never
: PublicTableNameOrOptions extends keyof PublicSchema["Tables"]
? PublicSchema["Tables"][PublicTableNameOrOptions] extends {
Update: infer U;
}
? U
: never
: never;
export type Enums<
PublicEnumNameOrOptions extends
| keyof PublicSchema["Enums"]
| { schema: keyof Database },
EnumName extends PublicEnumNameOrOptions extends { schema: keyof Database }
? keyof Database[PublicEnumNameOrOptions["schema"]]["Enums"]
: never = never,
> = PublicEnumNameOrOptions extends { schema: keyof Database }
? Database[PublicEnumNameOrOptions["schema"]]["Enums"][EnumName]
: PublicEnumNameOrOptions extends keyof PublicSchema["Enums"]
? PublicSchema["Enums"][PublicEnumNameOrOptions]
: never;
export type CompositeTypes<
PublicCompositeTypeNameOrOptions extends
| keyof PublicSchema["CompositeTypes"]
| { schema: keyof Database },
CompositeTypeName extends PublicCompositeTypeNameOrOptions extends {
schema: keyof Database;
}
? keyof Database[PublicCompositeTypeNameOrOptions["schema"]]["CompositeTypes"]
: never = never,
> = PublicCompositeTypeNameOrOptions extends { schema: keyof Database }
? Database[PublicCompositeTypeNameOrOptions["schema"]]["CompositeTypes"][CompositeTypeName]
: PublicCompositeTypeNameOrOptions extends keyof PublicSchema["CompositeTypes"]
? PublicSchema["CompositeTypes"][PublicCompositeTypeNameOrOptions]
: never;