mirror of
https://github.com/Portabase/portabase.git
synced 2026-07-14 11:16:13 +02:00
Finish migration prisma to drizzle.
This commit is contained in:
@@ -1,16 +1,21 @@
|
|||||||
import { PageParams } from "@/types/next";
|
import { PageParams } from "@/types/next";
|
||||||
|
import * as drizzleDb from "@/db";
|
||||||
|
|
||||||
import { Page, PageContent, PageHeader, PageTitle } from "@/features/layout/page";
|
import { Page, PageContent, PageHeader, PageTitle } from "@/features/layout/page";
|
||||||
import { AdminTabs } from "@/components/wrappers/dashboard/admin/admin-tabs";
|
import { AdminTabs } from "@/components/wrappers/dashboard/admin/admin-tabs";
|
||||||
import { currentUser } from "@/lib/auth/current-user";
|
import { currentUser } from "@/lib/auth/current-user";
|
||||||
import { db } from "@/db";
|
import { db } from "@/db";
|
||||||
|
import {eq, isNotNull, isNull} from "drizzle-orm";
|
||||||
|
|
||||||
|
|
||||||
export default async function RoutePage(props: PageParams<{}>) {
|
export default async function RoutePage(props: PageParams<{}>) {
|
||||||
const user = await currentUser()!;
|
const user = await currentUser();
|
||||||
|
|
||||||
const users = await db.query.user.findMany({
|
const users = await db.query.user.findMany({
|
||||||
where: (fields, { isNull, not }) => not(isNull(fields.deletedAt)),
|
where: (fields) => isNull(fields.deletedAt)
|
||||||
});
|
});
|
||||||
|
// const users = await db.query.user.findMany();
|
||||||
|
console.log("users",users);
|
||||||
|
|
||||||
const settings = await db.query.setting.findFirst({
|
const settings = await db.query.setting.findFirst({
|
||||||
where: (fields, { eq }) => eq(fields.name, "system"),
|
where: (fields, { eq }) => eq(fields.name, "system"),
|
||||||
@@ -22,7 +27,7 @@ export default async function RoutePage(props: PageParams<{}>) {
|
|||||||
<PageTitle>Administration Panel</PageTitle>
|
<PageTitle>Administration Panel</PageTitle>
|
||||||
</PageHeader>
|
</PageHeader>
|
||||||
<PageContent className="mt-10">
|
<PageContent className="mt-10">
|
||||||
<AdminTabs settings={settings!} currentUser={user} users={users} />
|
<AdminTabs settings={settings!} users={users} />
|
||||||
</PageContent>
|
</PageContent>
|
||||||
</Page>
|
</Page>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import {GearIcon} from "@radix-ui/react-icons";
|
import {GearIcon} from "@radix-ui/react-icons";
|
||||||
import {prisma} from "@/prisma";
|
|
||||||
import {PageParams} from "@/types/next";
|
import {PageParams} from "@/types/next";
|
||||||
import {Page, PageContent, PageDescription, PageTitle} from "@/features/layout/page";
|
import {Page, PageContent, PageDescription, PageTitle} from "@/features/layout/page";
|
||||||
import {formatDateLastContact} from "@/utils/date-formatting";
|
import {formatDateLastContact} from "@/utils/date-formatting";
|
||||||
@@ -9,38 +8,55 @@ import {Card, CardContent, CardHeader} from "@/components/ui/card";
|
|||||||
import {CardsWithPagination} from "@/components/wrappers/common/cards-with-pagination";
|
import {CardsWithPagination} from "@/components/wrappers/common/cards-with-pagination";
|
||||||
import {DatabaseCard} from "@/components/wrappers/dashboard/projects/ProjectCard/ProjectDatabaseCard";
|
import {DatabaseCard} from "@/components/wrappers/dashboard/projects/ProjectCard/ProjectDatabaseCard";
|
||||||
import {AgentCardKey} from "@/components/wrappers/dashboard/agent/AgentCardKey/AgentCardKey";
|
import {AgentCardKey} from "@/components/wrappers/dashboard/agent/AgentCardKey/AgentCardKey";
|
||||||
|
import { db } from "@/db";
|
||||||
|
import * as drizzleDb from "@/db";
|
||||||
|
import {and, eq} from "drizzle-orm";
|
||||||
|
import {notFound} from "next/navigation";
|
||||||
|
|
||||||
|
|
||||||
export default async function RoutePage(props: PageParams<{ agentId: string }>) {
|
export default async function RoutePage(props: PageParams<{ agentId: string }>) {
|
||||||
|
|
||||||
const {agentId} = await props.params
|
const {agentId} = await props.params
|
||||||
|
|
||||||
const agent = await prisma.agent.findUnique({
|
const agent = await db.query.agent.findFirst({
|
||||||
where: {
|
where: eq(drizzleDb.schemas.agent.id, agentId),
|
||||||
id: agentId,
|
with: {
|
||||||
},
|
databases: true
|
||||||
include: {
|
|
||||||
databases: {}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
//
|
||||||
|
console.log(agent)
|
||||||
|
|
||||||
const databaseId = 'db-123';
|
if (!agent) {
|
||||||
|
notFound()
|
||||||
const totalBackups = await prisma.backup.count({
|
}
|
||||||
where: {
|
//
|
||||||
databaseId: databaseId,
|
// const databaseId = 'db-123';
|
||||||
},
|
//
|
||||||
});
|
// const totalBackupsResult = await db
|
||||||
|
// .select({ count: drizzleDb.schemas.backup.id })
|
||||||
const successfulBackups = await prisma.backup.count({
|
// .from(drizzleDb.schemas.backup)
|
||||||
where: {
|
// .where(eq(drizzleDb.schemas.backup.databaseId, databaseId))
|
||||||
databaseId: databaseId,
|
// .execute();
|
||||||
status: 'success',
|
//
|
||||||
},
|
// const totalBackups = totalBackupsResult.length;
|
||||||
});
|
//
|
||||||
|
// const successfulBackupsResult = await db
|
||||||
const successRate = totalBackups > 0 ? (successfulBackups / totalBackups) * 100 : null
|
// .select({ count: drizzleDb.schemas.backup.id })
|
||||||
|
// .from(drizzleDb.schemas.backup)
|
||||||
|
// .where(
|
||||||
|
// and(
|
||||||
|
// eq(drizzleDb.schemas.backup.databaseId, databaseId),
|
||||||
|
// eq(drizzleDb.schemas.backup.status, "success")
|
||||||
|
// )
|
||||||
|
// )
|
||||||
|
// .execute();
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// const successfulBackups = successfulBackupsResult.length;
|
||||||
|
//
|
||||||
|
// const successRate =
|
||||||
|
// totalBackups > 0 ? (successfulBackups / totalBackups) * 100 : null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page>
|
<Page>
|
||||||
@@ -73,7 +89,7 @@ export default async function RoutePage(props: PageParams<{ agentId: string }>)
|
|||||||
Success rate
|
Success rate
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
{successRate ?? "Unavailable for now."}
|
{/*{successRate ?? "Unavailable for now."}*/}
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
<Card className="w-full sm:w-auto flex-1">
|
<Card className="w-full sm:w-auto flex-1">
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import Link from "next/link";
|
|||||||
import { Page, PageActions, PageContent, PageHeader, PageTitle } from "@/features/layout/page";
|
import { Page, PageActions, PageContent, PageHeader, PageTitle } from "@/features/layout/page";
|
||||||
import { notFound } from "next/navigation";
|
import { notFound } from "next/navigation";
|
||||||
import { db } from "@/db";
|
import { db } from "@/db";
|
||||||
export const dynamic = "force-dynamic";
|
|
||||||
|
|
||||||
export default async function RoutePage(props: PageParams<{}>) {
|
export default async function RoutePage(props: PageParams<{}>) {
|
||||||
const agents = await db.query.agent.findMany();
|
const agents = await db.query.agent.findMany();
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export default async function RoutePage(props: PageParams<{ projectId: string }>
|
|||||||
notFound();
|
notFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
const org = await db.query.organization.findFirst({
|
const org = await db.query.organization.findFirst({
|
||||||
where: eq(drizzleDb.schemas.organization.slug, "default"),
|
where: eq(drizzleDb.schemas.organization.slug, "default"),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export default async function RoutePage(props: PageParams<{
|
|||||||
<div className="justify-between gap-2 sm:flex">
|
<div className="justify-between gap-2 sm:flex">
|
||||||
<PageTitle className="flex items-center">
|
<PageTitle className="flex items-center">
|
||||||
{proj.name}
|
{proj.name}
|
||||||
<Link className={buttonVariants({ variant: "outline" })} href={`/dashboard/${organization.slug}/projects/${proj.id}/edit`}>
|
<Link className={buttonVariants({ variant: "outline" })} href={`/dashboard/projects/${proj.id}/edit`}>
|
||||||
<GearIcon className="w-7 h-7" />
|
<GearIcon className="w-7 h-7" />
|
||||||
</Link>
|
</Link>
|
||||||
</PageTitle>
|
</PageTitle>
|
||||||
|
|||||||
@@ -1,26 +1,19 @@
|
|||||||
import {PageParams} from "@/types/next";
|
import {PageParams} from "@/types/next";
|
||||||
import {Page, PageContent, PageHeader, PageTitle} from "@/features/layout/page";
|
import {Page, PageContent, PageHeader, PageTitle} from "@/features/layout/page";
|
||||||
import {getCurrentOrganizationSlug} from "@/features/dashboard/organization-cookie";
|
|
||||||
import {prisma} from "@/prisma";
|
|
||||||
import {requiredCurrentUser} from "@/auth/current-user";
|
|
||||||
import {notFound} from "next/navigation";
|
import {notFound} from "next/navigation";
|
||||||
import {OrganizationForm} from "@/components/wrappers/dashboard/organization/OrganizationForm/OrganizationForm";
|
import {OrganizationForm} from "@/components/wrappers/dashboard/organization/OrganizationForm/OrganizationForm";
|
||||||
import {getOrganization} from "@/lib/auth/auth";
|
import {getOrganization} from "@/lib/auth/auth";
|
||||||
|
|
||||||
|
|
||||||
export default async function RoutePage(props: PageParams<{
|
export default async function RoutePage(props: PageParams<{
|
||||||
slug: string;
|
|
||||||
}>) {
|
}>) {
|
||||||
|
const organization = await getOrganization({});
|
||||||
const {slug: organizationSlug} = await props.params;
|
|
||||||
|
|
||||||
const organization = await getOrganization({organizationSlug});
|
|
||||||
|
|
||||||
if (!organization) {
|
if (!organization) {
|
||||||
notFound()
|
notFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<Page>
|
<Page>
|
||||||
<PageHeader>
|
<PageHeader>
|
||||||
|
|||||||
@@ -3,9 +3,6 @@ import {Page, PageActions, PageContent, PageDescription, PageHeader, PageTitle}
|
|||||||
import {currentUser} from "@/lib/auth/current-user";
|
import {currentUser} from "@/lib/auth/current-user";
|
||||||
import {getOrganization} from "@/lib/auth/auth";
|
import {getOrganization} from "@/lib/auth/auth";
|
||||||
import {notFound} from "next/navigation";
|
import {notFound} from "next/navigation";
|
||||||
import {requiredCurrentUser} from "@/auth/current-user";
|
|
||||||
import {SettingsTabs} from "@/components/wrappers/dashboard/settings/SettingsTabs/SettingsTabs";
|
|
||||||
import {getCurrentOrganizationSlug} from "@/features/dashboard/organization-cookie";
|
|
||||||
import {
|
import {
|
||||||
DeleteOrganizationButton
|
DeleteOrganizationButton
|
||||||
} from "@/components/wrappers/dashboard/organization/DeleteOrganization/DeleteOrganizationButton";
|
} from "@/components/wrappers/dashboard/organization/DeleteOrganization/DeleteOrganizationButton";
|
||||||
@@ -13,50 +10,13 @@ import {EditButtonSettings} from "@/components/wrappers/dashboard/settings/EditB
|
|||||||
|
|
||||||
|
|
||||||
export default async function RoutePage(props: PageParams<{ slug: string }>) {
|
export default async function RoutePage(props: PageParams<{ slug: string }>) {
|
||||||
const {slug: organizationSlug} = await props.params;
|
const organization = await getOrganization({});
|
||||||
|
|
||||||
const user = await currentUser();
|
const user = await currentUser();
|
||||||
|
|
||||||
const organization = await getOrganization({organizationSlug});
|
if (!organization) {
|
||||||
|
|
||||||
if (!organization || organization?.slug !== organizationSlug) {
|
|
||||||
notFound();
|
notFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// const organization = await prisma.organization.findUnique({
|
|
||||||
// where: {
|
|
||||||
// slug: currentOrganizationSlug,
|
|
||||||
// },
|
|
||||||
// include: {
|
|
||||||
// users:{
|
|
||||||
// include:{
|
|
||||||
// user: {}
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// const currentOrganizationUser = await prisma.userOrganization.findFirst({
|
|
||||||
// where:{
|
|
||||||
// userId: user.id,
|
|
||||||
// organization:{
|
|
||||||
// slug: currentOrganizationSlug != "" ? currentOrganizationSlug : "default",
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// if (currentOrganizationUser.role != "admin") {
|
|
||||||
// notFound()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// const settings = await prisma.settings.findUnique({
|
|
||||||
// where: {
|
|
||||||
// name: "system"
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page>
|
<Page>
|
||||||
<PageHeader>
|
<PageHeader>
|
||||||
@@ -76,7 +36,7 @@ export default async function RoutePage(props: PageParams<{ slug: string }>) {
|
|||||||
Manage your organization settings.
|
Manage your organization settings.
|
||||||
</PageDescription>
|
</PageDescription>
|
||||||
<PageContent>
|
<PageContent>
|
||||||
{/*<SettingsTabs settings={settings} currentUser={user} users={organization.users}/>*/}
|
{/* TODO add the list of organisation members (add, remove, edit) */}
|
||||||
</PageContent>
|
</PageContent>
|
||||||
</Page>
|
</Page>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -8,17 +8,17 @@ import { notFound } from "next/navigation";
|
|||||||
import { db } from "@/db";
|
import { db } from "@/db";
|
||||||
import { asc, count, eq, inArray } from "drizzle-orm";
|
import { asc, count, eq, inArray } from "drizzle-orm";
|
||||||
import * as drizzleDb from "@/db";
|
import * as drizzleDb from "@/db";
|
||||||
|
import {getOrganization} from "@/lib/auth/auth";
|
||||||
|
|
||||||
export default async function RoutePage(props: PageParams<{ slug: string }>) {
|
export default async function RoutePage(props: PageParams<{ }>) {
|
||||||
const { slug: organizationSlug } = await props.params;
|
const organization = await getOrganization({});
|
||||||
|
|
||||||
const currentOrganizationSlug = await getCurrentOrganizationSlug();
|
if (!organization) {
|
||||||
if (currentOrganizationSlug !== organizationSlug) {
|
|
||||||
notFound();
|
notFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
const org = await db.query.organization.findFirst({
|
const org = await db.query.organization.findFirst({
|
||||||
where: eq(drizzleDb.schemas.organization.slug, currentOrganizationSlug),
|
where: eq(drizzleDb.schemas.organization.slug, organization.slug),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!org) notFound();
|
if (!org) notFound();
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import {NextResponse} from "next/server";
|
import {NextResponse} from "next/server";
|
||||||
import {prisma} from "@/prisma";
|
|
||||||
import {isUuidv4} from "@/utils/verify-uuid";
|
import {isUuidv4} from "@/utils/verify-uuid";
|
||||||
import {uploadLocalPrivate} from "@/features/upload/private/upload.action";
|
import {uploadLocalPrivate} from "@/features/upload/private/upload.action";
|
||||||
import {v4 as uuidv4} from "uuid";
|
import {v4 as uuidv4} from "uuid";
|
||||||
import {Backup, Database} from "@prisma/client";
|
|
||||||
import {eventEmitter} from "../../../events/route";
|
import {eventEmitter} from "../../../events/route";
|
||||||
|
import {db} from "@/db";
|
||||||
|
import {Backup} from "@/db/schema/06_database";
|
||||||
|
import {and, eq} from "drizzle-orm";
|
||||||
|
import * as drizzleDb from "@/db";
|
||||||
|
|
||||||
export async function POST(
|
export async function POST(
|
||||||
request: Request,
|
request: Request,
|
||||||
@@ -33,8 +35,8 @@ export async function POST(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const agent = await prisma.agent.findFirst({
|
const agent = await db.query.agent.findFirst({
|
||||||
where: { id: agentId },
|
where: eq(drizzleDb.schemas.agent.id, agentId),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!agent) {
|
if (!agent) {
|
||||||
@@ -44,8 +46,8 @@ export async function POST(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const database = await prisma.database.findFirst({
|
const database = await db.query.database.findFirst({
|
||||||
where: { generatedId },
|
where: eq(drizzleDb.schemas.database.agentDatabaseId, generatedId),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!database) {
|
if (!database) {
|
||||||
@@ -55,15 +57,17 @@ export async function POST(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let backup: Backup | null = null;
|
let backup: Backup | null | undefined = null;
|
||||||
|
|
||||||
if (method === "automatic") {
|
if (method === "automatic") {
|
||||||
backup = await prisma.backup.create({
|
[backup] = await db
|
||||||
data: {
|
.insert(drizzleDb.schemas.backup)
|
||||||
status: "ongoing",
|
.values({
|
||||||
|
status: 'ongoing',
|
||||||
databaseId: database.id,
|
databaseId: database.id,
|
||||||
},
|
})
|
||||||
});
|
.returning();
|
||||||
|
|
||||||
|
|
||||||
if (!backup) {
|
if (!backup) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
@@ -72,13 +76,14 @@ export async function POST(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
backup = await prisma.backup.findFirst({
|
backup = await db.query.backup.findFirst({
|
||||||
where: {
|
where: and(
|
||||||
status: "ongoing",
|
eq(drizzleDb.schemas.backup.status, 'ongoing'),
|
||||||
databaseId: database.id,
|
eq(drizzleDb.schemas.backup.databaseId, database.id),
|
||||||
},
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
if (!backup) {
|
if (!backup) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{error: "Unable to find the corresponding backup"},
|
{error: "Unable to find the corresponding backup"},
|
||||||
@@ -112,13 +117,14 @@ export async function POST(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await prisma.backup.update({
|
await db
|
||||||
where: { id: backup.id },
|
.update(drizzleDb.schemas.backup)
|
||||||
data: {
|
.set({
|
||||||
file: fileName,
|
file: fileName,
|
||||||
status: "success",
|
status: 'success',
|
||||||
},
|
})
|
||||||
});
|
.where(eq(drizzleDb.schemas.backup.id, backup.id));
|
||||||
|
|
||||||
eventEmitter.emit('modification', {update: true});
|
eventEmitter.emit('modification', {update: true});
|
||||||
|
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
@@ -128,10 +134,12 @@ export async function POST(
|
|||||||
{status: 200}
|
{status: 200}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
await prisma.backup.update({
|
|
||||||
where: { id: backup.id },
|
await db
|
||||||
data: { status: "failed" },
|
.update(drizzleDb.schemas.backup)
|
||||||
});
|
.set({status: 'failed'})
|
||||||
|
.where(eq(drizzleDb.schemas.backup.id, backup.id));
|
||||||
|
|
||||||
eventEmitter.emit('modification', {update: true});
|
eventEmitter.emit('modification', {update: true});
|
||||||
|
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
import {NextResponse} from "next/server";
|
import {NextResponse} from "next/server";
|
||||||
import {isUuidv4} from "@/utils/verify-uuid";
|
import {isUuidv4} from "@/utils/verify-uuid";
|
||||||
import {prisma} from "@/prisma";
|
|
||||||
import {eventEmitter} from "../../../events/route";
|
import {eventEmitter} from "../../../events/route";
|
||||||
|
import * as drizzleDb from "@/db";
|
||||||
|
import {db} from "@/db";
|
||||||
|
import {and, eq} from "drizzle-orm";
|
||||||
|
|
||||||
|
|
||||||
export type BodyResultRestore = {
|
export type BodyResultRestore = {
|
||||||
generatedId: string
|
generatedId: string
|
||||||
status: string
|
status: string
|
||||||
}
|
}
|
||||||
|
type RestorationStatus = 'waiting' | 'ongoing' | 'failed' | 'success';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export async function POST(
|
export async function POST(
|
||||||
@@ -33,43 +36,34 @@ export async function POST(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const agent = await prisma.agent.findFirst({
|
const agent = await db.query.agent.findFirst({
|
||||||
where: {
|
where: eq(drizzleDb.schemas.agent.id, agentId)
|
||||||
id: agentId
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
if (!agent) {
|
if (!agent) {
|
||||||
return NextResponse.json({error: "Agent not found"}, {status: 404})
|
return NextResponse.json({error: "Agent not found"}, {status: 404})
|
||||||
}
|
}
|
||||||
|
|
||||||
const database = await prisma.database.findFirst({
|
const database = await db.query.database.findFirst({
|
||||||
where: {
|
where: eq(drizzleDb.schemas.database.agentDatabaseId, body.generatedId)
|
||||||
generatedId: body.generatedId
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!database) {
|
if (!database) {
|
||||||
return NextResponse.json({error: "Database associated with generatedId provided not found"}, {status: 404})
|
return NextResponse.json({error: "Database associated with generatedId provided not found"}, {status: 404})
|
||||||
}
|
}
|
||||||
|
|
||||||
const restoration = await prisma.restoration.findFirst({
|
const restoration = await db.query.restoration.findFirst({
|
||||||
where: {
|
where: and(eq(drizzleDb.schemas.restoration.status, "ongoing"), eq(drizzleDb.schemas.restoration.databaseId, database.id),)
|
||||||
status : "ongoing",
|
|
||||||
databaseId: database.id
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!restoration) {
|
if (!restoration) {
|
||||||
return NextResponse.json({error: "Unable to fin the corresponding restoration"}, {status: 404})
|
return NextResponse.json({error: "Unable to fin the corresponding restoration"}, {status: 404})
|
||||||
}
|
}
|
||||||
|
|
||||||
await prisma.restoration.update({
|
await db
|
||||||
where:{
|
.update(drizzleDb.schemas.restoration)
|
||||||
id : restoration.id
|
.set({ status: body.status as RestorationStatus })
|
||||||
},
|
.where(eq(drizzleDb.schemas.restoration.id, restoration.id));
|
||||||
data: {
|
|
||||||
status: body.status
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const response = {
|
const response = {
|
||||||
message: true,
|
message: true,
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
import {Agent, Database} from "@prisma/client";
|
|
||||||
import {prisma} from "@/prisma";
|
|
||||||
import {NextResponse} from "next/server";
|
import {NextResponse} from "next/server";
|
||||||
import {Body} from "./route";
|
import {Body} from "./route";
|
||||||
import {isUuidv4} from "@/utils/verify-uuid";
|
import {isUuidv4} from "@/utils/verify-uuid";
|
||||||
import {getFileUrlPresignedLocal} from "@/features/upload/private/upload.action";
|
import {getFileUrlPresignedLocal} from "@/features/upload/private/upload.action";
|
||||||
|
import {Agent} from "@/db/schema/07_agent";
|
||||||
|
import {Database} from "@/db/schema/06_database";
|
||||||
|
import * as drizzleDb from "@/db";
|
||||||
|
import {db as dbClient} from "@/db";
|
||||||
|
import {and, eq} from "drizzle-orm";
|
||||||
|
|
||||||
export async function handleDatabases(body: Body, agent: Agent, lastContact: Date) {
|
export async function handleDatabases(body: Body, agent: Agent, lastContact: Date) {
|
||||||
const databasesResponse = [];
|
const databasesResponse = [];
|
||||||
|
|
||||||
const formatDatabase = (database: Database, backupAction: boolean, restoreAction: boolean, UrlBackup: string) => ({
|
const formatDatabase = (database: Database, backupAction: boolean, restoreAction: boolean, UrlBackup: string) => ({
|
||||||
generatedId: database.generatedId,
|
generatedId: database.agentDatabaseId,
|
||||||
dbms: database.dbms,
|
dbms: database.dbms,
|
||||||
data: {
|
data: {
|
||||||
backup: {
|
backup: {
|
||||||
@@ -25,15 +27,14 @@ export async function handleDatabases(body: Body, agent: Agent, lastContact: Dat
|
|||||||
});
|
});
|
||||||
|
|
||||||
for (const db of body.databases) {
|
for (const db of body.databases) {
|
||||||
const existingDatabase = await prisma.database.findFirst({
|
|
||||||
where: {
|
const existingDatabase = await dbClient.query.database.findFirst({
|
||||||
generatedId: db.generatedId,
|
where: eq(drizzleDb.schemas.database.agentDatabaseId, db.generatedId)
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let backupAction: boolean = false
|
let backupAction: boolean = false
|
||||||
let restoreAction: boolean = false
|
let restoreAction: boolean = false
|
||||||
let UrlBackup: string = null
|
let UrlBackup: string = ""
|
||||||
|
|
||||||
if (!existingDatabase) {
|
if (!existingDatabase) {
|
||||||
if (!isUuidv4(db.generatedId)) {
|
if (!isUuidv4(db.generatedId)) {
|
||||||
@@ -42,74 +43,69 @@ export async function handleDatabases(body: Body, agent: Agent, lastContact: Dat
|
|||||||
{ status: 500 }
|
{ status: 500 }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const databaseCreated = await prisma.database.create({
|
|
||||||
data: {
|
const [databaseCreated] = await dbClient
|
||||||
|
.insert(drizzleDb.schemas.database)
|
||||||
|
.values({
|
||||||
agentId: agent.id,
|
agentId: agent.id,
|
||||||
name: db.name,
|
name: db.name,
|
||||||
dbms: db.dbms,
|
dbms: db.dbms,
|
||||||
generatedId: db.generatedId,
|
agentDatabaseId: db.generatedId,
|
||||||
lastContact: lastContact,
|
lastContact: lastContact,
|
||||||
},
|
})
|
||||||
});
|
.returning();
|
||||||
|
|
||||||
if (databaseCreated) {
|
if (databaseCreated) {
|
||||||
databasesResponse.push(formatDatabase(databaseCreated, backupAction,restoreAction, UrlBackup));
|
databasesResponse.push(formatDatabase(databaseCreated, backupAction,restoreAction, UrlBackup));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const databaseUpdated = await prisma.database.update({
|
|
||||||
where: {
|
|
||||||
id: existingDatabase.id,
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
lastContact: lastContact,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const backup = await prisma.backup.findFirst({
|
|
||||||
where: {
|
|
||||||
databaseId: databaseUpdated.id,
|
const [databaseUpdated] = await dbClient
|
||||||
status: "waiting"
|
.update(drizzleDb.schemas.database)
|
||||||
}
|
.set({ lastContact: lastContact })
|
||||||
|
.where(eq(drizzleDb.schemas.database.id, existingDatabase.id))
|
||||||
|
.returning();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const backup = await dbClient.query.backup.findFirst({
|
||||||
|
where: and(eq(drizzleDb.schemas.backup.databaseId, databaseUpdated.id), eq(drizzleDb.schemas.backup.status,"waiting"))
|
||||||
})
|
})
|
||||||
|
|
||||||
const restoration = await prisma.restoration.findFirst({
|
|
||||||
where:{
|
const restoration = await dbClient.query.restoration.findFirst({
|
||||||
databaseId: databaseUpdated.id,
|
where: and(eq(drizzleDb.schemas.restoration.databaseId, databaseUpdated.id), eq(drizzleDb.schemas.restoration.status,"waiting"))
|
||||||
status: "waiting"
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
if(backup){
|
if(backup){
|
||||||
backupAction = true
|
backupAction = true
|
||||||
await prisma.backup.update({
|
|
||||||
where:{
|
await dbClient
|
||||||
id: backup.id
|
.update(drizzleDb.schemas.backup)
|
||||||
},
|
.set({ status: "ongoing" })
|
||||||
data: {
|
.where(eq(drizzleDb.schemas.backup.id, backup.id));
|
||||||
status: "ongoing"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(restoration){
|
if(restoration){
|
||||||
restoreAction = true
|
restoreAction = true
|
||||||
|
|
||||||
const backupToRestore = await prisma.backup.findFirst({
|
|
||||||
where:{
|
const backupToRestore = await dbClient.query.backup.findFirst({
|
||||||
id: restoration.backupId
|
where: eq(drizzleDb.schemas.backup.id, restoration.backupId),
|
||||||
}
|
|
||||||
})
|
|
||||||
const fileName = backupToRestore.file
|
|
||||||
UrlBackup = await getFileUrlPresignedLocal(fileName)
|
|
||||||
await prisma.restoration.update({
|
|
||||||
where: {
|
|
||||||
id: restoration.id
|
|
||||||
},
|
|
||||||
data:{
|
|
||||||
status: "ongoing"
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const fileName = backupToRestore?.file
|
||||||
|
UrlBackup = await getFileUrlPresignedLocal(fileName ?? "")
|
||||||
|
|
||||||
|
await dbClient
|
||||||
|
.update(drizzleDb.schemas.restoration)
|
||||||
|
.set({ status: "ongoing" })
|
||||||
|
.where(eq(drizzleDb.schemas.restoration.id, restoration.id));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
import {prisma} from "@/prisma";
|
|
||||||
import {NextResponse} from "next/server";
|
import {NextResponse} from "next/server";
|
||||||
import {Dbms} from "@prisma/client";
|
|
||||||
import {getFileUrlPresignedLocal} from "@/features/upload/private/upload.action";
|
import {getFileUrlPresignedLocal} from "@/features/upload/private/upload.action";
|
||||||
import {handleDatabases} from "./helpers";
|
import {handleDatabases} from "./helpers";
|
||||||
import {eventEmitter} from "../../../events/route";
|
import {eventEmitter} from "../../../events/route";
|
||||||
|
import * as drizzleDb from "@/db";
|
||||||
|
import {db} from "@/db";
|
||||||
|
import {EDbmsSchema} from "@/db/schema/types";
|
||||||
|
import {eq} from "drizzle-orm";
|
||||||
|
|
||||||
export type databaseAgent = {
|
export type databaseAgent = {
|
||||||
name: string,
|
name: string,
|
||||||
dbms: Dbms,
|
dbms: EDbmsSchema,
|
||||||
generatedId: string
|
generatedId: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,23 +34,21 @@ export async function POST(
|
|||||||
const body: Body = await request.json();
|
const body: Body = await request.json();
|
||||||
const lastContact = new Date();
|
const lastContact = new Date();
|
||||||
|
|
||||||
const agent = await prisma.agent.findFirst({
|
|
||||||
where: {
|
const agent = await db.query.agent.findFirst({
|
||||||
id: agentId
|
where: eq(drizzleDb.schemas.agent.id, agentId),
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!agent) {
|
if (!agent) {
|
||||||
return NextResponse.json({error: "Agent not found"}, {status: 404})
|
return NextResponse.json({error: "Agent not found"}, {status: 404})
|
||||||
}
|
}
|
||||||
const databasesResponse = await handleDatabases(body, agent, lastContact)
|
const databasesResponse = await handleDatabases(body, agent, lastContact)
|
||||||
await prisma.agent.update({
|
|
||||||
where:{
|
|
||||||
id: agentId,
|
await db
|
||||||
},
|
.update(drizzleDb.schemas.agent)
|
||||||
data:{
|
.set({ lastContact: lastContact })
|
||||||
lastContact: lastContact,
|
.where(eq(drizzleDb.schemas.agent.id, agentId));
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
eventEmitter.emit('modification', {update: true});
|
eventEmitter.emit('modification', {update: true});
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
"use client";
|
"use client"
|
||||||
|
|
||||||
import {ColumnDef} from "@tanstack/react-table";
|
import {ColumnDef} from "@tanstack/react-table";
|
||||||
import {Badge} from "@/components/ui/badge";
|
import {Badge} from "@/components/ui/badge";
|
||||||
import { User } from "@prisma/client";
|
|
||||||
import {updateUserAction} from "@/components/wrappers/dashboard/profile/UserForm/user-form.action";
|
import {updateUserAction} from "@/components/wrappers/dashboard/profile/UserForm/user-form.action";
|
||||||
import {useMutation} from "@tanstack/react-query";
|
import {useMutation} from "@tanstack/react-query";
|
||||||
import {toast} from "sonner";
|
import {toast} from "sonner";
|
||||||
@@ -11,6 +9,8 @@ import { useState } from "react";
|
|||||||
import {Trash2} from "lucide-react";
|
import {Trash2} from "lucide-react";
|
||||||
import {deleteUserAction} from "@/components/wrappers/dashboard/profile/ButtonDeleteAccount/delete-account.action";
|
import {deleteUserAction} from "@/components/wrappers/dashboard/profile/ButtonDeleteAccount/delete-account.action";
|
||||||
import {ButtonWithLoading} from "@/components/wrappers/common/button/button-with-loading";
|
import {ButtonWithLoading} from "@/components/wrappers/common/button/button-with-loading";
|
||||||
|
import {User} from "@/db/schema/01_user";
|
||||||
|
import {useSession} from "@/lib/auth/auth-client";
|
||||||
|
|
||||||
export const usersColumnsAdmin: ColumnDef<User>[] = [
|
export const usersColumnsAdmin: ColumnDef<User>[] = [
|
||||||
{
|
{
|
||||||
@@ -54,14 +54,9 @@ export const usersColumnsAdmin: ColumnDef<User>[] = [
|
|||||||
accessorKey: "updatedAt",
|
accessorKey: "updatedAt",
|
||||||
header: "Updated At",
|
header: "Updated At",
|
||||||
cell: ({row}) => {
|
cell: ({row}) => {
|
||||||
return new Date(row.getValue("updatedAt")).toLocaleString("fr-FR");
|
return new Date(row.getValue("updatedAt")).toLocaleString("fr-FR", {
|
||||||
},
|
timeZone: "Europe/Paris",
|
||||||
},
|
});
|
||||||
{
|
|
||||||
accessorKey: "authMethod",
|
|
||||||
header: "Method",
|
|
||||||
cell: ({ row }) => {
|
|
||||||
return <Badge variant="outline">{row.getValue("authMethod")}</Badge>;
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -69,6 +64,8 @@ export const usersColumnsAdmin: ColumnDef<User>[] = [
|
|||||||
id: "actions",
|
id: "actions",
|
||||||
cell: ({row}) => {
|
cell: ({row}) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const {data: session, isPending} = useSession();
|
||||||
|
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
mutationFn: () => deleteUserAction(row.original.id),
|
mutationFn: () => deleteUserAction(row.original.id),
|
||||||
onSuccess: async () => {
|
onSuccess: async () => {
|
||||||
@@ -77,8 +74,11 @@ export const usersColumnsAdmin: ColumnDef<User>[] = [
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
|
{!session || session?.user.email === row.original.email ? null :
|
||||||
<ButtonWithLoading
|
<ButtonWithLoading
|
||||||
variant="outline"
|
variant="outline"
|
||||||
text=""
|
text=""
|
||||||
@@ -88,6 +88,9 @@ export const usersColumnsAdmin: ColumnDef<User>[] = [
|
|||||||
}}
|
}}
|
||||||
size="icon"
|
size="icon"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { Card, CardContent, CardHeader } from "@/components/ui/card";
|
import { Card, CardContent, CardHeader } from "@/components/ui/card";
|
||||||
import { ProjectWith } from "@/db/schema";
|
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
import {ProjectWith} from "@/db/schema/05_project";
|
||||||
|
|
||||||
export type projectCardProps = {
|
export type projectCardProps = {
|
||||||
data: ProjectWith;
|
data: ProjectWith;
|
||||||
@@ -13,7 +13,7 @@ export const ProjectCard = (props: projectCardProps) => {
|
|||||||
const { data: project, organizationSlug } = props;
|
const { data: project, organizationSlug } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link href={`/dashboard/${organizationSlug}/projects/${project.id}`}>
|
<Link href={`/dashboard/projects/${project.id}`}>
|
||||||
<Card className="flex flex-row justify-between">
|
<Card className="flex flex-row justify-between">
|
||||||
<div className="">
|
<div className="">
|
||||||
<CardHeader>{project.name}</CardHeader>
|
<CardHeader>{project.name}</CardHeader>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export const ProjectDatabaseCard = (props: projectDatabaseCardProps) => {
|
|||||||
const { organizationSlug, data: database, extendedProps: extendedProps } = props;
|
const { organizationSlug, data: database, extendedProps: extendedProps } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link href={`/dashboard/${organizationSlug}/projects/${extendedProps.id}/database/${database.id}`}>
|
<Link href={`/dashboard/projects/${extendedProps.id}/database/${database.id}`}>
|
||||||
<DatabaseCard data={database} />
|
<DatabaseCard data={database} />
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ export const ProjectForm = (props: projectFormProps) => {
|
|||||||
if (project && project.data) {
|
if (project && project.data) {
|
||||||
if (project.data.success) {
|
if (project.data.success) {
|
||||||
project.data.actionSuccess && toast.success(project.data.actionSuccess.message);
|
project.data.actionSuccess && toast.success(project.data.actionSuccess.message);
|
||||||
router.push(`/dashboard/${props.organization.slug}/projects/${project.data.value!.id}`);
|
router.push(`/dashboard/projects/${project.data.value!.id}`);
|
||||||
router.refresh();
|
router.refresh();
|
||||||
} else {
|
} else {
|
||||||
project.data.actionError && toast.error(project.data.actionError.message || "Unknown error occurred.");
|
project.data.actionError && toast.error(project.data.actionError.message || "Unknown error occurred.");
|
||||||
|
|||||||
@@ -2,20 +2,14 @@ import {
|
|||||||
Sidebar,
|
Sidebar,
|
||||||
SidebarContent,
|
SidebarContent,
|
||||||
SidebarFooter,
|
SidebarFooter,
|
||||||
SidebarGroup,
|
|
||||||
SidebarGroupContent,
|
|
||||||
SidebarGroupLabel,
|
|
||||||
SidebarHeader,
|
SidebarHeader,
|
||||||
SidebarMenu as SM,
|
SidebarMenu as SM,
|
||||||
SidebarMenuItem,
|
SidebarMenuItem,
|
||||||
} from "@/components/ui/sidebar";
|
} from "@/components/ui/sidebar";
|
||||||
import {SidebarItem, SidebarMenu} from "@/components/wrappers/dashboard/sideBar/SideBarMenu/SideBarMenu";
|
|
||||||
import {OrganizationCombobox} from "@/components/wrappers/dashboard/organization/organization-combobox";
|
import {OrganizationCombobox} from "@/components/wrappers/dashboard/organization/organization-combobox";
|
||||||
import {SideBarLogo} from "@/components/wrappers/dashboard/sideBar/SideBarLogo/SideBarLogo";
|
import {SideBarLogo} from "@/components/wrappers/dashboard/sideBar/SideBarLogo/SideBarLogo";
|
||||||
import {SideBarFooterCredit} from "@/components/wrappers/dashboard/sideBar/SideBarFooterCredit/SideBarFooterCredit";
|
import {SideBarFooterCredit} from "@/components/wrappers/dashboard/sideBar/SideBarFooterCredit/SideBarFooterCredit";
|
||||||
import {LoggedInButton} from "@/components/wrappers/dashboard/loggedInButton/LoggedInButton";
|
import {LoggedInButton} from "@/components/wrappers/dashboard/loggedInButton/LoggedInButton";
|
||||||
import {Layers, ChartArea, Settings, ShieldHalf} from "lucide-react";
|
|
||||||
import {authClient} from "@/lib/auth/auth-client";
|
|
||||||
import {SidebarContentA} from "./sidebar-content";
|
import {SidebarContentA} from "./sidebar-content";
|
||||||
import {getActiveMember, getOrganization} from "@/lib/auth/auth";
|
import {getActiveMember, getOrganization} from "@/lib/auth/auth";
|
||||||
import {notFound} from "next/navigation";
|
import {notFound} from "next/navigation";
|
||||||
@@ -31,7 +25,6 @@ export async function AppSidebar() {
|
|||||||
|
|
||||||
const organization = await getOrganization({organizationId: member.organizationId});
|
const organization = await getOrganization({organizationId: member.organizationId});
|
||||||
|
|
||||||
//todo: à revoir
|
|
||||||
console.log("organization", organization);
|
console.log("organization", organization);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ export const SidebarContentA = () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const adminItems: SidebarItem[] = [
|
const adminItems: SidebarItem[] = [
|
||||||
{
|
{
|
||||||
type: "list",
|
type: "list",
|
||||||
@@ -62,13 +64,24 @@ export const SidebarContentA = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
activeOrganization && (
|
activeOrganization && (
|
||||||
|
<>
|
||||||
<SidebarGroup>
|
<SidebarGroup>
|
||||||
<SidebarGroupLabel>Application</SidebarGroupLabel>
|
<SidebarGroupLabel>Application</SidebarGroupLabel>
|
||||||
<SidebarGroupContent>
|
<SidebarGroupContent>
|
||||||
<SidebarMenu items={appItems} baseUrl={`/dashboard/${activeOrganization.slug}`} />
|
<SidebarMenu items={appItems} baseUrl={`/dashboard`} />
|
||||||
</SidebarGroupContent>
|
</SidebarGroupContent>
|
||||||
</SidebarGroup>
|
</SidebarGroup>
|
||||||
|
{(session && (session.user.role === "admin" || session.user.role === "superadmin")) && (
|
||||||
|
<SidebarGroup>
|
||||||
|
<SidebarGroupLabel>Administration</SidebarGroupLabel>
|
||||||
|
<SidebarGroupContent>
|
||||||
|
<SidebarMenu items={adminItems} baseUrl={`/dashboard`} />
|
||||||
|
</SidebarGroupContent>
|
||||||
|
</SidebarGroup>
|
||||||
|
)}
|
||||||
|
|
||||||
|
</>
|
||||||
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export const database = pgTable("databases", {
|
|||||||
agentDatabaseId: uuid("agent_database_id").notNull().defaultRandom(),
|
agentDatabaseId: uuid("agent_database_id").notNull().defaultRandom(),
|
||||||
name: text("name").notNull(),
|
name: text("name").notNull(),
|
||||||
dbms: dbmsEnum("dbms").notNull(),
|
dbms: dbmsEnum("dbms").notNull(),
|
||||||
description: text("description").notNull(),
|
description: text("description"),
|
||||||
backupPolicy: text("backup_policy"),
|
backupPolicy: text("backup_policy"),
|
||||||
isWaitingForBackup: boolean("is_waiting_for_backup").default(false).notNull(),
|
isWaitingForBackup: boolean("is_waiting_for_backup").default(false).notNull(),
|
||||||
backupToRestore: text("backup_to_restore"),
|
backupToRestore: text("backup_to_restore"),
|
||||||
@@ -23,8 +23,7 @@ export const database = pgTable("databases", {
|
|||||||
lastContact: timestamp("last_contact"),
|
lastContact: timestamp("last_contact"),
|
||||||
|
|
||||||
projectId: uuid("project_id")
|
projectId: uuid("project_id")
|
||||||
.references(() => project.id)
|
.references(() => project.id),
|
||||||
.notNull(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export const backup = pgTable(
|
export const backup = pgTable(
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
|
import { pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
|
||||||
import { createSelectSchema } from "drizzle-zod";
|
import { createSelectSchema } from "drizzle-zod";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
import {database} from "@/db/schema/06_database";
|
||||||
|
import {relations} from "drizzle-orm";
|
||||||
|
|
||||||
export const agent = pgTable("agents", {
|
export const agent = pgTable("agents", {
|
||||||
id: uuid("id").primaryKey().defaultRandom(),
|
id: uuid("id").primaryKey().defaultRandom(),
|
||||||
@@ -14,3 +16,8 @@ export const agent = pgTable("agents", {
|
|||||||
|
|
||||||
export const agentSchema = createSelectSchema(agent);
|
export const agentSchema = createSelectSchema(agent);
|
||||||
export type Agent = z.infer<typeof agentSchema>;
|
export type Agent = z.infer<typeof agentSchema>;
|
||||||
|
|
||||||
|
|
||||||
|
export const agentRelations = relations(agent, ({ many }) => ({
|
||||||
|
databases: many(database),
|
||||||
|
}));
|
||||||
@@ -97,7 +97,7 @@ export const auth = betterAuth({
|
|||||||
await db.insert(drizzleDb.schemas.member).values({
|
await db.insert(drizzleDb.schemas.member).values({
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
organizationId: defaultOrg.id,
|
organizationId: defaultOrg.id,
|
||||||
role: "orgOwner",
|
role: "owner",
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.warn("Default organization not found. Cannot assign member.");
|
console.warn("Default organization not found. Cannot assign member.");
|
||||||
|
|||||||
Reference in New Issue
Block a user