- 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>
43 lines
979 B
TypeScript
43 lines
979 B
TypeScript
import { auth } from "@turbostarter/auth/server";
|
|
import { HttpStatusCode } from "@turbostarter/shared/constants";
|
|
import { HttpException, slugify } from "@turbostarter/shared/utils";
|
|
|
|
const MAX_ATTEMPTS = 3;
|
|
|
|
export const generateSlug = async (name: string) => {
|
|
const base = slugify(name, {
|
|
lower: true,
|
|
remove: /[.,'+:()]/g,
|
|
});
|
|
|
|
let slug = base;
|
|
let isAvailable = false;
|
|
|
|
for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {
|
|
let check;
|
|
try {
|
|
check = await auth.api.checkOrganizationSlug({
|
|
body: { slug },
|
|
});
|
|
} catch {
|
|
check = { status: false };
|
|
}
|
|
|
|
if (check.status) {
|
|
isAvailable = true;
|
|
break;
|
|
}
|
|
|
|
const randomDigits = Math.floor(100000 + Math.random() * 900000).toString();
|
|
slug = `${base}-${randomDigits}`;
|
|
}
|
|
|
|
if (!isAvailable) {
|
|
throw new HttpException(HttpStatusCode.BAD_REQUEST, {
|
|
code: "organization:error.slugNotAvailable",
|
|
});
|
|
}
|
|
|
|
return { slug };
|
|
};
|