feat: export reports as xlsx and add machine inventory

This commit is contained in:
Esdras Renan 2025-10-27 18:00:28 -03:00
parent 29b865885c
commit 714b199879
34 changed files with 2304 additions and 245 deletions

View file

@ -15,6 +15,8 @@ export const ensureUser = mutation({
role: v.optional(v.string()),
teams: v.optional(v.array(v.string())),
companyId: v.optional(v.id("companies")),
jobTitle: v.optional(v.string()),
managerId: v.optional(v.id("users")),
},
handler: async (ctx, args) => {
const existing = await ctx.db
@ -23,23 +25,38 @@ export const ensureUser = mutation({
.first();
const reconcile = async (record: typeof existing) => {
if (!record) return null;
const hasJobTitleArg = Object.prototype.hasOwnProperty.call(args, "jobTitle");
const hasManagerArg = Object.prototype.hasOwnProperty.call(args, "managerId");
const jobTitleChanged = hasJobTitleArg ? (record.jobTitle ?? null) !== (args.jobTitle ?? null) : false;
const managerChanged = hasManagerArg
? String(record.managerId ?? "") !== String(args.managerId ?? "")
: false;
const shouldPatch =
record.tenantId !== args.tenantId ||
(args.role && record.role !== args.role) ||
(args.avatarUrl && record.avatarUrl !== args.avatarUrl) ||
record.name !== args.name ||
(args.teams && JSON.stringify(args.teams) !== JSON.stringify(record.teams ?? [])) ||
(args.companyId && record.companyId !== args.companyId);
(args.companyId && record.companyId !== args.companyId) ||
jobTitleChanged ||
managerChanged;
if (shouldPatch) {
await ctx.db.patch(record._id, {
const patch: Record<string, unknown> = {
tenantId: args.tenantId,
role: args.role ?? record.role,
avatarUrl: args.avatarUrl ?? record.avatarUrl,
name: args.name,
teams: args.teams ?? record.teams,
companyId: args.companyId ?? record.companyId,
});
};
if (hasJobTitleArg) {
patch.jobTitle = args.jobTitle ?? undefined;
}
if (hasManagerArg) {
patch.managerId = args.managerId ?? undefined;
}
await ctx.db.patch(record._id, patch);
const updated = await ctx.db.get(record._id);
if (updated) {
return updated;
@ -70,6 +87,8 @@ export const ensureUser = mutation({
role: args.role ?? "AGENT",
teams: args.teams ?? [],
companyId: args.companyId,
jobTitle: args.jobTitle,
managerId: args.managerId,
});
return await ctx.db.get(id);
},
@ -151,6 +170,8 @@ export const listCustomers = query({
companyName: company?.name ?? null,
companyIsAvulso: Boolean(company?.isAvulso),
avatarUrl: user.avatarUrl ?? null,
jobTitle: user.jobTitle ?? null,
managerId: user.managerId ? String(user.managerId) : null,
}
})
.sort((a, b) => a.name.localeCompare(b.name ?? "", "pt-BR"))
@ -239,6 +260,17 @@ export const deleteUser = mutation({
}
}
// Limpa vínculo de subordinados
const directReports = await ctx.db
.query("users")
.withIndex("by_tenant_manager", (q) => q.eq("tenantId", user.tenantId).eq("managerId", userId))
.collect();
await Promise.all(
directReports.map(async (report) => {
await ctx.db.patch(report._id, { managerId: undefined });
})
);
await ctx.db.delete(userId);
return { status: "deleted" };
},