feat(reports): adiciona opcao Todas as empresas no relatorio por empresa
- Frontend: usa usePersistentCompanyFilter para persistir selecao - Frontend: adiciona opcao "Todas as empresas" como primeira opcao - Backend: torna companyId opcional na query companyOverview - Backend: usa resolveScopedCompanyId para scoping de gestores 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
14480df9f3
commit
8a237a820d
2 changed files with 59 additions and 39 deletions
|
|
@ -2406,18 +2406,20 @@ export const companyOverview = query({
|
|||
args: {
|
||||
tenantId: v.string(),
|
||||
viewerId: v.id("users"),
|
||||
companyId: v.id("companies"),
|
||||
companyId: v.optional(v.id("companies")),
|
||||
range: v.optional(v.string()),
|
||||
},
|
||||
handler: async (ctx, { tenantId, viewerId, companyId, range }) => {
|
||||
const viewer = await requireStaff(ctx, viewerId, tenantId);
|
||||
if (viewer.role === "MANAGER" && viewer.user.companyId && viewer.user.companyId !== companyId) {
|
||||
throw new ConvexError("Gestores só podem consultar relatórios da própria empresa");
|
||||
}
|
||||
const scopedCompanyId = resolveScopedCompanyId(viewer, companyId);
|
||||
|
||||
const company = await ctx.db.get(companyId);
|
||||
if (!company || company.tenantId !== tenantId) {
|
||||
throw new ConvexError("Empresa não encontrada");
|
||||
// Buscar dados da empresa selecionada (se houver)
|
||||
let company: Doc<"companies"> | null = null;
|
||||
if (scopedCompanyId) {
|
||||
company = await ctx.db.get(scopedCompanyId);
|
||||
if (!company || company.tenantId !== tenantId) {
|
||||
throw new ConvexError("Empresa não encontrada");
|
||||
}
|
||||
}
|
||||
|
||||
const normalizedRange = (range ?? "30d").toLowerCase();
|
||||
|
|
@ -2426,20 +2428,35 @@ export const companyOverview = query({
|
|||
const startMs = now - rangeDays * ONE_DAY_MS;
|
||||
|
||||
// Limita consultas para evitar OOM em empresas muito grandes
|
||||
const tickets = await ctx.db
|
||||
.query("tickets")
|
||||
.withIndex("by_tenant_company", (q) => q.eq("tenantId", tenantId).eq("companyId", companyId))
|
||||
.take(2000);
|
||||
const tickets = scopedCompanyId
|
||||
? await ctx.db
|
||||
.query("tickets")
|
||||
.withIndex("by_tenant_company", (q) => q.eq("tenantId", tenantId).eq("companyId", scopedCompanyId))
|
||||
.take(2000)
|
||||
: await ctx.db
|
||||
.query("tickets")
|
||||
.withIndex("by_tenant", (q) => q.eq("tenantId", tenantId))
|
||||
.take(2000);
|
||||
|
||||
const machines = await ctx.db
|
||||
.query("machines")
|
||||
.withIndex("by_tenant_company", (q) => q.eq("tenantId", tenantId).eq("companyId", companyId))
|
||||
.take(1000);
|
||||
const machines = scopedCompanyId
|
||||
? await ctx.db
|
||||
.query("machines")
|
||||
.withIndex("by_tenant_company", (q) => q.eq("tenantId", tenantId).eq("companyId", scopedCompanyId))
|
||||
.take(1000)
|
||||
: await ctx.db
|
||||
.query("machines")
|
||||
.withIndex("by_tenant", (q) => q.eq("tenantId", tenantId))
|
||||
.take(1000);
|
||||
|
||||
const users = await ctx.db
|
||||
.query("users")
|
||||
.withIndex("by_tenant_company", (q) => q.eq("tenantId", tenantId).eq("companyId", companyId))
|
||||
.take(500);
|
||||
const users = scopedCompanyId
|
||||
? await ctx.db
|
||||
.query("users")
|
||||
.withIndex("by_tenant_company", (q) => q.eq("tenantId", tenantId).eq("companyId", scopedCompanyId))
|
||||
.take(500)
|
||||
: await ctx.db
|
||||
.query("users")
|
||||
.withIndex("by_tenant", (q) => q.eq("tenantId", tenantId))
|
||||
.take(500);
|
||||
|
||||
const statusCounts = {} as Record<string, number>;
|
||||
const priorityCounts = {} as Record<string, number>;
|
||||
|
|
@ -2534,11 +2551,13 @@ export const companyOverview = query({
|
|||
});
|
||||
|
||||
return {
|
||||
company: {
|
||||
id: company._id,
|
||||
name: company.name,
|
||||
isAvulso: company.isAvulso ?? false,
|
||||
},
|
||||
company: company
|
||||
? {
|
||||
id: company._id,
|
||||
name: company.name,
|
||||
isAvulso: company.isAvulso ?? false,
|
||||
}
|
||||
: null,
|
||||
rangeDays,
|
||||
generatedAt: now,
|
||||
tickets: {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue