feat: dispositivos e ajustes de csat e relatórios

This commit is contained in:
codex-bot 2025-11-03 19:29:50 -03:00
parent 25d2a9b062
commit e0ef66555d
86 changed files with 5811 additions and 992 deletions

View file

@ -169,6 +169,26 @@ export default defineSchema({
})
)
),
csatScore: v.optional(v.number()),
csatMaxScore: v.optional(v.number()),
csatComment: v.optional(v.string()),
csatRatedAt: v.optional(v.number()),
csatRatedBy: v.optional(v.id("users")),
csatAssigneeId: v.optional(v.id("users")),
csatAssigneeSnapshot: v.optional(
v.object({
name: v.string(),
email: v.optional(v.string()),
avatarUrl: v.optional(v.string()),
teams: v.optional(v.array(v.string())),
})
),
formTemplate: v.optional(v.string()),
relatedTicketIds: v.optional(v.array(v.id("tickets"))),
resolvedWithTicketId: v.optional(v.id("tickets")),
reopenDeadline: v.optional(v.number()),
reopenedAt: v.optional(v.number()),
chatEnabled: v.optional(v.boolean()),
totalWorkedMs: v.optional(v.number()),
internalWorkedMs: v.optional(v.number()),
externalWorkedMs: v.optional(v.number()),
@ -183,7 +203,9 @@ export default defineSchema({
.index("by_tenant_machine", ["tenantId", "machineId"])
.index("by_tenant", ["tenantId"])
.index("by_tenant_created", ["tenantId", "createdAt"])
.index("by_tenant_company_created", ["tenantId", "companyId", "createdAt"]),
.index("by_tenant_resolved", ["tenantId", "resolvedAt"])
.index("by_tenant_company_created", ["tenantId", "companyId", "createdAt"])
.index("by_tenant_company_resolved", ["tenantId", "companyId", "resolvedAt"]),
ticketComments: defineTable({
ticketId: v.id("tickets"),
@ -221,6 +243,45 @@ export default defineSchema({
createdAt: v.number(),
}).index("by_ticket", ["ticketId"]),
ticketChatMessages: defineTable({
ticketId: v.id("tickets"),
authorId: v.id("users"),
authorSnapshot: v.optional(
v.object({
name: v.string(),
email: v.optional(v.string()),
avatarUrl: v.optional(v.string()),
teams: v.optional(v.array(v.string())),
})
),
body: v.string(),
attachments: v.optional(
v.array(
v.object({
storageId: v.id("_storage"),
name: v.string(),
size: v.optional(v.number()),
type: v.optional(v.string()),
})
)
),
notifiedAt: v.optional(v.number()),
createdAt: v.number(),
updatedAt: v.number(),
tenantId: v.string(),
companyId: v.optional(v.id("companies")),
readBy: v.optional(
v.array(
v.object({
userId: v.id("users"),
readAt: v.number(),
})
)
),
})
.index("by_ticket_created", ["ticketId", "createdAt"])
.index("by_tenant_created", ["tenantId", "createdAt"]),
commentTemplates: defineTable({
tenantId: v.string(),
kind: v.optional(v.string()),
@ -291,11 +352,29 @@ export default defineSchema({
})
)
),
scope: v.optional(v.string()),
createdAt: v.number(),
updatedAt: v.number(),
})
.index("by_tenant_key", ["tenantId", "key"])
.index("by_tenant_order", ["tenantId", "order"])
.index("by_tenant_scope", ["tenantId", "scope"])
.index("by_tenant", ["tenantId"]),
ticketFormSettings: defineTable({
tenantId: v.string(),
template: v.string(),
scope: v.string(), // tenant | company | user
companyId: v.optional(v.id("companies")),
userId: v.optional(v.id("users")),
enabled: v.boolean(),
createdAt: v.number(),
updatedAt: v.number(),
actorId: v.optional(v.id("users")),
})
.index("by_tenant_template_scope", ["tenantId", "template", "scope"])
.index("by_tenant_template_company", ["tenantId", "template", "companyId"])
.index("by_tenant_template_user", ["tenantId", "template", "userId"])
.index("by_tenant", ["tenantId"]),
userInvites: defineTable({
@ -339,6 +418,23 @@ export default defineSchema({
serialNumbers: v.array(v.string()),
fingerprint: v.string(),
metadata: v.optional(v.any()),
displayName: v.optional(v.string()),
deviceType: v.optional(v.string()),
devicePlatform: v.optional(v.string()),
deviceProfile: v.optional(v.any()),
managementMode: v.optional(v.string()),
customFields: v.optional(
v.array(
v.object({
fieldId: v.id("deviceFields"),
fieldKey: v.string(),
label: v.string(),
type: v.string(),
value: v.any(),
displayValue: v.optional(v.string()),
})
)
),
lastHeartbeatAt: v.optional(v.number()),
status: v.optional(v.string()),
isActive: v.optional(v.boolean()),
@ -382,4 +478,58 @@ export default defineSchema({
.index("by_tenant_machine", ["tenantId", "machineId"])
.index("by_machine_created", ["machineId", "createdAt"])
.index("by_machine_revoked_expires", ["machineId", "revoked", "expiresAt"]),
deviceFields: defineTable({
tenantId: v.string(),
key: v.string(),
label: v.string(),
description: v.optional(v.string()),
type: v.string(),
required: v.optional(v.boolean()),
options: v.optional(
v.array(
v.object({
value: v.string(),
label: v.string(),
})
)
),
scope: v.optional(v.string()),
companyId: v.optional(v.id("companies")),
order: v.number(),
createdAt: v.number(),
updatedAt: v.number(),
createdBy: v.optional(v.id("users")),
updatedBy: v.optional(v.id("users")),
})
.index("by_tenant_order", ["tenantId", "order"])
.index("by_tenant_key", ["tenantId", "key"])
.index("by_tenant_company", ["tenantId", "companyId"])
.index("by_tenant_scope", ["tenantId", "scope"])
.index("by_tenant", ["tenantId"]),
deviceExportTemplates: defineTable({
tenantId: v.string(),
name: v.string(),
slug: v.string(),
description: v.optional(v.string()),
columns: v.array(
v.object({
key: v.string(),
label: v.optional(v.string()),
})
),
filters: v.optional(v.any()),
companyId: v.optional(v.id("companies")),
isDefault: v.optional(v.boolean()),
isActive: v.optional(v.boolean()),
createdBy: v.optional(v.id("users")),
updatedBy: v.optional(v.id("users")),
createdAt: v.number(),
updatedAt: v.number(),
})
.index("by_tenant_slug", ["tenantId", "slug"])
.index("by_tenant_company", ["tenantId", "companyId"])
.index("by_tenant_default", ["tenantId", "isDefault"])
.index("by_tenant", ["tenantId"]),
});