feat: SSE para chat desktop, rate limiting, retry, testes e atualizacao de stack
- Implementa Server-Sent Events (SSE) para chat no desktop com fallback HTTP - Adiciona rate limiting nas APIs de chat (poll, messages, sessions) - Adiciona retry com backoff exponencial para mutations - Cria testes para modulo liveChat (20 testes) - Corrige testes de SMTP (unit tests para extractEnvelopeAddress) - Adiciona indice by_status_lastActivity para cron de sessoes inativas - Atualiza stack: Bun 1.3.4, React 19, recharts 3, noble/hashes 2, etc 🤖 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
0e0bd9a49c
commit
d01c37522f
19 changed files with 1465 additions and 443 deletions
|
|
@ -3,8 +3,8 @@ import { action, mutation, query, type MutationCtx, type QueryCtx } from "./_gen
|
|||
import { ConvexError } from "convex/values"
|
||||
import { api } from "./_generated/api"
|
||||
import type { Doc, Id } from "./_generated/dataModel"
|
||||
import { sha256 } from "@noble/hashes/sha256"
|
||||
import { bytesToHex as toHex } from "@noble/hashes/utils"
|
||||
import { sha256 } from "@noble/hashes/sha2.js"
|
||||
import { bytesToHex as toHex } from "@noble/hashes/utils.js"
|
||||
|
||||
// ============================================
|
||||
// HELPERS
|
||||
|
|
@ -728,14 +728,11 @@ export const autoEndInactiveSessions = mutation({
|
|||
// Limitar a 50 sessões por execução para evitar timeout do cron (30s)
|
||||
const maxSessionsPerRun = 50
|
||||
|
||||
// Buscar sessões ativas com inatividade > 5 minutos (com limite)
|
||||
// Buscar sessões ativas com inatividade > 5 minutos (usando índice otimizado)
|
||||
const inactiveSessions = await ctx.db
|
||||
.query("liveChatSessions")
|
||||
.filter((q) =>
|
||||
q.and(
|
||||
q.eq(q.field("status"), "ACTIVE"),
|
||||
q.lt(q.field("lastActivityAt"), cutoffTime)
|
||||
)
|
||||
.withIndex("by_status_lastActivity", (q) =>
|
||||
q.eq("status", "ACTIVE").lt("lastActivityAt", cutoffTime)
|
||||
)
|
||||
.take(maxSessionsPerRun)
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ import { mutation, query } from "./_generated/server"
|
|||
import { api } from "./_generated/api"
|
||||
import { paginationOptsValidator } from "convex/server"
|
||||
import { ConvexError, v, Infer } from "convex/values"
|
||||
import { sha256 } from "@noble/hashes/sha256"
|
||||
import { randomBytes } from "@noble/hashes/utils"
|
||||
import { sha256 } from "@noble/hashes/sha2.js"
|
||||
import { randomBytes } from "@noble/hashes/utils.js"
|
||||
import type { Doc, Id } from "./_generated/dataModel"
|
||||
import type { MutationCtx, QueryCtx } from "./_generated/server"
|
||||
import { normalizeStatus } from "./tickets"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { randomBytes } from "@noble/hashes/utils"
|
||||
import { randomBytes } from "@noble/hashes/utils.js"
|
||||
import { ConvexError, v } from "convex/values"
|
||||
|
||||
import { mutation, query } from "./_generated/server"
|
||||
|
|
|
|||
|
|
@ -433,7 +433,8 @@ export default defineSchema({
|
|||
.index("by_ticket", ["ticketId"])
|
||||
.index("by_machine_status", ["machineId", "status"])
|
||||
.index("by_tenant_machine", ["tenantId", "machineId"])
|
||||
.index("by_tenant_status", ["tenantId", "status"]),
|
||||
.index("by_tenant_status", ["tenantId", "status"])
|
||||
.index("by_status_lastActivity", ["status", "lastActivityAt"]),
|
||||
|
||||
commentTemplates: defineTable({
|
||||
tenantId: v.string(),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { v } from "convex/values"
|
||||
import { mutation, query } from "./_generated/server"
|
||||
import type { Id, Doc } from "./_generated/dataModel"
|
||||
import { sha256 } from "@noble/hashes/sha256"
|
||||
import { sha256 } from "@noble/hashes/sha2.js"
|
||||
|
||||
const DEFAULT_TENANT_ID = "default"
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue