feat(db): mesh data model — meshes, members, invites, audit log

- pgSchema "mesh" with 4 tables isolating the peer mesh domain
- Enums: visibility, transport, tier, role
- audit_log is metadata-only (E2E encryption enforced at broker/client)
- Cascade on mesh delete, soft-delete via archivedAt/revokedAt

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alejandro Gutiérrez
2026-04-04 21:19:32 +01:00
commit d3163a5bff
1384 changed files with 314925 additions and 0 deletions

View File

@@ -0,0 +1,29 @@
import { cn } from "@turbostarter/ui";
export const DetailsList = ({
className,
...props
}: React.ComponentProps<"ul">) => {
return (
<ul
className={cn(
"xl:*:px- -m-px grid grid-cols-1 gap-y-8 @lg/details:grid-cols-2 @lg/details:gap-y-0 @3xl/details:grid-cols-3",
className,
)}
{...props}
/>
);
};
export const DetailsListItem = ({
className,
...props
}: React.ComponentProps<"li">) => (
<li
className={cn(
"px-1 @lg/details:border @lg/details:px-6 @lg/details:py-8 @3xl/details:px-8 @3xl/details:py-10 [&:not(:first-child)]:-ms-px [&:not(:first-child)]:-mt-px",
className,
)}
{...props}
/>
);

View File

@@ -0,0 +1,90 @@
import { memo } from "react";
import { isKey } from "@turbostarter/i18n";
import { getTranslation } from "@turbostarter/i18n/server";
import { Icons } from "@turbostarter/ui-web/icons";
import {
SidebarGroup,
SidebarGroupLabel,
SidebarMenuItem,
SidebarRail,
} from "@turbostarter/ui-web/sidebar";
import { SidebarMenu } from "@turbostarter/ui-web/sidebar";
import {
SidebarContent,
SidebarFooter,
SidebarHeader,
} from "@turbostarter/ui-web/sidebar";
import { Sidebar } from "@turbostarter/ui-web/sidebar";
import { pathsConfig } from "~/config/paths";
import { SidebarLink } from "~/modules/common/layout/dashboard/sidebar-link";
import { TurboLink } from "~/modules/common/turbo-link";
import { UserNavigation } from "~/modules/user/user-navigation";
import type { User } from "@turbostarter/auth";
import type { Icon } from "@turbostarter/ui-web/icons";
interface AdminSidebarProps {
readonly user: User;
readonly menu: {
label: string;
items: {
title: string;
href: string;
icon: Icon;
}[];
}[];
}
export const AdminSidebar = memo<AdminSidebarProps>(async ({ user, menu }) => {
const { t, i18n } = await getTranslation({ ns: "common" });
return (
<Sidebar collapsible="icon">
<SidebarHeader>
<TurboLink
href={pathsConfig.index}
className="flex items-center gap-3 p-2 transition-[padding] group-data-[collapsible=icon]:p-0.5"
>
<Icons.Logo className="text-primary h-8 transition-[width,height]" />
<Icons.LogoText className="text-foreground h-4 group-data-[collapsible=icon]:hidden" />
</TurboLink>
</SidebarHeader>
<SidebarContent>
{menu.map((group) => (
<SidebarGroup key={group.label}>
<SidebarGroupLabel className="uppercase">
{isKey(group.label, i18n, "common")
? t(group.label)
: group.label}
</SidebarGroupLabel>
<SidebarMenu>
{group.items.map((item) => {
const title = isKey(item.title, i18n, "common")
? t(item.title)
: item.title;
return (
<SidebarMenuItem key={item.href}>
<SidebarLink href={item.href} tooltip={title}>
<item.icon />
<span>{title}</span>
</SidebarLink>
</SidebarMenuItem>
);
})}
</SidebarMenu>
</SidebarGroup>
))}
</SidebarContent>
<SidebarFooter>
<SidebarMenu>
<SidebarMenuItem>
<UserNavigation user={user} />
</SidebarMenuItem>
</SidebarMenu>
</SidebarFooter>
<SidebarRail />
</Sidebar>
);
});