feat: monorepo
This commit is contained in:
191
packages/db/src/repository/board.repo.ts
Normal file
191
packages/db/src/repository/board.repo.ts
Normal 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;
|
||||
};
|
||||
426
packages/db/src/repository/card.repo.ts
Normal file
426
packages/db/src/repository/card.repo.ts
Normal 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;
|
||||
};
|
||||
84
packages/db/src/repository/cardActivity.repo.ts
Normal file
84
packages/db/src/repository/cardActivity.repo.ts
Normal 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;
|
||||
};
|
||||
63
packages/db/src/repository/cardComment.repo.ts
Normal file
63
packages/db/src/repository/cardComment.repo.ts
Normal 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;
|
||||
};
|
||||
38
packages/db/src/repository/import.repo.ts
Normal file
38
packages/db/src/repository/import.repo.ts
Normal 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;
|
||||
};
|
||||
90
packages/db/src/repository/label.repo.ts
Normal file
90
packages/db/src/repository/label.repo.ts
Normal 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;
|
||||
};
|
||||
161
packages/db/src/repository/list.repo.ts
Normal file
161
packages/db/src/repository/list.repo.ts
Normal 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;
|
||||
};
|
||||
74
packages/db/src/repository/member.repo.ts
Normal file
74
packages/db/src/repository/member.repo.ts
Normal 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;
|
||||
};
|
||||
42
packages/db/src/repository/user.repo.ts
Normal file
42
packages/db/src/repository/user.repo.ts
Normal 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;
|
||||
};
|
||||
159
packages/db/src/repository/workspace.repo.ts
Normal file
159
packages/db/src/repository/workspace.repo.ts
Normal 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;
|
||||
};
|
||||
Reference in New Issue
Block a user