feat: overhaul admin user management and desktop UX

This commit is contained in:
Esdras Renan 2025-10-13 10:36:38 -03:00
parent 7d6f3bea01
commit ecad81b0ea
16 changed files with 1546 additions and 395 deletions

View file

@ -16,6 +16,20 @@ type NormalizedIdentifiers = {
serials: string[]
}
function normalizeCompanySlug(input?: string | null): string | undefined {
if (!input) return undefined
const trimmed = input.trim()
if (!trimmed) return undefined
const ascii = trimmed
.normalize("NFD")
.replace(/[\u0300-\u036f]/g, "")
.replace(/[\u2013\u2014]/g, "-")
const sanitized = ascii.replace(/[^\w\s-]/g, "").replace(/[_\s]+/g, "-")
const collapsed = sanitized.replace(/-+/g, "-").toLowerCase()
const normalized = collapsed.replace(/^-+|-+$/g, "")
return normalized || undefined
}
function getProvisioningSecret() {
const secret = process.env["MACHINE_PROVISIONING_SECRET"]
if (!secret) {
@ -92,10 +106,11 @@ async function ensureCompany(
tenantId: string,
companySlug?: string
): Promise<{ companyId?: Id<"companies">; companySlug?: string }> {
if (!companySlug) return {}
const normalized = normalizeCompanySlug(companySlug)
if (!normalized) return {}
const company = await ctx.db
.query("companies")
.withIndex("by_tenant_slug", (q: any) => q.eq("tenantId", tenantId).eq("slug", companySlug))
.withIndex("by_tenant_slug", (q: any) => q.eq("tenantId", tenantId).eq("slug", normalized))
.unique()
if (!company) {
throw new ConvexError("Empresa não encontrada para o tenant informado")
@ -317,9 +332,10 @@ export const register = mutation({
}
const tenantId = args.tenantId ?? DEFAULT_TENANT_ID
const normalizedCompanySlug = normalizeCompanySlug(args.companySlug)
const identifiers = normalizeIdentifiers(args.macAddresses, args.serialNumbers)
const fingerprint = computeFingerprint(tenantId, args.companySlug, args.hostname, identifiers)
const { companyId, companySlug } = await ensureCompany(ctx, tenantId, args.companySlug)
const fingerprint = computeFingerprint(tenantId, normalizedCompanySlug, args.hostname, identifiers)
const { companyId, companySlug } = await ensureCompany(ctx, tenantId, normalizedCompanySlug)
const now = Date.now()
const metadataPatch = args.metadata && typeof args.metadata === "object" ? (args.metadata as Record<string, unknown>) : undefined
@ -454,9 +470,10 @@ export const upsertInventory = mutation({
}
const tenantId = args.tenantId ?? DEFAULT_TENANT_ID
const normalizedCompanySlug = normalizeCompanySlug(args.companySlug)
const identifiers = normalizeIdentifiers(args.macAddresses, args.serialNumbers)
const fingerprint = computeFingerprint(tenantId, args.companySlug, args.hostname, identifiers)
const { companyId, companySlug } = await ensureCompany(ctx, tenantId, args.companySlug)
const fingerprint = computeFingerprint(tenantId, normalizedCompanySlug, args.hostname, identifiers)
const { companyId, companySlug } = await ensureCompany(ctx, tenantId, normalizedCompanySlug)
const now = Date.now()
const metadataPatch: Record<string, unknown> = {}