diff --git a/apps/web/package.json b/apps/web/package.json index 14889ab27..2a74b65e8 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -22,6 +22,9 @@ "@aws-sdk/client-s3": "^3.802.0", "@aws-sdk/lib-storage": "^3.802.0", "@aws-sdk/s3-request-presigner": "^3.812.0", + "@dnd-kit/core": "^6.3.1", + "@dnd-kit/sortable": "^10.0.0", + "@dnd-kit/utilities": "^3.2.2", "@headlessui/react": "^2.2.0", "@hookform/resolvers": "^3.3.4", "@kan/api": "workspace:*", diff --git a/apps/web/src/views/boards/components/BoardsList.tsx b/apps/web/src/views/boards/components/BoardsList.tsx index 0e2c03586..f7b994cb5 100644 --- a/apps/web/src/views/boards/components/BoardsList.tsx +++ b/apps/web/src/views/boards/components/BoardsList.tsx @@ -1,40 +1,123 @@ -import Link from "next/link"; +import type { DragEndEvent } from "@dnd-kit/core"; +import { useRouter } from "next/router"; +import { + closestCenter, + DndContext, + PointerSensor, + useSensor, + useSensors, +} from "@dnd-kit/core"; +import { + arrayMove, + rectSortingStrategy, + SortableContext, +} from "@dnd-kit/sortable"; import { t } from "@lingui/core/macro"; -import { HiOutlineRectangleStack, HiOutlineStar, HiStar } from "react-icons/hi2"; -import { motion } from "framer-motion"; +import { useRef } from "react"; +import { HiOutlineRectangleStack } from "react-icons/hi2"; + import Button from "~/components/Button"; -import PatternedBackground from "~/components/PatternedBackground"; import { Tooltip } from "~/components/Tooltip"; import { usePermissions } from "~/hooks/usePermissions"; import { useModal } from "~/providers/modal"; import { useWorkspace } from "~/providers/workspace"; import { api } from "~/utils/api"; +import { SortableBoardCard } from "./SortableBoardCard"; -export function BoardsList({ isTemplate, archived = false }: { isTemplate?: boolean; archived?: boolean }) { +export function BoardsList({ + isTemplate, + archived = false, +}: { + isTemplate?: boolean; + archived?: boolean; +}) { const { workspace } = useWorkspace(); const { openModal } = useModal(); const { canCreateBoard } = usePermissions(); + const router = useRouter(); const utils = api.useUtils(); + + const queryInput = { + workspacePublicId: workspace.publicId, + type: isTemplate ? ("template" as const) : ("regular" as const), + archived, + }; + const updateBoard = api.board.update.useMutation({ onSuccess: () => { void utils.board.all.invalidate(); }, }); - const { data, isLoading } = api.board.all.useQuery( - { - workspacePublicId: workspace.publicId, - type: isTemplate ? "template" : "regular", - archived: archived, + const reorderBoard = api.board.reorder.useMutation({ + onMutate: ({ boardPublicId, newPosition }) => { + const previousData = utils.board.all.getData(queryInput); + + // Apply the optimistic reorder synchronously (before any await) so it + // batches into the same render as dnd-kit clearing the drag transform. + // Otherwise the card snaps back to its original slot for one frame before + // jumping to the new slot. + utils.board.all.setData(queryInput, (old) => { + if (!old) return old; + + const moved = old.find((b) => b.publicId === boardPublicId); + if (!moved) return old; + + // newPosition is the index within the board's favourite group; map it + // back to an absolute index in the full (favourites-first) list. + const group = old.filter((b) => b.favorite === moved.favorite); + const target = group[newPosition]; + if (!target) return old; + + const oldIndex = old.findIndex((b) => b.publicId === boardPublicId); + const newIndex = old.findIndex((b) => b.publicId === target.publicId); + if (oldIndex === -1 || newIndex === -1) return old; + + return arrayMove(old, oldIndex, newIndex); + }); + + // Cancel in-flight refetches so they can't clobber the optimistic order. + void utils.board.all.cancel(queryInput); + + return { previousData }; + }, + onError: (_err, _vars, context) => { + if (context?.previousData) { + utils.board.all.setData(queryInput, context.previousData); + } }, - { enabled: workspace.publicId ? true : false }, + onSuccess: () => { + // The optimistic order already matches what the server computes, so mark + // the query stale WITHOUT refetching now. Refetching immediately replaces + // the array mid-animation, which makes dnd-kit re-measure from stale + // positions and the cards fly in from a default spot. It refreshes on the + // next natural trigger (focus/remount). + void utils.board.all.invalidate(queryInput, { refetchType: "none" }); + }, + }); + + const { data, isLoading } = api.board.all.useQuery(queryInput, { + enabled: workspace.publicId ? true : false, + }); + + const sensors = useSensors( + useSensor(PointerSensor, { + // Require an 8px drag before activating so plain clicks still navigate. + activationConstraint: { distance: 8 }, + }), ); + // Whether the current pointer interaction became a drag. The browser fires a + // `click` on pointer-release after a drag; `handleOpenBoard` reads this to skip + // navigation for that click. Reset on pointer-down, set in `onDragStart` (which + // only fires once the 8px threshold is passed). + const didDragRef = useRef(false); + const handleToggleFavorite = ( e: React.MouseEvent, boardPublicId: string, - currentFavorite: boolean | undefined + currentFavorite: boolean | undefined, ) => { e.preventDefault(); e.stopPropagation(); @@ -44,6 +127,52 @@ export function BoardsList({ isTemplate, archived = false }: { isTemplate?: bool }); }; + const handlePointerDownCapture = () => { + didDragRef.current = false; + }; + + const handleDragStart = () => { + didDragRef.current = true; + }; + + const handleOpenBoard = ( + e: React.MouseEvent | React.KeyboardEvent, + boardPublicId: string, + ) => { + // Skip the click the browser fires right after a drag. + if (didDragRef.current) return; + + const path = `/${isTemplate ? "templates" : "boards"}/${boardPublicId}`; + + if (e.metaKey || e.ctrlKey) { + window.open(path, "_blank"); + return; + } + + void router.push(path); + }; + + const handleDragEnd = (event: DragEndEvent) => { + const { active, over } = event; + if (!over || active.id === over.id || !data) return; + + const activeBoard = data.find((b) => b.publicId === active.id); + const overBoard = data.find((b) => b.publicId === over.id); + if (!activeBoard || !overBoard) return; + + // Reordering only happens within the same favourite group; cross-group + // moves are handled via the favourite toggle. + if (activeBoard.favorite !== overBoard.favorite) return; + + const group = data.filter((b) => b.favorite === activeBoard.favorite); + const newPosition = group.findIndex((b) => b.publicId === over.id); + if (newPosition === -1) return; + + reorderBoard.mutate({ + boardPublicId: active.id as string, + newPosition, + }); + }; if (isLoading) return ( @@ -60,16 +189,18 @@ export function BoardsList({ isTemplate, archived = false }: { isTemplate?: bool

- {archived ? t`No archived boards` : t`No ${isTemplate ? "templates" : "boards"}`} + {archived + ? t`No archived boards` + : t`No ${isTemplate ? "templates" : "boards"}`}

- {archived ? t`Boards you archive will appear here.` : t`Get started by creating a new ${isTemplate ? "template" : "board"}`} + {archived + ? t`Boards you archive will appear here.` + : t`Get started by creating a new ${isTemplate ? "template" : "board"}`}

-

- {board.name} -

- - - - ))} - + {data?.map((board) => ( + + ))} + + + ); } diff --git a/apps/web/src/views/boards/components/SortableBoardCard.tsx b/apps/web/src/views/boards/components/SortableBoardCard.tsx new file mode 100644 index 000000000..963ddc24d --- /dev/null +++ b/apps/web/src/views/boards/components/SortableBoardCard.tsx @@ -0,0 +1,89 @@ +import type { AnimateLayoutChanges } from "@dnd-kit/sortable"; +import { useSortable } from "@dnd-kit/sortable"; +import { CSS } from "@dnd-kit/utilities"; +import { HiOutlineStar, HiStar } from "react-icons/hi2"; + +import PatternedBackground from "~/components/PatternedBackground"; + +// Disable dnd-kit's layout-change (FLIP) animation. When the list reorders after +// a drop, the optimistic data already puts cards in the right slots; letting +// dnd-kit also FLIP-animate the change makes displaced cards fly in from the +// grid container's corner (its rect measurement ignores grid gap/padding). +const animateLayoutChanges: AnimateLayoutChanges = () => false; + +interface SortableBoardCardProps { + board: { + publicId: string; + name: string; + favorite: boolean; + }; + onOpen: ( + e: React.MouseEvent | React.KeyboardEvent, + boardPublicId: string, + ) => void; + onToggleFavorite: ( + e: React.MouseEvent, + boardPublicId: string, + currentFavorite: boolean | undefined, + ) => void; +} + +export function SortableBoardCard({ + board, + onOpen, + onToggleFavorite, +}: SortableBoardCardProps) { + const { + attributes, + listeners, + setNodeRef, + transform, + transition, + isDragging, + } = useSortable({ id: board.publicId, animateLayoutChanges }); + + const style = { + transform: CSS.Transform.toString(transform), + transition, + opacity: isDragging ? 0.5 : 1, + zIndex: isDragging ? 10 : undefined, + }; + + // Navigation is programmatic (no anchor): an `` initiates the browser's + // native link navigation/drag during a pointer drag, which fires before + // dnd-kit's drag-end and cannot be reliably cancelled. `onOpen` is gated on + // the drag flag in the parent. + return ( +
+
onOpen(e, board.publicId)} + onKeyDown={(e) => { + if (e.key === "Enter" || e.key === " ") onOpen(e, board.publicId); + }} + className="group relative mr-5 flex h-[150px] w-full cursor-pointer items-center justify-center rounded-md border border-dashed border-light-400 bg-light-50 shadow-sm hover:bg-light-200 dark:border-dark-600 dark:bg-dark-50 dark:hover:bg-dark-100" + > + + +

+ {board.name} +

+
+
+ ); +} diff --git a/packages/api/src/routers/board.ts b/packages/api/src/routers/board.ts index 42bf817ab..efc9a6161 100644 --- a/packages/api/src/routers/board.ts +++ b/packages/api/src/routers/board.ts @@ -505,11 +505,14 @@ export const boardRouter = createTRPCRouter({ // Handle favorite toggle separately if (input.favorite !== undefined) { - if (input.favorite) { - await boardRepo.addUserFavorite(ctx.db, userId, board.id); - } else { - await boardRepo.removeUserFavorite(ctx.db, userId, board.id); - } + await boardRepo.setFavourite(ctx.db, { + userId, + boardId: board.id, + isFavourite: input.favorite, + workspaceId: board.workspaceId, + boardType: board.type, + isArchived: board.isArchived, + }); } // Handle other updates (name, slug, visibility) @@ -549,8 +552,71 @@ export const boardRouter = createTRPCRouter({ code: "INTERNAL_SERVER_ERROR", }); + // If the archive status actually changed, move the board to the end of + // the target archive group and compact the group it left (per user). + if ( + input.isArchived !== undefined && + input.isArchived !== board.isArchived + ) { + await boardRepo.reassignPositionsOnArchiveToggle(ctx.db, { + boardId: board.id, + workspaceId: board.workspaceId, + boardType: board.type, + newIsArchived: input.isArchived, + }); + } + return result; }), + reorder: protectedProcedure + .meta({ + openapi: { + method: "PUT", + path: "/boards/{boardPublicId}/reorder", + summary: "Reorder board", + description: + "Reorders a board to a new position within the current user's list", + tags: ["Boards"], + protect: true, + }, + }) + .input( + z.object({ + boardPublicId: z.string().min(12), + newPosition: z.number().int().min(0), + }), + ) + .output(z.object({ success: z.boolean() })) + .mutation(async ({ ctx, input }) => { + const userId = ctx.user?.id; + + if (!userId) + throw new TRPCError({ + message: `User not authenticated`, + code: "UNAUTHORIZED", + }); + + const board = await boardRepo.getWorkspaceAndBoardIdByBoardPublicId( + ctx.db, + input.boardPublicId, + ); + + if (!board) + throw new TRPCError({ + message: `Board with public ID ${input.boardPublicId} not found`, + code: "NOT_FOUND", + }); + + await assertPermission(ctx.db, userId, board.workspaceId, "board:view"); + + await boardRepo.reorder(ctx.db, { + userId, + boardPublicId: input.boardPublicId, + newPosition: input.newPosition, + }); + + return { success: true }; + }), delete: protectedProcedure .meta({ openapi: { diff --git a/packages/api/src/routers/member.ts b/packages/api/src/routers/member.ts index e74ebbac2..6c64d8b3d 100644 --- a/packages/api/src/routers/member.ts +++ b/packages/api/src/routers/member.ts @@ -2,6 +2,7 @@ import { TRPCError } from "@trpc/server"; import { env } from "next-runtime-env"; import { z } from "zod"; +import * as boardRepo from "@kan/db/repository/board.repo"; import * as inviteLinkRepo from "@kan/db/repository/inviteLink.repo"; import * as memberRepo from "@kan/db/repository/member.repo"; import * as permissionRepo from "@kan/db/repository/permission.repo"; @@ -692,6 +693,12 @@ export const memberRouter = createTRPCRouter({ status: "active", }); + // Seed per-user board ordering for every existing board in the workspace. + await boardRepo.createBoardUsersForMember(ctx.db, { + userId: user.id, + workspaceId: invite.workspaceId, + }); + return { success: true, workspacePublicId: workspace.publicId, diff --git a/packages/auth/src/hooks.ts b/packages/auth/src/hooks.ts index dcdc35aa0..79480c64c 100644 --- a/packages/auth/src/hooks.ts +++ b/packages/auth/src/hooks.ts @@ -4,6 +4,7 @@ import { createAuthMiddleware } from "better-auth/api"; import { env } from "next-runtime-env"; import type { dbClient } from "@kan/db/client"; +import * as boardRepo from "@kan/db/repository/board.repo"; import * as memberRepo from "@kan/db/repository/member.repo"; import * as userRepo from "@kan/db/repository/user.repo"; import { notificationClient } from "@kan/email"; @@ -167,6 +168,12 @@ export function createMiddlewareHooks(db: dbClient) { memberId: member.id, userId, }); + + // Seed per-user board ordering for every board in the workspace. + await boardRepo.createBoardUsersForMember(db, { + userId, + workspaceId: member.workspaceId, + }); } } } diff --git a/packages/db/migrations/20260604130224_AddBoardUserTable.sql b/packages/db/migrations/20260604130224_AddBoardUserTable.sql new file mode 100644 index 000000000..ffc988f97 --- /dev/null +++ b/packages/db/migrations/20260604130224_AddBoardUserTable.sql @@ -0,0 +1,48 @@ +CREATE TABLE IF NOT EXISTS "board_user" ( + "userId" uuid NOT NULL, + "boardId" bigint NOT NULL, + "position" integer NOT NULL, + "isFavourite" boolean DEFAULT false NOT NULL, + "createdAt" timestamp DEFAULT now() NOT NULL, + CONSTRAINT "board_user_userId_boardId_pk" PRIMARY KEY("userId","boardId") +); +--> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "board_user" ADD CONSTRAINT "board_user_userId_user_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; +--> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "board_user" ADD CONSTRAINT "board_user_boardId_board_id_fk" FOREIGN KEY ("boardId") REFERENCES "public"."board"("id") ON DELETE cascade ON UPDATE no action; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; +--> statement-breakpoint +CREATE INDEX IF NOT EXISTS "board_user_user_idx" ON "board_user" USING btree ("userId");--> statement-breakpoint +CREATE INDEX IF NOT EXISTS "board_user_board_idx" ON "board_user" USING btree ("boardId");--> statement-breakpoint +-- Seed board_user for every (active member, non-deleted board) pair. Favourites +-- (migrated from user_board_favorites) and non-favourites form independent +-- position sequences per user, board type and archive status, each starting at 0. +INSERT INTO "board_user" ("userId", "boardId", "position", "isFavourite", "createdAt") +SELECT + wm."userId", + b."id", + (ROW_NUMBER() OVER ( + PARTITION BY + wm."userId", + b."type", + b."isArchived", + (CASE WHEN ubf."userId" IS NOT NULL THEN 1 ELSE 0 END) + ORDER BY b."createdAt", b."id" + ) - 1)::integer AS position, + CASE WHEN ubf."userId" IS NOT NULL THEN true ELSE false END AS "isFavourite", + now() +FROM "workspace_members" wm +JOIN "board" b ON b."workspaceId" = wm."workspaceId" AND b."deletedAt" IS NULL +LEFT JOIN "user_board_favorites" ubf + ON ubf."userId" = wm."userId" AND ubf."boardId" = b."id" +WHERE wm."userId" IS NOT NULL + AND wm."deletedAt" IS NULL + AND wm."status" = 'active' +ON CONFLICT ("userId", "boardId") DO NOTHING; \ No newline at end of file diff --git a/packages/db/migrations/20260604130424_DropUserBoardFavorites.sql b/packages/db/migrations/20260604130424_DropUserBoardFavorites.sql new file mode 100644 index 000000000..db563a5d2 --- /dev/null +++ b/packages/db/migrations/20260604130424_DropUserBoardFavorites.sql @@ -0,0 +1 @@ +DROP TABLE "user_board_favorites" CASCADE; \ No newline at end of file diff --git a/packages/db/migrations/meta/20260604130224_snapshot.json b/packages/db/migrations/meta/20260604130224_snapshot.json new file mode 100644 index 000000000..e84eaf350 --- /dev/null +++ b/packages/db/migrations/meta/20260604130224_snapshot.json @@ -0,0 +1,3979 @@ +{ + "id": "24f3d025-b7dc-47cb-bef8-5b7ab296527d", + "prevId": "c8acd64a-f67f-4119-8cf3-d98322744d50", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.account": { + "name": "account", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "accountId": { + "name": "accountId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "providerId": { + "name": "providerId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "accessToken": { + "name": "accessToken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refreshToken": { + "name": "refreshToken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "idToken": { + "name": "idToken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "accessTokenExpiresAt": { + "name": "accessTokenExpiresAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "refreshTokenExpiresAt": { + "name": "refreshTokenExpiresAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "account_userId_user_id_fk": { + "name": "account_userId_user_id_fk", + "tableFrom": "account", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.apiKey": { + "name": "apiKey", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "start": { + "name": "start", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "prefix": { + "name": "prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "refillInterval": { + "name": "refillInterval", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "refillAmount": { + "name": "refillAmount", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "lastRefillAt": { + "name": "lastRefillAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "rateLimitEnabled": { + "name": "rateLimitEnabled", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "rateLimitTimeWindow": { + "name": "rateLimitTimeWindow", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "rateLimitMax": { + "name": "rateLimitMax", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "requestCount": { + "name": "requestCount", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "remaining": { + "name": "remaining", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "lastRequest": { + "name": "lastRequest", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "expiresAt": { + "name": "expiresAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "permissions": { + "name": "permissions", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "apiKey_userId_user_id_fk": { + "name": "apiKey_userId_user_id_fk", + "tableFrom": "apiKey", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.session": { + "name": "session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "expiresAt": { + "name": "expiresAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "ipAddress": { + "name": "ipAddress", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "userAgent": { + "name": "userAgent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "userId": { + "name": "userId", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "session_userId_user_id_fk": { + "name": "session_userId_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "session_token_unique": { + "name": "session_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.verification": { + "name": "verification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expiresAt": { + "name": "expiresAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.board_user": { + "name": "board_user", + "schema": "", + "columns": { + "userId": { + "name": "userId", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "boardId": { + "name": "boardId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "isFavourite": { + "name": "isFavourite", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "board_user_user_idx": { + "name": "board_user_user_idx", + "columns": [ + { + "expression": "userId", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "board_user_board_idx": { + "name": "board_user_board_idx", + "columns": [ + { + "expression": "boardId", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "board_user_userId_user_id_fk": { + "name": "board_user_userId_user_id_fk", + "tableFrom": "board_user", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "board_user_boardId_board_id_fk": { + "name": "board_user_boardId_board_id_fk", + "tableFrom": "board_user", + "tableTo": "board", + "columnsFrom": [ + "boardId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "board_user_userId_boardId_pk": { + "name": "board_user_userId_boardId_pk", + "columns": [ + "userId", + "boardId" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.board": { + "name": "board", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "slug": { + "name": "slug", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedAt": { + "name": "deletedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedBy": { + "name": "deletedBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "importId": { + "name": "importId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "workspaceId": { + "name": "workspaceId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "visibility": { + "name": "visibility", + "type": "board_visibility", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'private'" + }, + "type": { + "name": "type", + "type": "board_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'regular'" + }, + "isArchived": { + "name": "isArchived", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "sourceBoardId": { + "name": "sourceBoardId", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "board_is_archived_idx": { + "name": "board_is_archived_idx", + "columns": [ + { + "expression": "isArchived", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "board_visibility_idx": { + "name": "board_visibility_idx", + "columns": [ + { + "expression": "visibility", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "board_type_idx": { + "name": "board_type_idx", + "columns": [ + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "board_source_idx": { + "name": "board_source_idx", + "columns": [ + { + "expression": "sourceBoardId", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "unique_slug_per_workspace": { + "name": "unique_slug_per_workspace", + "columns": [ + { + "expression": "workspaceId", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"board\".\"deletedAt\" IS NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "board_createdBy_user_id_fk": { + "name": "board_createdBy_user_id_fk", + "tableFrom": "board", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "board_deletedBy_user_id_fk": { + "name": "board_deletedBy_user_id_fk", + "tableFrom": "board", + "tableTo": "user", + "columnsFrom": [ + "deletedBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "board_importId_import_id_fk": { + "name": "board_importId_import_id_fk", + "tableFrom": "board", + "tableTo": "import", + "columnsFrom": [ + "importId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "board_workspaceId_workspace_id_fk": { + "name": "board_workspaceId_workspace_id_fk", + "tableFrom": "board", + "tableTo": "workspace", + "columnsFrom": [ + "workspaceId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "board_publicId_unique": { + "name": "board_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.user_board_favorites": { + "name": "user_board_favorites", + "schema": "", + "columns": { + "userId": { + "name": "userId", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "boardId": { + "name": "boardId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "user_board_favorite_user_idx": { + "name": "user_board_favorite_user_idx", + "columns": [ + { + "expression": "userId", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "user_board_favorite_board_idx": { + "name": "user_board_favorite_board_idx", + "columns": [ + { + "expression": "boardId", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_board_favorites_userId_user_id_fk": { + "name": "user_board_favorites_userId_user_id_fk", + "tableFrom": "user_board_favorites", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_board_favorites_boardId_board_id_fk": { + "name": "user_board_favorites_boardId_board_id_fk", + "tableFrom": "user_board_favorites", + "tableTo": "board", + "columnsFrom": [ + "boardId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_board_favorites_userId_boardId_pk": { + "name": "user_board_favorites_userId_boardId_pk", + "columns": [ + "userId", + "boardId" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.card_activity": { + "name": "card_activity", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "card_activity_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "cardId": { + "name": "cardId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "fromIndex": { + "name": "fromIndex", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "toIndex": { + "name": "toIndex", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "fromListId": { + "name": "fromListId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "toListId": { + "name": "toListId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "labelId": { + "name": "labelId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "workspaceMemberId": { + "name": "workspaceMemberId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "fromTitle": { + "name": "fromTitle", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "toTitle": { + "name": "toTitle", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "fromDescription": { + "name": "fromDescription", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "toDescription": { + "name": "toDescription", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "commentId": { + "name": "commentId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "fromComment": { + "name": "fromComment", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "toComment": { + "name": "toComment", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "fromDueDate": { + "name": "fromDueDate", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "toDueDate": { + "name": "toDueDate", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "sourceBoardId": { + "name": "sourceBoardId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "attachmentId": { + "name": "attachmentId", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "card_activity_cardId_card_id_fk": { + "name": "card_activity_cardId_card_id_fk", + "tableFrom": "card_activity", + "tableTo": "card", + "columnsFrom": [ + "cardId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "card_activity_fromListId_list_id_fk": { + "name": "card_activity_fromListId_list_id_fk", + "tableFrom": "card_activity", + "tableTo": "list", + "columnsFrom": [ + "fromListId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "card_activity_toListId_list_id_fk": { + "name": "card_activity_toListId_list_id_fk", + "tableFrom": "card_activity", + "tableTo": "list", + "columnsFrom": [ + "toListId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "card_activity_labelId_label_id_fk": { + "name": "card_activity_labelId_label_id_fk", + "tableFrom": "card_activity", + "tableTo": "label", + "columnsFrom": [ + "labelId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "card_activity_workspaceMemberId_workspace_members_id_fk": { + "name": "card_activity_workspaceMemberId_workspace_members_id_fk", + "tableFrom": "card_activity", + "tableTo": "workspace_members", + "columnsFrom": [ + "workspaceMemberId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "card_activity_createdBy_user_id_fk": { + "name": "card_activity_createdBy_user_id_fk", + "tableFrom": "card_activity", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "card_activity_commentId_card_comments_id_fk": { + "name": "card_activity_commentId_card_comments_id_fk", + "tableFrom": "card_activity", + "tableTo": "card_comments", + "columnsFrom": [ + "commentId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "card_activity_sourceBoardId_board_id_fk": { + "name": "card_activity_sourceBoardId_board_id_fk", + "tableFrom": "card_activity", + "tableTo": "board", + "columnsFrom": [ + "sourceBoardId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "card_activity_attachmentId_card_attachment_id_fk": { + "name": "card_activity_attachmentId_card_attachment_id_fk", + "tableFrom": "card_activity", + "tableTo": "card_attachment", + "columnsFrom": [ + "attachmentId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "card_activity_publicId_unique": { + "name": "card_activity_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.card_attachment": { + "name": "card_attachment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "cardId": { + "name": "cardId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "filename": { + "name": "filename", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "originalFilename": { + "name": "originalFilename", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "contentType": { + "name": "contentType", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "size": { + "name": "size", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "s3Key": { + "name": "s3Key", + "type": "varchar(500)", + "primaryKey": false, + "notNull": true + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "deletedAt": { + "name": "deletedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "card_attachment_cardId_card_id_fk": { + "name": "card_attachment_cardId_card_id_fk", + "tableFrom": "card_attachment", + "tableTo": "card", + "columnsFrom": [ + "cardId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "card_attachment_createdBy_user_id_fk": { + "name": "card_attachment_createdBy_user_id_fk", + "tableFrom": "card_attachment", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "card_attachment_publicId_unique": { + "name": "card_attachment_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public._card_workspace_members": { + "name": "_card_workspace_members", + "schema": "", + "columns": { + "cardId": { + "name": "cardId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "workspaceMemberId": { + "name": "workspaceMemberId", + "type": "bigint", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "_card_workspace_members_cardId_card_id_fk": { + "name": "_card_workspace_members_cardId_card_id_fk", + "tableFrom": "_card_workspace_members", + "tableTo": "card", + "columnsFrom": [ + "cardId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "_card_workspace_members_workspaceMemberId_workspace_members_id_fk": { + "name": "_card_workspace_members_workspaceMemberId_workspace_members_id_fk", + "tableFrom": "_card_workspace_members", + "tableTo": "workspace_members", + "columnsFrom": [ + "workspaceMemberId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "_card_workspace_members_cardId_workspaceMemberId_pk": { + "name": "_card_workspace_members_cardId_workspaceMemberId_pk", + "columns": [ + "cardId", + "workspaceMemberId" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.card": { + "name": "card", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "index": { + "name": "index", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedAt": { + "name": "deletedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedBy": { + "name": "deletedBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "listId": { + "name": "listId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "importId": { + "name": "importId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "dueDate": { + "name": "dueDate", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "card_createdBy_user_id_fk": { + "name": "card_createdBy_user_id_fk", + "tableFrom": "card", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "card_deletedBy_user_id_fk": { + "name": "card_deletedBy_user_id_fk", + "tableFrom": "card", + "tableTo": "user", + "columnsFrom": [ + "deletedBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "card_listId_list_id_fk": { + "name": "card_listId_list_id_fk", + "tableFrom": "card", + "tableTo": "list", + "columnsFrom": [ + "listId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "card_importId_import_id_fk": { + "name": "card_importId_import_id_fk", + "tableFrom": "card", + "tableTo": "import", + "columnsFrom": [ + "importId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "card_publicId_unique": { + "name": "card_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public._card_labels": { + "name": "_card_labels", + "schema": "", + "columns": { + "cardId": { + "name": "cardId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "labelId": { + "name": "labelId", + "type": "bigint", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "_card_labels_cardId_card_id_fk": { + "name": "_card_labels_cardId_card_id_fk", + "tableFrom": "_card_labels", + "tableTo": "card", + "columnsFrom": [ + "cardId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "_card_labels_labelId_label_id_fk": { + "name": "_card_labels_labelId_label_id_fk", + "tableFrom": "_card_labels", + "tableTo": "label", + "columnsFrom": [ + "labelId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "_card_labels_cardId_labelId_pk": { + "name": "_card_labels_cardId_labelId_pk", + "columns": [ + "cardId", + "labelId" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.card_comments": { + "name": "card_comments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "comment": { + "name": "comment", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "cardId": { + "name": "cardId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedAt": { + "name": "deletedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedBy": { + "name": "deletedBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "card_comments_cardId_card_id_fk": { + "name": "card_comments_cardId_card_id_fk", + "tableFrom": "card_comments", + "tableTo": "card", + "columnsFrom": [ + "cardId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "card_comments_createdBy_user_id_fk": { + "name": "card_comments_createdBy_user_id_fk", + "tableFrom": "card_comments", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "card_comments_deletedBy_user_id_fk": { + "name": "card_comments_deletedBy_user_id_fk", + "tableFrom": "card_comments", + "tableTo": "user", + "columnsFrom": [ + "deletedBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "card_comments_publicId_unique": { + "name": "card_comments_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.card_checklist_item": { + "name": "card_checklist_item", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(500)", + "primaryKey": false, + "notNull": true + }, + "completed": { + "name": "completed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "index": { + "name": "index", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "checklistId": { + "name": "checklistId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedAt": { + "name": "deletedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedBy": { + "name": "deletedBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "card_checklist_item_checklistId_card_checklist_id_fk": { + "name": "card_checklist_item_checklistId_card_checklist_id_fk", + "tableFrom": "card_checklist_item", + "tableTo": "card_checklist", + "columnsFrom": [ + "checklistId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "card_checklist_item_createdBy_user_id_fk": { + "name": "card_checklist_item_createdBy_user_id_fk", + "tableFrom": "card_checklist_item", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "card_checklist_item_deletedBy_user_id_fk": { + "name": "card_checklist_item_deletedBy_user_id_fk", + "tableFrom": "card_checklist_item", + "tableTo": "user", + "columnsFrom": [ + "deletedBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "card_checklist_item_publicId_unique": { + "name": "card_checklist_item_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.card_checklist": { + "name": "card_checklist", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "index": { + "name": "index", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "cardId": { + "name": "cardId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedAt": { + "name": "deletedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedBy": { + "name": "deletedBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "card_checklist_cardId_card_id_fk": { + "name": "card_checklist_cardId_card_id_fk", + "tableFrom": "card_checklist", + "tableTo": "card", + "columnsFrom": [ + "cardId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "card_checklist_createdBy_user_id_fk": { + "name": "card_checklist_createdBy_user_id_fk", + "tableFrom": "card_checklist", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "card_checklist_deletedBy_user_id_fk": { + "name": "card_checklist_deletedBy_user_id_fk", + "tableFrom": "card_checklist", + "tableTo": "user", + "columnsFrom": [ + "deletedBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "card_checklist_publicId_unique": { + "name": "card_checklist_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.feedback": { + "name": "feedback", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "feedback": { + "name": "feedback", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reviewed": { + "name": "reviewed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "feedback_createdBy_user_id_fk": { + "name": "feedback_createdBy_user_id_fk", + "tableFrom": "feedback", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.import": { + "name": "import", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "source", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "import_createdBy_user_id_fk": { + "name": "import_createdBy_user_id_fk", + "tableFrom": "import", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "import_publicId_unique": { + "name": "import_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.label": { + "name": "label", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "colourCode": { + "name": "colourCode", + "type": "varchar(12)", + "primaryKey": false, + "notNull": false + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "boardId": { + "name": "boardId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "importId": { + "name": "importId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "deletedAt": { + "name": "deletedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedBy": { + "name": "deletedBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "label_createdBy_user_id_fk": { + "name": "label_createdBy_user_id_fk", + "tableFrom": "label", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "label_boardId_board_id_fk": { + "name": "label_boardId_board_id_fk", + "tableFrom": "label", + "tableTo": "board", + "columnsFrom": [ + "boardId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "label_importId_import_id_fk": { + "name": "label_importId_import_id_fk", + "tableFrom": "label", + "tableTo": "import", + "columnsFrom": [ + "importId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "label_deletedBy_user_id_fk": { + "name": "label_deletedBy_user_id_fk", + "tableFrom": "label", + "tableTo": "user", + "columnsFrom": [ + "deletedBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "label_publicId_unique": { + "name": "label_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.list": { + "name": "list", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "index": { + "name": "index", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedAt": { + "name": "deletedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedBy": { + "name": "deletedBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "boardId": { + "name": "boardId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "importId": { + "name": "importId", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "list_createdBy_user_id_fk": { + "name": "list_createdBy_user_id_fk", + "tableFrom": "list", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "list_deletedBy_user_id_fk": { + "name": "list_deletedBy_user_id_fk", + "tableFrom": "list", + "tableTo": "user", + "columnsFrom": [ + "deletedBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "list_boardId_board_id_fk": { + "name": "list_boardId_board_id_fk", + "tableFrom": "list", + "tableTo": "board", + "columnsFrom": [ + "boardId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "list_importId_import_id_fk": { + "name": "list_importId_import_id_fk", + "tableFrom": "list", + "tableTo": "import", + "columnsFrom": [ + "importId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "list_publicId_unique": { + "name": "list_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuid_generate_v4()" + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "emailVerified": { + "name": "emailVerified", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "image": { + "name": "image", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "stripeCustomerId": { + "name": "stripeCustomerId", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_email_unique": { + "name": "user_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.integration": { + "name": "integration", + "schema": "", + "columns": { + "provider": { + "name": "provider", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "accessToken": { + "name": "accessToken", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "refreshToken": { + "name": "refreshToken", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "expiresAt": { + "name": "expiresAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "integration_userId_user_id_fk": { + "name": "integration_userId_user_id_fk", + "tableFrom": "integration", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "integration_pkey": { + "name": "integration_pkey", + "columns": [ + "userId", + "provider" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.workspace_slug_checks": { + "name": "workspace_slug_checks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "available": { + "name": "available", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "reserved": { + "name": "reserved", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "workspaceId": { + "name": "workspaceId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "workspace_slug_checks_workspaceId_workspace_id_fk": { + "name": "workspace_slug_checks_workspaceId_workspace_id_fk", + "tableFrom": "workspace_slug_checks", + "tableTo": "workspace", + "columnsFrom": [ + "workspaceId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "workspace_slug_checks_createdBy_user_id_fk": { + "name": "workspace_slug_checks_createdBy_user_id_fk", + "tableFrom": "workspace_slug_checks", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.workspace_slugs": { + "name": "workspace_slugs", + "schema": "", + "columns": { + "slug": { + "name": "slug", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "slug_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "workspace_slugs_slug_unique": { + "name": "workspace_slugs_slug_unique", + "nullsNotDistinct": false, + "columns": [ + "slug" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspace_members": { + "name": "workspace_members", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "workspaceId": { + "name": "workspaceId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedAt": { + "name": "deletedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedBy": { + "name": "deletedBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "role": { + "name": "role", + "type": "role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "roleId": { + "name": "roleId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "member_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'invited'" + } + }, + "indexes": {}, + "foreignKeys": { + "workspace_members_userId_user_id_fk": { + "name": "workspace_members_userId_user_id_fk", + "tableFrom": "workspace_members", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "workspace_members_workspaceId_workspace_id_fk": { + "name": "workspace_members_workspaceId_workspace_id_fk", + "tableFrom": "workspace_members", + "tableTo": "workspace", + "columnsFrom": [ + "workspaceId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "workspace_members_deletedBy_user_id_fk": { + "name": "workspace_members_deletedBy_user_id_fk", + "tableFrom": "workspace_members", + "tableTo": "user", + "columnsFrom": [ + "deletedBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "workspace_members_roleId_workspace_roles_id_fk": { + "name": "workspace_members_roleId_workspace_roles_id_fk", + "tableFrom": "workspace_members", + "tableTo": "workspace_roles", + "columnsFrom": [ + "roleId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "workspace_members_publicId_unique": { + "name": "workspace_members_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.workspace": { + "name": "workspace", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "slug": { + "name": "slug", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "plan": { + "name": "plan", + "type": "workspace_plan", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'free'" + }, + "showEmailsToMembers": { + "name": "showEmailsToMembers", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "weekStartDay": { + "name": "weekStartDay", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedAt": { + "name": "deletedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedBy": { + "name": "deletedBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "workspace_createdBy_user_id_fk": { + "name": "workspace_createdBy_user_id_fk", + "tableFrom": "workspace", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "workspace_deletedBy_user_id_fk": { + "name": "workspace_deletedBy_user_id_fk", + "tableFrom": "workspace", + "tableTo": "user", + "columnsFrom": [ + "deletedBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "workspace_publicId_unique": { + "name": "workspace_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + }, + "workspace_slug_unique": { + "name": "workspace_slug_unique", + "nullsNotDistinct": false, + "columns": [ + "slug" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.subscription": { + "name": "subscription", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "plan": { + "name": "plan", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "referenceId": { + "name": "referenceId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": false + }, + "stripeCustomerId": { + "name": "stripeCustomerId", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "stripeSubscriptionId": { + "name": "stripeSubscriptionId", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "periodStart": { + "name": "periodStart", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "periodEnd": { + "name": "periodEnd", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "cancelAtPeriodEnd": { + "name": "cancelAtPeriodEnd", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "seats": { + "name": "seats", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "unlimitedSeats": { + "name": "unlimitedSeats", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "trialStart": { + "name": "trialStart", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "trialEnd": { + "name": "trialEnd", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "subscription_referenceId_workspace_publicId_fk": { + "name": "subscription_referenceId_workspace_publicId_fk", + "tableFrom": "subscription", + "tableTo": "workspace", + "columnsFrom": [ + "referenceId" + ], + "columnsTo": [ + "publicId" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.workspace_invite_links": { + "name": "workspace_invite_links", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "workspaceId": { + "name": "workspaceId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "code": { + "name": "code", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "invite_link_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "expiresAt": { + "name": "expiresAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updatedBy": { + "name": "updatedBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "workspace_invite_links_workspaceId_workspace_id_fk": { + "name": "workspace_invite_links_workspaceId_workspace_id_fk", + "tableFrom": "workspace_invite_links", + "tableTo": "workspace", + "columnsFrom": [ + "workspaceId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "workspace_invite_links_createdBy_user_id_fk": { + "name": "workspace_invite_links_createdBy_user_id_fk", + "tableFrom": "workspace_invite_links", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "workspace_invite_links_updatedBy_user_id_fk": { + "name": "workspace_invite_links_updatedBy_user_id_fk", + "tableFrom": "workspace_invite_links", + "tableTo": "user", + "columnsFrom": [ + "updatedBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "workspace_invite_links_publicId_unique": { + "name": "workspace_invite_links_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + }, + "workspace_invite_links_code_unique": { + "name": "workspace_invite_links_code_unique", + "nullsNotDistinct": false, + "columns": [ + "code" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.workspace_member_permissions": { + "name": "workspace_member_permissions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "workspaceMemberId": { + "name": "workspaceMemberId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "permission": { + "name": "permission", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "granted": { + "name": "granted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "unique_member_permission": { + "name": "unique_member_permission", + "columns": [ + { + "expression": "workspaceMemberId", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "permission", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "permission_member_idx": { + "name": "permission_member_idx", + "columns": [ + { + "expression": "workspaceMemberId", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.workspace_role_permissions": { + "name": "workspace_role_permissions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "workspaceRoleId": { + "name": "workspaceRoleId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "permission": { + "name": "permission", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "granted": { + "name": "granted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "unique_role_permission": { + "name": "unique_role_permission", + "columns": [ + { + "expression": "workspaceRoleId", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "permission", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "role_permissions_role_idx": { + "name": "role_permissions_role_idx", + "columns": [ + { + "expression": "workspaceRoleId", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspace_role_permissions_workspaceRoleId_workspace_roles_id_fk": { + "name": "workspace_role_permissions_workspaceRoleId_workspace_roles_id_fk", + "tableFrom": "workspace_role_permissions", + "tableTo": "workspace_roles", + "columnsFrom": [ + "workspaceRoleId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.workspace_roles": { + "name": "workspace_roles", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "workspaceId": { + "name": "workspaceId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "hierarchyLevel": { + "name": "hierarchyLevel", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "isSystem": { + "name": "isSystem", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "unique_role_per_workspace": { + "name": "unique_role_per_workspace", + "columns": [ + { + "expression": "workspaceId", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_roles_workspace_idx": { + "name": "workspace_roles_workspace_idx", + "columns": [ + { + "expression": "workspaceId", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspace_roles_workspaceId_workspace_id_fk": { + "name": "workspace_roles_workspaceId_workspace_id_fk", + "tableFrom": "workspace_roles", + "tableTo": "workspace", + "columnsFrom": [ + "workspaceId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "workspace_roles_publicId_unique": { + "name": "workspace_roles_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.notification": { + "name": "notification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "notification_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "cardId": { + "name": "cardId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "commentId": { + "name": "commentId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "workspaceId": { + "name": "workspaceId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "readAt": { + "name": "readAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "deletedAt": { + "name": "deletedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "notification_user_deleted_idx": { + "name": "notification_user_deleted_idx", + "columns": [ + { + "expression": "userId", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "deletedAt", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notification_user_read_deleted_idx": { + "name": "notification_user_read_deleted_idx", + "columns": [ + { + "expression": "userId", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "readAt", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "deletedAt", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notification_user_type_card_idx": { + "name": "notification_user_type_card_idx", + "columns": [ + { + "expression": "userId", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "cardId", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notification_user_type_workspace_idx": { + "name": "notification_user_type_workspace_idx", + "columns": [ + { + "expression": "userId", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "workspaceId", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notification_user_created_idx": { + "name": "notification_user_created_idx", + "columns": [ + { + "expression": "userId", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "createdAt", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "notification_userId_user_id_fk": { + "name": "notification_userId_user_id_fk", + "tableFrom": "notification", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notification_cardId_card_id_fk": { + "name": "notification_cardId_card_id_fk", + "tableFrom": "notification", + "tableTo": "card", + "columnsFrom": [ + "cardId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notification_commentId_card_comments_id_fk": { + "name": "notification_commentId_card_comments_id_fk", + "tableFrom": "notification", + "tableTo": "card_comments", + "columnsFrom": [ + "commentId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notification_workspaceId_workspace_id_fk": { + "name": "notification_workspaceId_workspace_id_fk", + "tableFrom": "notification", + "tableTo": "workspace", + "columnsFrom": [ + "workspaceId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "notification_publicId_unique": { + "name": "notification_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.workspace_webhooks": { + "name": "workspace_webhooks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "workspaceId": { + "name": "workspaceId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "varchar(2048)", + "primaryKey": false, + "notNull": true + }, + "secret": { + "name": "secret", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "events": { + "name": "events", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "workspace_webhooks_workspace_idx": { + "name": "workspace_webhooks_workspace_idx", + "columns": [ + { + "expression": "workspaceId", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspace_webhooks_workspaceId_workspace_id_fk": { + "name": "workspace_webhooks_workspaceId_workspace_id_fk", + "tableFrom": "workspace_webhooks", + "tableTo": "workspace", + "columnsFrom": [ + "workspaceId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "workspace_webhooks_createdBy_user_id_fk": { + "name": "workspace_webhooks_createdBy_user_id_fk", + "tableFrom": "workspace_webhooks", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "workspace_webhooks_publicId_unique": { + "name": "workspace_webhooks_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + } + }, + "enums": { + "public.board_type": { + "name": "board_type", + "schema": "public", + "values": [ + "regular", + "template" + ] + }, + "public.board_visibility": { + "name": "board_visibility", + "schema": "public", + "values": [ + "private", + "public" + ] + }, + "public.card_activity_type": { + "name": "card_activity_type", + "schema": "public", + "values": [ + "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.updated.checklist.added", + "card.updated.checklist.renamed", + "card.updated.checklist.deleted", + "card.updated.checklist.item.added", + "card.updated.checklist.item.updated", + "card.updated.checklist.item.completed", + "card.updated.checklist.item.uncompleted", + "card.updated.checklist.item.deleted", + "card.updated.attachment.added", + "card.updated.attachment.removed", + "card.updated.dueDate.added", + "card.updated.dueDate.updated", + "card.updated.dueDate.removed", + "card.archived" + ] + }, + "public.source": { + "name": "source", + "schema": "public", + "values": [ + "trello", + "github" + ] + }, + "public.status": { + "name": "status", + "schema": "public", + "values": [ + "started", + "success", + "failed" + ] + }, + "public.role": { + "name": "role", + "schema": "public", + "values": [ + "admin", + "member", + "guest" + ] + }, + "public.member_status": { + "name": "member_status", + "schema": "public", + "values": [ + "invited", + "active", + "removed", + "paused" + ] + }, + "public.slug_type": { + "name": "slug_type", + "schema": "public", + "values": [ + "reserved", + "premium" + ] + }, + "public.workspace_plan": { + "name": "workspace_plan", + "schema": "public", + "values": [ + "free", + "pro", + "enterprise" + ] + }, + "public.invite_link_status": { + "name": "invite_link_status", + "schema": "public", + "values": [ + "active", + "inactive" + ] + }, + "public.notification_type": { + "name": "notification_type", + "schema": "public", + "values": [ + "mention", + "workspace.member.added", + "workspace.member.removed", + "workspace.role.changed" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/packages/db/migrations/meta/20260604130424_snapshot.json b/packages/db/migrations/meta/20260604130424_snapshot.json new file mode 100644 index 000000000..20d0fc16c --- /dev/null +++ b/packages/db/migrations/meta/20260604130424_snapshot.json @@ -0,0 +1,3881 @@ +{ + "id": "12aeac70-3129-456c-8429-5da5162e4653", + "prevId": "24f3d025-b7dc-47cb-bef8-5b7ab296527d", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.account": { + "name": "account", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "accountId": { + "name": "accountId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "providerId": { + "name": "providerId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "accessToken": { + "name": "accessToken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refreshToken": { + "name": "refreshToken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "idToken": { + "name": "idToken", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "accessTokenExpiresAt": { + "name": "accessTokenExpiresAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "refreshTokenExpiresAt": { + "name": "refreshTokenExpiresAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "account_userId_user_id_fk": { + "name": "account_userId_user_id_fk", + "tableFrom": "account", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.apiKey": { + "name": "apiKey", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "start": { + "name": "start", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "prefix": { + "name": "prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "refillInterval": { + "name": "refillInterval", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "refillAmount": { + "name": "refillAmount", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "lastRefillAt": { + "name": "lastRefillAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "rateLimitEnabled": { + "name": "rateLimitEnabled", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "rateLimitTimeWindow": { + "name": "rateLimitTimeWindow", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "rateLimitMax": { + "name": "rateLimitMax", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "requestCount": { + "name": "requestCount", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "remaining": { + "name": "remaining", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "lastRequest": { + "name": "lastRequest", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "expiresAt": { + "name": "expiresAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "permissions": { + "name": "permissions", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "apiKey_userId_user_id_fk": { + "name": "apiKey_userId_user_id_fk", + "tableFrom": "apiKey", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.session": { + "name": "session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "expiresAt": { + "name": "expiresAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "ipAddress": { + "name": "ipAddress", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "userAgent": { + "name": "userAgent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "userId": { + "name": "userId", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "session_userId_user_id_fk": { + "name": "session_userId_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "session_token_unique": { + "name": "session_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.verification": { + "name": "verification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expiresAt": { + "name": "expiresAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.board_user": { + "name": "board_user", + "schema": "", + "columns": { + "userId": { + "name": "userId", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "boardId": { + "name": "boardId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "isFavourite": { + "name": "isFavourite", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "board_user_user_idx": { + "name": "board_user_user_idx", + "columns": [ + { + "expression": "userId", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "board_user_board_idx": { + "name": "board_user_board_idx", + "columns": [ + { + "expression": "boardId", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "board_user_userId_user_id_fk": { + "name": "board_user_userId_user_id_fk", + "tableFrom": "board_user", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "board_user_boardId_board_id_fk": { + "name": "board_user_boardId_board_id_fk", + "tableFrom": "board_user", + "tableTo": "board", + "columnsFrom": [ + "boardId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "board_user_userId_boardId_pk": { + "name": "board_user_userId_boardId_pk", + "columns": [ + "userId", + "boardId" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.board": { + "name": "board", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "slug": { + "name": "slug", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedAt": { + "name": "deletedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedBy": { + "name": "deletedBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "importId": { + "name": "importId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "workspaceId": { + "name": "workspaceId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "visibility": { + "name": "visibility", + "type": "board_visibility", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'private'" + }, + "type": { + "name": "type", + "type": "board_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'regular'" + }, + "isArchived": { + "name": "isArchived", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "sourceBoardId": { + "name": "sourceBoardId", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "board_is_archived_idx": { + "name": "board_is_archived_idx", + "columns": [ + { + "expression": "isArchived", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "board_visibility_idx": { + "name": "board_visibility_idx", + "columns": [ + { + "expression": "visibility", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "board_type_idx": { + "name": "board_type_idx", + "columns": [ + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "board_source_idx": { + "name": "board_source_idx", + "columns": [ + { + "expression": "sourceBoardId", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "unique_slug_per_workspace": { + "name": "unique_slug_per_workspace", + "columns": [ + { + "expression": "workspaceId", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"board\".\"deletedAt\" IS NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "board_createdBy_user_id_fk": { + "name": "board_createdBy_user_id_fk", + "tableFrom": "board", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "board_deletedBy_user_id_fk": { + "name": "board_deletedBy_user_id_fk", + "tableFrom": "board", + "tableTo": "user", + "columnsFrom": [ + "deletedBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "board_importId_import_id_fk": { + "name": "board_importId_import_id_fk", + "tableFrom": "board", + "tableTo": "import", + "columnsFrom": [ + "importId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "board_workspaceId_workspace_id_fk": { + "name": "board_workspaceId_workspace_id_fk", + "tableFrom": "board", + "tableTo": "workspace", + "columnsFrom": [ + "workspaceId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "board_publicId_unique": { + "name": "board_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.card_activity": { + "name": "card_activity", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "card_activity_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "cardId": { + "name": "cardId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "fromIndex": { + "name": "fromIndex", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "toIndex": { + "name": "toIndex", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "fromListId": { + "name": "fromListId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "toListId": { + "name": "toListId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "labelId": { + "name": "labelId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "workspaceMemberId": { + "name": "workspaceMemberId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "fromTitle": { + "name": "fromTitle", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "toTitle": { + "name": "toTitle", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "fromDescription": { + "name": "fromDescription", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "toDescription": { + "name": "toDescription", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "commentId": { + "name": "commentId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "fromComment": { + "name": "fromComment", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "toComment": { + "name": "toComment", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "fromDueDate": { + "name": "fromDueDate", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "toDueDate": { + "name": "toDueDate", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "sourceBoardId": { + "name": "sourceBoardId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "attachmentId": { + "name": "attachmentId", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "card_activity_cardId_card_id_fk": { + "name": "card_activity_cardId_card_id_fk", + "tableFrom": "card_activity", + "tableTo": "card", + "columnsFrom": [ + "cardId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "card_activity_fromListId_list_id_fk": { + "name": "card_activity_fromListId_list_id_fk", + "tableFrom": "card_activity", + "tableTo": "list", + "columnsFrom": [ + "fromListId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "card_activity_toListId_list_id_fk": { + "name": "card_activity_toListId_list_id_fk", + "tableFrom": "card_activity", + "tableTo": "list", + "columnsFrom": [ + "toListId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "card_activity_labelId_label_id_fk": { + "name": "card_activity_labelId_label_id_fk", + "tableFrom": "card_activity", + "tableTo": "label", + "columnsFrom": [ + "labelId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "card_activity_workspaceMemberId_workspace_members_id_fk": { + "name": "card_activity_workspaceMemberId_workspace_members_id_fk", + "tableFrom": "card_activity", + "tableTo": "workspace_members", + "columnsFrom": [ + "workspaceMemberId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "card_activity_createdBy_user_id_fk": { + "name": "card_activity_createdBy_user_id_fk", + "tableFrom": "card_activity", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "card_activity_commentId_card_comments_id_fk": { + "name": "card_activity_commentId_card_comments_id_fk", + "tableFrom": "card_activity", + "tableTo": "card_comments", + "columnsFrom": [ + "commentId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "card_activity_sourceBoardId_board_id_fk": { + "name": "card_activity_sourceBoardId_board_id_fk", + "tableFrom": "card_activity", + "tableTo": "board", + "columnsFrom": [ + "sourceBoardId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "card_activity_attachmentId_card_attachment_id_fk": { + "name": "card_activity_attachmentId_card_attachment_id_fk", + "tableFrom": "card_activity", + "tableTo": "card_attachment", + "columnsFrom": [ + "attachmentId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "card_activity_publicId_unique": { + "name": "card_activity_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.card_attachment": { + "name": "card_attachment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "cardId": { + "name": "cardId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "filename": { + "name": "filename", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "originalFilename": { + "name": "originalFilename", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "contentType": { + "name": "contentType", + "type": "varchar(100)", + "primaryKey": false, + "notNull": true + }, + "size": { + "name": "size", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "s3Key": { + "name": "s3Key", + "type": "varchar(500)", + "primaryKey": false, + "notNull": true + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "deletedAt": { + "name": "deletedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "card_attachment_cardId_card_id_fk": { + "name": "card_attachment_cardId_card_id_fk", + "tableFrom": "card_attachment", + "tableTo": "card", + "columnsFrom": [ + "cardId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "card_attachment_createdBy_user_id_fk": { + "name": "card_attachment_createdBy_user_id_fk", + "tableFrom": "card_attachment", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "card_attachment_publicId_unique": { + "name": "card_attachment_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public._card_workspace_members": { + "name": "_card_workspace_members", + "schema": "", + "columns": { + "cardId": { + "name": "cardId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "workspaceMemberId": { + "name": "workspaceMemberId", + "type": "bigint", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "_card_workspace_members_cardId_card_id_fk": { + "name": "_card_workspace_members_cardId_card_id_fk", + "tableFrom": "_card_workspace_members", + "tableTo": "card", + "columnsFrom": [ + "cardId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "_card_workspace_members_workspaceMemberId_workspace_members_id_fk": { + "name": "_card_workspace_members_workspaceMemberId_workspace_members_id_fk", + "tableFrom": "_card_workspace_members", + "tableTo": "workspace_members", + "columnsFrom": [ + "workspaceMemberId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "_card_workspace_members_cardId_workspaceMemberId_pk": { + "name": "_card_workspace_members_cardId_workspaceMemberId_pk", + "columns": [ + "cardId", + "workspaceMemberId" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.card": { + "name": "card", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "index": { + "name": "index", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedAt": { + "name": "deletedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedBy": { + "name": "deletedBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "listId": { + "name": "listId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "importId": { + "name": "importId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "dueDate": { + "name": "dueDate", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "card_createdBy_user_id_fk": { + "name": "card_createdBy_user_id_fk", + "tableFrom": "card", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "card_deletedBy_user_id_fk": { + "name": "card_deletedBy_user_id_fk", + "tableFrom": "card", + "tableTo": "user", + "columnsFrom": [ + "deletedBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "card_listId_list_id_fk": { + "name": "card_listId_list_id_fk", + "tableFrom": "card", + "tableTo": "list", + "columnsFrom": [ + "listId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "card_importId_import_id_fk": { + "name": "card_importId_import_id_fk", + "tableFrom": "card", + "tableTo": "import", + "columnsFrom": [ + "importId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "card_publicId_unique": { + "name": "card_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public._card_labels": { + "name": "_card_labels", + "schema": "", + "columns": { + "cardId": { + "name": "cardId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "labelId": { + "name": "labelId", + "type": "bigint", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "_card_labels_cardId_card_id_fk": { + "name": "_card_labels_cardId_card_id_fk", + "tableFrom": "_card_labels", + "tableTo": "card", + "columnsFrom": [ + "cardId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "_card_labels_labelId_label_id_fk": { + "name": "_card_labels_labelId_label_id_fk", + "tableFrom": "_card_labels", + "tableTo": "label", + "columnsFrom": [ + "labelId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "_card_labels_cardId_labelId_pk": { + "name": "_card_labels_cardId_labelId_pk", + "columns": [ + "cardId", + "labelId" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.card_comments": { + "name": "card_comments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "comment": { + "name": "comment", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "cardId": { + "name": "cardId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedAt": { + "name": "deletedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedBy": { + "name": "deletedBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "card_comments_cardId_card_id_fk": { + "name": "card_comments_cardId_card_id_fk", + "tableFrom": "card_comments", + "tableTo": "card", + "columnsFrom": [ + "cardId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "card_comments_createdBy_user_id_fk": { + "name": "card_comments_createdBy_user_id_fk", + "tableFrom": "card_comments", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "card_comments_deletedBy_user_id_fk": { + "name": "card_comments_deletedBy_user_id_fk", + "tableFrom": "card_comments", + "tableTo": "user", + "columnsFrom": [ + "deletedBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "card_comments_publicId_unique": { + "name": "card_comments_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.card_checklist_item": { + "name": "card_checklist_item", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "varchar(500)", + "primaryKey": false, + "notNull": true + }, + "completed": { + "name": "completed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "index": { + "name": "index", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "checklistId": { + "name": "checklistId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedAt": { + "name": "deletedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedBy": { + "name": "deletedBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "card_checklist_item_checklistId_card_checklist_id_fk": { + "name": "card_checklist_item_checklistId_card_checklist_id_fk", + "tableFrom": "card_checklist_item", + "tableTo": "card_checklist", + "columnsFrom": [ + "checklistId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "card_checklist_item_createdBy_user_id_fk": { + "name": "card_checklist_item_createdBy_user_id_fk", + "tableFrom": "card_checklist_item", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "card_checklist_item_deletedBy_user_id_fk": { + "name": "card_checklist_item_deletedBy_user_id_fk", + "tableFrom": "card_checklist_item", + "tableTo": "user", + "columnsFrom": [ + "deletedBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "card_checklist_item_publicId_unique": { + "name": "card_checklist_item_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.card_checklist": { + "name": "card_checklist", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "index": { + "name": "index", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "cardId": { + "name": "cardId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedAt": { + "name": "deletedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedBy": { + "name": "deletedBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "card_checklist_cardId_card_id_fk": { + "name": "card_checklist_cardId_card_id_fk", + "tableFrom": "card_checklist", + "tableTo": "card", + "columnsFrom": [ + "cardId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "card_checklist_createdBy_user_id_fk": { + "name": "card_checklist_createdBy_user_id_fk", + "tableFrom": "card_checklist", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "card_checklist_deletedBy_user_id_fk": { + "name": "card_checklist_deletedBy_user_id_fk", + "tableFrom": "card_checklist", + "tableTo": "user", + "columnsFrom": [ + "deletedBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "card_checklist_publicId_unique": { + "name": "card_checklist_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.feedback": { + "name": "feedback", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "feedback": { + "name": "feedback", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reviewed": { + "name": "reviewed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "feedback_createdBy_user_id_fk": { + "name": "feedback_createdBy_user_id_fk", + "tableFrom": "feedback", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.import": { + "name": "import", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "source", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "import_createdBy_user_id_fk": { + "name": "import_createdBy_user_id_fk", + "tableFrom": "import", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "import_publicId_unique": { + "name": "import_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.label": { + "name": "label", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "colourCode": { + "name": "colourCode", + "type": "varchar(12)", + "primaryKey": false, + "notNull": false + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "boardId": { + "name": "boardId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "importId": { + "name": "importId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "deletedAt": { + "name": "deletedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedBy": { + "name": "deletedBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "label_createdBy_user_id_fk": { + "name": "label_createdBy_user_id_fk", + "tableFrom": "label", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "label_boardId_board_id_fk": { + "name": "label_boardId_board_id_fk", + "tableFrom": "label", + "tableTo": "board", + "columnsFrom": [ + "boardId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "label_importId_import_id_fk": { + "name": "label_importId_import_id_fk", + "tableFrom": "label", + "tableTo": "import", + "columnsFrom": [ + "importId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "label_deletedBy_user_id_fk": { + "name": "label_deletedBy_user_id_fk", + "tableFrom": "label", + "tableTo": "user", + "columnsFrom": [ + "deletedBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "label_publicId_unique": { + "name": "label_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.list": { + "name": "list", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "index": { + "name": "index", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedAt": { + "name": "deletedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedBy": { + "name": "deletedBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "boardId": { + "name": "boardId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "importId": { + "name": "importId", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "list_createdBy_user_id_fk": { + "name": "list_createdBy_user_id_fk", + "tableFrom": "list", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "list_deletedBy_user_id_fk": { + "name": "list_deletedBy_user_id_fk", + "tableFrom": "list", + "tableTo": "user", + "columnsFrom": [ + "deletedBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "list_boardId_board_id_fk": { + "name": "list_boardId_board_id_fk", + "tableFrom": "list", + "tableTo": "board", + "columnsFrom": [ + "boardId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "list_importId_import_id_fk": { + "name": "list_importId_import_id_fk", + "tableFrom": "list", + "tableTo": "import", + "columnsFrom": [ + "importId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "list_publicId_unique": { + "name": "list_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuid_generate_v4()" + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "emailVerified": { + "name": "emailVerified", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "image": { + "name": "image", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "stripeCustomerId": { + "name": "stripeCustomerId", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_email_unique": { + "name": "user_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.integration": { + "name": "integration", + "schema": "", + "columns": { + "provider": { + "name": "provider", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "accessToken": { + "name": "accessToken", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "refreshToken": { + "name": "refreshToken", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "expiresAt": { + "name": "expiresAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "integration_userId_user_id_fk": { + "name": "integration_userId_user_id_fk", + "tableFrom": "integration", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "integration_pkey": { + "name": "integration_pkey", + "columns": [ + "userId", + "provider" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.workspace_slug_checks": { + "name": "workspace_slug_checks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "available": { + "name": "available", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "reserved": { + "name": "reserved", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "workspaceId": { + "name": "workspaceId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "workspace_slug_checks_workspaceId_workspace_id_fk": { + "name": "workspace_slug_checks_workspaceId_workspace_id_fk", + "tableFrom": "workspace_slug_checks", + "tableTo": "workspace", + "columnsFrom": [ + "workspaceId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "workspace_slug_checks_createdBy_user_id_fk": { + "name": "workspace_slug_checks_createdBy_user_id_fk", + "tableFrom": "workspace_slug_checks", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.workspace_slugs": { + "name": "workspace_slugs", + "schema": "", + "columns": { + "slug": { + "name": "slug", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "slug_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "workspace_slugs_slug_unique": { + "name": "workspace_slugs_slug_unique", + "nullsNotDistinct": false, + "columns": [ + "slug" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspace_members": { + "name": "workspace_members", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "workspaceId": { + "name": "workspaceId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedAt": { + "name": "deletedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedBy": { + "name": "deletedBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "role": { + "name": "role", + "type": "role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "roleId": { + "name": "roleId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "member_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'invited'" + } + }, + "indexes": {}, + "foreignKeys": { + "workspace_members_userId_user_id_fk": { + "name": "workspace_members_userId_user_id_fk", + "tableFrom": "workspace_members", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "workspace_members_workspaceId_workspace_id_fk": { + "name": "workspace_members_workspaceId_workspace_id_fk", + "tableFrom": "workspace_members", + "tableTo": "workspace", + "columnsFrom": [ + "workspaceId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "workspace_members_deletedBy_user_id_fk": { + "name": "workspace_members_deletedBy_user_id_fk", + "tableFrom": "workspace_members", + "tableTo": "user", + "columnsFrom": [ + "deletedBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "workspace_members_roleId_workspace_roles_id_fk": { + "name": "workspace_members_roleId_workspace_roles_id_fk", + "tableFrom": "workspace_members", + "tableTo": "workspace_roles", + "columnsFrom": [ + "roleId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "workspace_members_publicId_unique": { + "name": "workspace_members_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.workspace": { + "name": "workspace", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "slug": { + "name": "slug", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "plan": { + "name": "plan", + "type": "workspace_plan", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'free'" + }, + "showEmailsToMembers": { + "name": "showEmailsToMembers", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "weekStartDay": { + "name": "weekStartDay", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedAt": { + "name": "deletedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "deletedBy": { + "name": "deletedBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "workspace_createdBy_user_id_fk": { + "name": "workspace_createdBy_user_id_fk", + "tableFrom": "workspace", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "workspace_deletedBy_user_id_fk": { + "name": "workspace_deletedBy_user_id_fk", + "tableFrom": "workspace", + "tableTo": "user", + "columnsFrom": [ + "deletedBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "workspace_publicId_unique": { + "name": "workspace_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + }, + "workspace_slug_unique": { + "name": "workspace_slug_unique", + "nullsNotDistinct": false, + "columns": [ + "slug" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.subscription": { + "name": "subscription", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "plan": { + "name": "plan", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "referenceId": { + "name": "referenceId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": false + }, + "stripeCustomerId": { + "name": "stripeCustomerId", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "stripeSubscriptionId": { + "name": "stripeSubscriptionId", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "periodStart": { + "name": "periodStart", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "periodEnd": { + "name": "periodEnd", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "cancelAtPeriodEnd": { + "name": "cancelAtPeriodEnd", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "seats": { + "name": "seats", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "unlimitedSeats": { + "name": "unlimitedSeats", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "trialStart": { + "name": "trialStart", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "trialEnd": { + "name": "trialEnd", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "subscription_referenceId_workspace_publicId_fk": { + "name": "subscription_referenceId_workspace_publicId_fk", + "tableFrom": "subscription", + "tableTo": "workspace", + "columnsFrom": [ + "referenceId" + ], + "columnsTo": [ + "publicId" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.workspace_invite_links": { + "name": "workspace_invite_links", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "workspaceId": { + "name": "workspaceId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "code": { + "name": "code", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "invite_link_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "expiresAt": { + "name": "expiresAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "updatedBy": { + "name": "updatedBy", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "workspace_invite_links_workspaceId_workspace_id_fk": { + "name": "workspace_invite_links_workspaceId_workspace_id_fk", + "tableFrom": "workspace_invite_links", + "tableTo": "workspace", + "columnsFrom": [ + "workspaceId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "workspace_invite_links_createdBy_user_id_fk": { + "name": "workspace_invite_links_createdBy_user_id_fk", + "tableFrom": "workspace_invite_links", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "workspace_invite_links_updatedBy_user_id_fk": { + "name": "workspace_invite_links_updatedBy_user_id_fk", + "tableFrom": "workspace_invite_links", + "tableTo": "user", + "columnsFrom": [ + "updatedBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "workspace_invite_links_publicId_unique": { + "name": "workspace_invite_links_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + }, + "workspace_invite_links_code_unique": { + "name": "workspace_invite_links_code_unique", + "nullsNotDistinct": false, + "columns": [ + "code" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.workspace_member_permissions": { + "name": "workspace_member_permissions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "workspaceMemberId": { + "name": "workspaceMemberId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "permission": { + "name": "permission", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "granted": { + "name": "granted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "unique_member_permission": { + "name": "unique_member_permission", + "columns": [ + { + "expression": "workspaceMemberId", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "permission", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "permission_member_idx": { + "name": "permission_member_idx", + "columns": [ + { + "expression": "workspaceMemberId", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.workspace_role_permissions": { + "name": "workspace_role_permissions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "workspaceRoleId": { + "name": "workspaceRoleId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "permission": { + "name": "permission", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "granted": { + "name": "granted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "unique_role_permission": { + "name": "unique_role_permission", + "columns": [ + { + "expression": "workspaceRoleId", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "permission", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "role_permissions_role_idx": { + "name": "role_permissions_role_idx", + "columns": [ + { + "expression": "workspaceRoleId", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspace_role_permissions_workspaceRoleId_workspace_roles_id_fk": { + "name": "workspace_role_permissions_workspaceRoleId_workspace_roles_id_fk", + "tableFrom": "workspace_role_permissions", + "tableTo": "workspace_roles", + "columnsFrom": [ + "workspaceRoleId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.workspace_roles": { + "name": "workspace_roles", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "workspaceId": { + "name": "workspaceId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(64)", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "hierarchyLevel": { + "name": "hierarchyLevel", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "isSystem": { + "name": "isSystem", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "unique_role_per_workspace": { + "name": "unique_role_per_workspace", + "columns": [ + { + "expression": "workspaceId", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "workspace_roles_workspace_idx": { + "name": "workspace_roles_workspace_idx", + "columns": [ + { + "expression": "workspaceId", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspace_roles_workspaceId_workspace_id_fk": { + "name": "workspace_roles_workspaceId_workspace_id_fk", + "tableFrom": "workspace_roles", + "tableTo": "workspace", + "columnsFrom": [ + "workspaceId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "workspace_roles_publicId_unique": { + "name": "workspace_roles_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.notification": { + "name": "notification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "notification_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "cardId": { + "name": "cardId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "commentId": { + "name": "commentId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "workspaceId": { + "name": "workspaceId", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "readAt": { + "name": "readAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "deletedAt": { + "name": "deletedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "notification_user_deleted_idx": { + "name": "notification_user_deleted_idx", + "columns": [ + { + "expression": "userId", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "deletedAt", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notification_user_read_deleted_idx": { + "name": "notification_user_read_deleted_idx", + "columns": [ + { + "expression": "userId", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "readAt", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "deletedAt", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notification_user_type_card_idx": { + "name": "notification_user_type_card_idx", + "columns": [ + { + "expression": "userId", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "cardId", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notification_user_type_workspace_idx": { + "name": "notification_user_type_workspace_idx", + "columns": [ + { + "expression": "userId", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "workspaceId", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notification_user_created_idx": { + "name": "notification_user_created_idx", + "columns": [ + { + "expression": "userId", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "createdAt", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "notification_userId_user_id_fk": { + "name": "notification_userId_user_id_fk", + "tableFrom": "notification", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notification_cardId_card_id_fk": { + "name": "notification_cardId_card_id_fk", + "tableFrom": "notification", + "tableTo": "card", + "columnsFrom": [ + "cardId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notification_commentId_card_comments_id_fk": { + "name": "notification_commentId_card_comments_id_fk", + "tableFrom": "notification", + "tableTo": "card_comments", + "columnsFrom": [ + "commentId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "notification_workspaceId_workspace_id_fk": { + "name": "notification_workspaceId_workspace_id_fk", + "tableFrom": "notification", + "tableTo": "workspace", + "columnsFrom": [ + "workspaceId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "notification_publicId_unique": { + "name": "notification_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + }, + "public.workspace_webhooks": { + "name": "workspace_webhooks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "publicId": { + "name": "publicId", + "type": "varchar(12)", + "primaryKey": false, + "notNull": true + }, + "workspaceId": { + "name": "workspaceId", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "varchar(2048)", + "primaryKey": false, + "notNull": true + }, + "secret": { + "name": "secret", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "events": { + "name": "events", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "createdBy": { + "name": "createdBy", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updatedAt": { + "name": "updatedAt", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "workspace_webhooks_workspace_idx": { + "name": "workspace_webhooks_workspace_idx", + "columns": [ + { + "expression": "workspaceId", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspace_webhooks_workspaceId_workspace_id_fk": { + "name": "workspace_webhooks_workspaceId_workspace_id_fk", + "tableFrom": "workspace_webhooks", + "tableTo": "workspace", + "columnsFrom": [ + "workspaceId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "workspace_webhooks_createdBy_user_id_fk": { + "name": "workspace_webhooks_createdBy_user_id_fk", + "tableFrom": "workspace_webhooks", + "tableTo": "user", + "columnsFrom": [ + "createdBy" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "workspace_webhooks_publicId_unique": { + "name": "workspace_webhooks_publicId_unique", + "nullsNotDistinct": false, + "columns": [ + "publicId" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": true + } + }, + "enums": { + "public.board_type": { + "name": "board_type", + "schema": "public", + "values": [ + "regular", + "template" + ] + }, + "public.board_visibility": { + "name": "board_visibility", + "schema": "public", + "values": [ + "private", + "public" + ] + }, + "public.card_activity_type": { + "name": "card_activity_type", + "schema": "public", + "values": [ + "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.updated.checklist.added", + "card.updated.checklist.renamed", + "card.updated.checklist.deleted", + "card.updated.checklist.item.added", + "card.updated.checklist.item.updated", + "card.updated.checklist.item.completed", + "card.updated.checklist.item.uncompleted", + "card.updated.checklist.item.deleted", + "card.updated.attachment.added", + "card.updated.attachment.removed", + "card.updated.dueDate.added", + "card.updated.dueDate.updated", + "card.updated.dueDate.removed", + "card.archived" + ] + }, + "public.source": { + "name": "source", + "schema": "public", + "values": [ + "trello", + "github" + ] + }, + "public.status": { + "name": "status", + "schema": "public", + "values": [ + "started", + "success", + "failed" + ] + }, + "public.role": { + "name": "role", + "schema": "public", + "values": [ + "admin", + "member", + "guest" + ] + }, + "public.member_status": { + "name": "member_status", + "schema": "public", + "values": [ + "invited", + "active", + "removed", + "paused" + ] + }, + "public.slug_type": { + "name": "slug_type", + "schema": "public", + "values": [ + "reserved", + "premium" + ] + }, + "public.workspace_plan": { + "name": "workspace_plan", + "schema": "public", + "values": [ + "free", + "pro", + "enterprise" + ] + }, + "public.invite_link_status": { + "name": "invite_link_status", + "schema": "public", + "values": [ + "active", + "inactive" + ] + }, + "public.notification_type": { + "name": "notification_type", + "schema": "public", + "values": [ + "mention", + "workspace.member.added", + "workspace.member.removed", + "workspace.role.changed" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/packages/db/migrations/meta/_journal.json b/packages/db/migrations/meta/_journal.json index 1d075c057..8599ebce8 100644 --- a/packages/db/migrations/meta/_journal.json +++ b/packages/db/migrations/meta/_journal.json @@ -246,6 +246,20 @@ "when": 1780057951781, "tag": "20260529123231_DropPartnerLicenseKeyUniqueConstraint", "breakpoints": true + }, + { + "idx": 35, + "version": "7", + "when": 1780578144579, + "tag": "20260604130224_AddBoardUserTable", + "breakpoints": true + }, + { + "idx": 36, + "version": "7", + "when": 1780578264458, + "tag": "20260604130424_DropUserBoardFavorites", + "breakpoints": true } ] -} \ No newline at end of file +} diff --git a/packages/db/src/repository/board.repo.ts b/packages/db/src/repository/board.repo.ts index aa37a1104..5e5f39157 100644 --- a/packages/db/src/repository/board.repo.ts +++ b/packages/db/src/repository/board.repo.ts @@ -4,12 +4,14 @@ import { count, desc, eq, + gt, gte, inArray, isNotNull, isNull, lt, or, + sql, } from "drizzle-orm"; import type { dbClient } from "@kan/db/client"; @@ -26,11 +28,55 @@ import { comments, labels, lists, - userBoardFavorites, + boardUsers, workspaceMembers, } from "@kan/db/schema"; import { generateUID } from "@kan/shared/utils"; +// Transaction handle type (the client passed to db.transaction callbacks). +// Used by helpers that must run inside an existing transaction. +type dbTx = Parameters[0]>[0]; + +/** + * Seed a board_user row for every active workspace member for a newly created + * board. The new board is appended to the end of each user's non-favourite + * group (within the board's type + archive scope). + */ +const seedBoardUsersForBoard = async ( + db: dbTx, + args: { boardId: number; workspaceId: number }, +) => { + await db.execute(sql` + INSERT INTO "board_user" ("userId", "boardId", "position", "isFavourite", "createdAt") + SELECT + wm."userId", + ${args.boardId}, + COALESCE( + ( + SELECT MAX(bu."position") + 1 + FROM "board_user" bu + JOIN "board" b ON b."id" = bu."boardId" + WHERE bu."userId" = wm."userId" + AND b."workspaceId" = ${args.workspaceId} + AND b."type" = (SELECT "type" FROM "board" WHERE "id" = ${args.boardId}) + AND b."isArchived" = (SELECT "isArchived" FROM "board" WHERE "id" = ${args.boardId}) + AND bu."isFavourite" = false + AND b."deletedAt" IS NULL + AND bu."boardId" != ${args.boardId} + ), + 0 + ), + false, + now() + FROM "workspace_members" wm + WHERE wm."workspaceId" = ${args.workspaceId} + AND wm."userId" IS NOT NULL + AND wm."deletedAt" IS NULL + AND wm."status" = 'active' + ON CONFLICT ("userId", "boardId") DO NOTHING + `); +}; + export const getCount = async (db: dbClient) => { const result = await db .select({ count: count() }) @@ -52,10 +98,11 @@ export const getAllByWorkspaceId = async ( name: true, }, with: { - userFavorites: { - where: eq(userBoardFavorites.userId, userId), + boardUsers: { + where: eq(boardUsers.userId, userId), columns: { - userId: true, + position: true, + isFavourite: true, }, }, lists: { @@ -82,19 +129,20 @@ export const getAllByWorkspaceId = async ( ), }); - // Transform and sort: favorites first, then alphabetically + // Transform and sort: favourites first, then by per-user position return boardsData .map((board) => ({ ...board, - favorite: board.userFavorites.length > 0, - userFavorites: undefined, + favorite: board.boardUsers[0]?.isFavourite ?? false, + position: board.boardUsers[0]?.position ?? 0, + boardUsers: undefined, })) .sort((a, b) => { - // Sort favorites first + // Sort favourites first if (a.favorite && !b.favorite) return -1; if (!a.favorite && b.favorite) return 1; - // Then alphabetically by name - return a.name.localeCompare(b.name); + // Then by per-user position + return a.position - b.position; }); }; @@ -200,10 +248,10 @@ export const getByPublicId = async ( isArchived: true, }, with: { - userFavorites: { - where: eq(userBoardFavorites.userId, userId), + boardUsers: { + where: eq(boardUsers.userId, userId), columns: { - userId: true, + isFavourite: true, }, }, workspace: { @@ -363,8 +411,8 @@ export const getByPublicId = async ( const formattedResult = { ...board, - favorite: board.userFavorites.length > 0, - userFavorites: undefined, + favorite: board.boardUsers[0]?.isFavourite ?? false, + boardUsers: undefined, lists: board.lists.map((list) => ({ ...list, cards: list.cards.map((card) => ({ @@ -609,25 +657,34 @@ export const create = async ( sourceBoardId?: number; }, ) => { - const [result] = await db - .insert(boards) - .values({ - publicId: boardInput.publicId ?? generateUID(), - name: boardInput.name, - createdBy: boardInput.createdBy, - workspaceId: boardInput.workspaceId, - importId: boardInput.importId, - slug: boardInput.slug, - type: boardInput.type ?? "regular", - sourceBoardId: boardInput.sourceBoardId, - }) - .returning({ - id: boards.id, - publicId: boards.publicId, - name: boards.name, - }); + return db.transaction(async (tx) => { + const [result] = await tx + .insert(boards) + .values({ + publicId: boardInput.publicId ?? generateUID(), + name: boardInput.name, + createdBy: boardInput.createdBy, + workspaceId: boardInput.workspaceId, + importId: boardInput.importId, + slug: boardInput.slug, + type: boardInput.type ?? "regular", + sourceBoardId: boardInput.sourceBoardId, + }) + .returning({ + id: boards.id, + publicId: boards.publicId, + name: boards.name, + }); - return result; + if (result) { + await seedBoardUsersForBoard(tx, { + boardId: result.id, + workspaceId: boardInput.workspaceId, + }); + } + + return result; + }); }; export const update = async ( @@ -666,16 +723,51 @@ export const softDelete = async ( deletedBy: string; }, ) => { - const [result] = await db - .update(boards) - .set({ deletedAt: args.deletedAt, deletedBy: args.deletedBy }) - .where(and(eq(boards.id, args.boardId), isNull(boards.deletedAt))) - .returning({ - publicId: boards.publicId, - name: boards.name, - }); + return db.transaction(async (tx) => { + const [result] = await tx + .update(boards) + .set({ deletedAt: args.deletedAt, deletedBy: args.deletedBy }) + .where(and(eq(boards.id, args.boardId), isNull(boards.deletedAt))) + .returning({ + publicId: boards.publicId, + name: boards.name, + workspaceId: boards.workspaceId, + type: boards.type, + isArchived: boards.isArchived, + }); - return result; + if (result) { + // The board is now soft-deleted (deletedAt IS NOT NULL) so it is excluded + // from the compaction below. Renumber the remaining boards' positions + // (per user, per favourite group) to keep them contiguous from 0. + await tx.execute(sql` + WITH ordered AS ( + SELECT bu."userId", bu."boardId", + ROW_NUMBER() OVER ( + PARTITION BY bu."userId", bu."isFavourite" + ORDER BY bu."position" + ) - 1 AS new_position + FROM "board_user" bu + JOIN "board" b ON b."id" = bu."boardId" + WHERE b."workspaceId" = ${result.workspaceId} + AND b."type" = ${result.type} + AND b."isArchived" = ${result.isArchived} + AND b."deletedAt" IS NULL + AND bu."userId" IN ( + SELECT "userId" FROM "board_user" WHERE "boardId" = ${args.boardId} + ) + ) + UPDATE "board_user" bu + SET "position" = o.new_position + FROM ordered o + WHERE bu."userId" = o."userId" AND bu."boardId" = o."boardId" + `); + } + + return result + ? { publicId: result.publicId, name: result.name } + : undefined; + }); }; export const hardDelete = async (db: dbClient, workspaceId: number) => { @@ -717,6 +809,8 @@ export const getWorkspaceAndBoardIdByBoardPublicId = async ( id: true, workspaceId: true, createdBy: true, + type: true, + isArchived: true, }, where: eq(boards.publicId, boardPublicId), }); @@ -804,6 +898,11 @@ export const createFromSnapshot = async ( if (!newBoard) throw new Error("Failed to create board"); + await seedBoardUsersForBoard(tx, { + boardId: newBoard.id, + workspaceId: args.workspaceId, + }); + // Labels const srcLabels = args.source.labels; const labelMap = new Map(); @@ -969,33 +1068,295 @@ export const createFromSnapshot = async ( }); }; -export const addUserFavorite = async ( +/** + * Reorder a board to a new position within the current user's favourite group + * (favourites and non-favourites keep separate position sequences, scoped per + * user, board type and archive status). + */ +export const reorder = async ( db: dbClient, - userId: string, - boardId: number, + args: { + userId: string; + boardPublicId: string; + newPosition: number; + }, ) => { - return db - .insert(userBoardFavorites) - .values({ - userId, - boardId, - }) - .onConflictDoNothing() - .returning(); + return db.transaction(async (tx) => { + const board = await tx.query.boards.findFirst({ + columns: { + id: true, + workspaceId: true, + type: true, + isArchived: true, + }, + where: eq(boards.publicId, args.boardPublicId), + }); + + if (!board) + throw new Error(`Board not found for public ID ${args.boardPublicId}`); + + const boardUser = await tx.query.boardUsers.findFirst({ + columns: { position: true, isFavourite: true }, + where: and( + eq(boardUsers.userId, args.userId), + eq(boardUsers.boardId, board.id), + ), + }); + + if (!boardUser) throw new Error(`board_user record not found`); + + const oldPosition = boardUser.position; + const isFavourite = boardUser.isFavourite; + + await tx.execute(sql` + WITH scoped AS ( + SELECT bu."boardId" + FROM "board_user" bu + JOIN "board" b ON b."id" = bu."boardId" + WHERE bu."userId" = ${args.userId} + AND b."workspaceId" = ${board.workspaceId} + AND b."type" = ${board.type} + AND b."isArchived" = ${board.isArchived} + AND bu."isFavourite" = ${isFavourite} + AND b."deletedAt" IS NULL + ) + UPDATE "board_user" bu + SET "position" = + CASE + WHEN bu."boardId" = ${board.id} THEN ${args.newPosition} + WHEN ${oldPosition} < ${args.newPosition} + AND bu."position" > ${oldPosition} + AND bu."position" <= ${args.newPosition} + THEN bu."position" - 1 + WHEN ${oldPosition} > ${args.newPosition} + AND bu."position" >= ${args.newPosition} + AND bu."position" < ${oldPosition} + THEN bu."position" + 1 + ELSE bu."position" + END + WHERE bu."userId" = ${args.userId} + AND bu."boardId" IN (SELECT "boardId" FROM scoped) + `); + + // Defensive auto-heal: if any duplicate positions slipped in, compact. + const countExpr = sql`COUNT(*)`.mapWith(Number); + const duplicates = await tx + .select({ position: boardUsers.position, count: countExpr }) + .from(boardUsers) + .innerJoin(boards, eq(boardUsers.boardId, boards.id)) + .where( + and( + eq(boardUsers.userId, args.userId), + eq(boards.workspaceId, board.workspaceId), + eq(boards.type, board.type), + eq(boards.isArchived, board.isArchived), + eq(boardUsers.isFavourite, isFavourite), + isNull(boards.deletedAt), + ), + ) + .groupBy(boardUsers.position) + .having(gt(countExpr, 1)); + + if (duplicates.length > 0) { + await tx.execute(sql` + WITH ordered AS ( + SELECT bu."userId", bu."boardId", + ROW_NUMBER() OVER (ORDER BY bu."position", bu."boardId") - 1 AS new_position + FROM "board_user" bu + JOIN "board" b ON b."id" = bu."boardId" + WHERE bu."userId" = ${args.userId} + AND b."workspaceId" = ${board.workspaceId} + AND b."type" = ${board.type} + AND b."isArchived" = ${board.isArchived} + AND bu."isFavourite" = ${isFavourite} + AND b."deletedAt" IS NULL + ) + UPDATE "board_user" bu + SET "position" = o.new_position + FROM ordered o + WHERE bu."userId" = o."userId" AND bu."boardId" = o."boardId" + `); + } + + const updatedBoard = await tx.query.boards.findFirst({ + columns: { publicId: true, name: true }, + where: eq(boards.publicId, args.boardPublicId), + }); + + return updatedBoard; + }); }; -export const removeUserFavorite = async ( +/** + * Toggle a board's favourite status for a user. The board moves to the end of + * the target favourite group and the group it left is compacted. + */ +export const setFavourite = async ( db: dbClient, - userId: string, - boardId: number, + args: { + userId: string; + boardId: number; + isFavourite: boolean; + workspaceId: number; + boardType: "regular" | "template"; + isArchived: boolean; + }, ) => { - return db - .delete(userBoardFavorites) - .where( - and( - eq(userBoardFavorites.userId, userId), - eq(userBoardFavorites.boardId, boardId) + return db.transaction(async (tx) => { + const targetRows = await tx + .select({ position: boardUsers.position }) + .from(boardUsers) + .innerJoin(boards, eq(boardUsers.boardId, boards.id)) + .where( + and( + eq(boardUsers.userId, args.userId), + eq(boards.workspaceId, args.workspaceId), + eq(boards.type, args.boardType), + eq(boards.isArchived, args.isArchived), + eq(boardUsers.isFavourite, args.isFavourite), + isNull(boards.deletedAt), + ), + ); + + const maxPosition = targetRows.reduce( + (max, row) => Math.max(max, row.position), + -1, + ); + + await tx + .insert(boardUsers) + .values({ + userId: args.userId, + boardId: args.boardId, + position: maxPosition + 1, + isFavourite: args.isFavourite, + }) + .onConflictDoUpdate({ + target: [boardUsers.userId, boardUsers.boardId], + set: { isFavourite: args.isFavourite, position: maxPosition + 1 }, + }); + + // Compact the group the board just left. + await tx.execute(sql` + WITH ordered AS ( + SELECT bu."userId", bu."boardId", + ROW_NUMBER() OVER (ORDER BY bu."position") - 1 AS new_position + FROM "board_user" bu + JOIN "board" b ON b."id" = bu."boardId" + WHERE bu."userId" = ${args.userId} + AND b."workspaceId" = ${args.workspaceId} + AND b."type" = ${args.boardType} + AND b."isArchived" = ${args.isArchived} + AND bu."isFavourite" = ${!args.isFavourite} + AND b."deletedAt" IS NULL + ) + UPDATE "board_user" bu + SET "position" = o.new_position + FROM ordered o + WHERE bu."userId" = o."userId" AND bu."boardId" = o."boardId" + `); + + return { success: true }; + }); +}; + +/** + * Seed board_user rows for a user who has just joined a workspace, one per + * non-deleted board, with sequential positions per board type + archive status. + */ +export const createBoardUsersForMember = async ( + db: dbClient, + args: { + userId: string; + workspaceId: number; + }, +) => { + await db.execute(sql` + INSERT INTO "board_user" ("userId", "boardId", "position", "isFavourite", "createdAt") + SELECT + ${args.userId}, + b."id", + (ROW_NUMBER() OVER ( + PARTITION BY b."type", b."isArchived" + ORDER BY b."createdAt", b."id" + ) - 1)::integer, + false, + now() + FROM "board" b + WHERE b."workspaceId" = ${args.workspaceId} + AND b."deletedAt" IS NULL + ON CONFLICT ("userId", "boardId") DO NOTHING + `); +}; + +/** + * After a board's archive status flips, move it to the end of the target + * archive group (per user, preserving each user's favourite flag) and compact + * the archive group it left. The board's isArchived column must already reflect + * the new value when this runs. + */ +export const reassignPositionsOnArchiveToggle = async ( + db: dbClient, + args: { + boardId: number; + workspaceId: number; + boardType: "regular" | "template"; + newIsArchived: boolean; + }, +) => { + return db.transaction(async (tx) => { + // 1. Place the toggled board at the end of each user's target group. + await tx.execute(sql` + UPDATE "board_user" bu + SET "position" = sub.new_position + FROM ( + SELECT + bu2."userId", + COALESCE( + ( + SELECT MAX(bu3."position") + 1 + FROM "board_user" bu3 + JOIN "board" b3 ON b3."id" = bu3."boardId" + WHERE bu3."userId" = bu2."userId" + AND b3."workspaceId" = ${args.workspaceId} + AND b3."type" = ${args.boardType} + AND b3."isArchived" = ${args.newIsArchived} + AND bu3."isFavourite" = bu2."isFavourite" + AND b3."deletedAt" IS NULL + AND bu3."boardId" != ${args.boardId} + ), + 0 + ) AS new_position + FROM "board_user" bu2 + WHERE bu2."boardId" = ${args.boardId} + ) sub + WHERE bu."userId" = sub."userId" AND bu."boardId" = ${args.boardId} + `); + + // 2. Compact the archive group the board just left. + await tx.execute(sql` + WITH ordered AS ( + SELECT bu."userId", bu."boardId", + ROW_NUMBER() OVER ( + PARTITION BY bu."userId", bu."isFavourite" + ORDER BY bu."position" + ) - 1 AS new_position + FROM "board_user" bu + JOIN "board" b ON b."id" = bu."boardId" + WHERE b."workspaceId" = ${args.workspaceId} + AND b."type" = ${args.boardType} + AND b."isArchived" = ${!args.newIsArchived} + AND b."deletedAt" IS NULL + AND bu."userId" IN ( + SELECT "userId" FROM "board_user" WHERE "boardId" = ${args.boardId} + ) ) - ) - .returning(); + UPDATE "board_user" bu + SET "position" = o.new_position + FROM ordered o + WHERE bu."userId" = o."userId" AND bu."boardId" = o."boardId" + `); + + return { success: true }; + }); }; \ No newline at end of file diff --git a/packages/db/src/schema/boards.ts b/packages/db/src/schema/boards.ts index 140fa76c9..8ac96a814 100644 --- a/packages/db/src/schema/boards.ts +++ b/packages/db/src/schema/boards.ts @@ -3,6 +3,7 @@ import { bigint, bigserial, index, + integer, pgEnum, pgTable, primaryKey, @@ -70,7 +71,7 @@ export const boards = pgTable( ).enableRLS(); export const boardsRelations = relations(boards, ({ one, many }) => ({ - userFavorites: many(userBoardFavorites), + boardUsers: many(boardUsers), createdBy: one(users, { fields: [boards.createdBy], references: [users.id], @@ -96,8 +97,8 @@ export const boardsRelations = relations(boards, ({ one, many }) => ({ }), })); -export const userBoardFavorites = pgTable( - "user_board_favorites", +export const boardUsers = pgTable( + "board_user", { userId: uuid("userId") .notNull() @@ -105,11 +106,26 @@ export const userBoardFavorites = pgTable( boardId: bigint("boardId", { mode: "number" }) .notNull() .references(() => boards.id, { onDelete: "cascade" }), + position: integer("position").notNull(), + isFavourite: boolean("isFavourite").notNull().default(false), createdAt: timestamp("createdAt").defaultNow().notNull(), }, - (table) => ({ - pk: primaryKey({ columns: [table.userId, table.boardId] }), - userIdx: index("user_board_favorite_user_idx").on(table.userId), - boardIdx: index("user_board_favorite_board_idx").on(table.boardId), + (table) => [ + primaryKey({ columns: [table.userId, table.boardId] }), + index("board_user_user_idx").on(table.userId), + index("board_user_board_idx").on(table.boardId), + ], +); + +export const boardUsersRelations = relations(boardUsers, ({ one }) => ({ + user: one(users, { + fields: [boardUsers.userId], + references: [users.id], + relationName: "boardUserUser", + }), + board: one(boards, { + fields: [boardUsers.boardId], + references: [boards.id], + relationName: "boardUserBoard", }), -); \ No newline at end of file +})); \ No newline at end of file diff --git a/packages/db/src/schema/users.ts b/packages/db/src/schema/users.ts index 11a107c58..bb9ee9386 100644 --- a/packages/db/src/schema/users.ts +++ b/packages/db/src/schema/users.ts @@ -8,7 +8,7 @@ import { } from "drizzle-orm/pg-core"; import { apikey } from "./auth"; -import { boards, userBoardFavorites } from "./boards"; +import { boards } from "./boards"; import { cards } from "./cards"; import { imports } from "./imports"; import { lists } from "./lists"; @@ -83,15 +83,4 @@ export const usersToWorkspacesRelations = relations( relationName: "usersToWorkspacesWorkspace", }), }), -); - -export const userBoardFavoritesRelations = relations(userBoardFavorites, ({ one }) => ({ - user: one(users, { - fields: [userBoardFavorites.userId], - references: [users.id], - }), - board: one(boards, { - fields: [userBoardFavorites.boardId], - references: [boards.id], - }), -})); \ No newline at end of file +); \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6a5dc9e56..5848e00cc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -88,6 +88,15 @@ importers: '@aws-sdk/s3-request-presigner': specifier: ^3.812.0 version: 3.879.0 + '@dnd-kit/core': + specifier: ^6.3.1 + version: 6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@dnd-kit/sortable': + specifier: ^10.0.0 + version: 10.0.0(@dnd-kit/core@6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + '@dnd-kit/utilities': + specifier: ^3.2.2 + version: 3.2.2(react@18.3.1) '@headlessui/react': specifier: ^2.2.0 version: 2.2.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -1514,6 +1523,28 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} + '@dnd-kit/accessibility@3.1.1': + resolution: {integrity: sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==} + peerDependencies: + react: '>=16.8.0' + + '@dnd-kit/core@6.3.1': + resolution: {integrity: sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@dnd-kit/sortable@10.0.0': + resolution: {integrity: sha512-+xqhmIIzvAYMGfBYYnbKuNicfSsk4RksY2XdmJhT+HAC01nix6fHCztU68jooFiMUB01Ky3F0FyOvhG/BZrWkg==} + peerDependencies: + '@dnd-kit/core': ^6.3.0 + react: '>=16.8.0' + + '@dnd-kit/utilities@3.2.2': + resolution: {integrity: sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==} + peerDependencies: + react: '>=16.8.0' + '@drizzle-team/brocli@0.10.2': resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==} @@ -5786,25 +5817,29 @@ packages: glob@10.3.10: resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} engines: {node: '>=16 || 14 >=14.17'} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true glob@10.4.5: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true glob@11.0.3: resolution: {integrity: sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==} engines: {node: 20 || >=22} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true glob@11.1.0: resolution: {integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==} engines: {node: 20 || >=22} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} @@ -10200,6 +10235,31 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 + '@dnd-kit/accessibility@3.1.1(react@18.3.1)': + dependencies: + react: 18.3.1 + tslib: 2.8.1 + + '@dnd-kit/core@6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@dnd-kit/accessibility': 3.1.1(react@18.3.1) + '@dnd-kit/utilities': 3.2.2(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + tslib: 2.8.1 + + '@dnd-kit/sortable@10.0.0(@dnd-kit/core@6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + dependencies: + '@dnd-kit/core': 6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@dnd-kit/utilities': 3.2.2(react@18.3.1) + react: 18.3.1 + tslib: 2.8.1 + + '@dnd-kit/utilities@3.2.2(react@18.3.1)': + dependencies: + react: 18.3.1 + tslib: 2.8.1 + '@drizzle-team/brocli@0.10.2': {} '@electric-sql/pglite@0.3.7': {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index b70d3eefd..bd05fe60f 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -3,6 +3,10 @@ packages: - packages/* - tooling/* +# Only install package versions published at least 7 days ago (10080 minutes) +# to reduce exposure to supply-chain attacks via freshly published releases. +minimumReleaseAge: 10080 + catalog: "@tanstack/react-query": ^5.59.15 "@trpc/client": ^11.4.3