Files
claudemesh/packages/api/src/modules/organization/queries/generate-slug.ts
Alejandro Gutiérrez d3163a5bff 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>
2026-04-04 21:19:32 +01:00

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 };
};