fix(convex): corrigir memory leak com .collect() sem limite e adicionar otimizacoes

Problema: Convex backend consumindo 16GB+ de RAM causando OOM kills

Correcoes aplicadas:
- Substituido todos os .collect() por .take(LIMIT) em 27+ arquivos
- Adicionado indice by_usbPolicyStatus para otimizar query de maquinas
- Corrigido N+1 problem em alerts.ts usando Map lookup
- Corrigido full table scan em usbPolicy.ts
- Corrigido subscription leaks no frontend (tickets-view, use-ticket-categories)
- Atualizado versao do Convex backend para precompiled-2025-12-04-cc6af4c

Arquivos principais modificados:
- convex/*.ts - limites em todas as queries .collect()
- convex/schema.ts - novo indice by_usbPolicyStatus
- convex/alerts.ts - N+1 fix com Map
- convex/usbPolicy.ts - uso do novo indice
- src/components/tickets/tickets-view.tsx - skip condicional
- src/hooks/use-ticket-categories.ts - skip condicional

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
esdrasrenan 2025-12-09 21:30:06 -03:00
parent a4b46b08ba
commit 638faeb287
33 changed files with 139 additions and 128 deletions

View file

@ -219,7 +219,7 @@ export const list = query({
const dashboards = await ctx.db
.query("dashboards")
.withIndex("by_tenant", (q) => q.eq("tenantId", tenantId))
.collect()
.take(100)
const filtered = (includeArchived ? dashboards : dashboards.filter((d) => !(d.isArchived ?? false))).sort(
(a, b) => b.updatedAt - a.updatedAt,
@ -230,7 +230,7 @@ export const list = query({
const widgets = await ctx.db
.query("dashboardWidgets")
.withIndex("by_dashboard", (q) => q.eq("dashboardId", dashboard._id))
.collect()
.take(100)
return {
...sanitizeDashboard(dashboard),
widgetsCount: widgets.length,
@ -256,14 +256,14 @@ export const get = query({
const widgets = await ctx.db
.query("dashboardWidgets")
.withIndex("by_dashboard_order", (q) => q.eq("dashboardId", dashboardId))
.collect()
.take(100)
widgets.sort((a, b) => a.order - b.order || a.createdAt - b.createdAt)
const shares = await ctx.db
.query("dashboardShares")
.withIndex("by_dashboard", (q) => q.eq("dashboardId", dashboardId))
.collect()
.take(50)
return {
dashboard: sanitizeDashboard(dashboard),
@ -457,7 +457,7 @@ export const updateLayout = mutation({
const widgets = await ctx.db
.query("dashboardWidgets")
.withIndex("by_dashboard", (q) => q.eq("dashboardId", dashboardId))
.collect()
.take(100)
const byKey = new Map<string, Doc<"dashboardWidgets">>()
widgets.forEach((widget) => byKey.set(widget.widgetKey, widget))
@ -518,7 +518,7 @@ export const addWidget = mutation({
const existingWidgets = await ctx.db
.query("dashboardWidgets")
.withIndex("by_dashboard", (q) => q.eq("dashboardId", dashboardId))
.collect()
.take(100)
const widgetId = await ctx.db.insert("dashboardWidgets", {
tenantId,
@ -617,7 +617,7 @@ export const ensureQueueSummaryWidget = mutation({
const widgets = await ctx.db
.query("dashboardWidgets")
.withIndex("by_dashboard_order", (q) => q.eq("dashboardId", dashboardId))
.collect()
.take(100)
widgets.sort((a, b) => a.order - b.order || a.createdAt - b.createdAt)
@ -871,7 +871,7 @@ export const upsertShare = mutation({
const existingShares = await ctx.db
.query("dashboardShares")
.withIndex("by_dashboard", (q) => q.eq("dashboardId", dashboardId))
.collect()
.take(50)
const now = Date.now()
let shareDoc = existingShares.find((share) => share.audience === audience)
@ -917,7 +917,7 @@ export const revokeShareToken = mutation({
const shares = await ctx.db
.query("dashboardShares")
.withIndex("by_dashboard", (q) => q.eq("dashboardId", dashboardId))
.collect()
.take(50)
for (const share of shares) {
if (share.audience === "public-link") {