feat: adicionar construtor de dashboards e api de métricas

This commit is contained in:
Esdras Renan 2025-11-04 20:37:34 -03:00
parent c2acd65764
commit 741f1d7f9c
14 changed files with 4356 additions and 9 deletions

View file

@ -1,6 +1,35 @@
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
const gridLayoutItem = v.object({
i: v.string(),
x: v.number(),
y: v.number(),
w: v.number(),
h: v.number(),
minW: v.optional(v.number()),
minH: v.optional(v.number()),
static: v.optional(v.boolean()),
});
const widgetLayout = v.object({
x: v.number(),
y: v.number(),
w: v.number(),
h: v.number(),
minW: v.optional(v.number()),
minH: v.optional(v.number()),
static: v.optional(v.boolean()),
});
const tvSection = v.object({
id: v.string(),
title: v.optional(v.string()),
description: v.optional(v.string()),
widgetKeys: v.array(v.string()),
durationSeconds: v.optional(v.number()),
});
export default defineSchema({
users: defineTable({
tenantId: v.string(),
@ -77,6 +106,77 @@ export default defineSchema({
.index("by_tenant_created", ["tenantId", "createdAt"])
.index("by_tenant", ["tenantId"]),
dashboards: defineTable({
tenantId: v.string(),
name: v.string(),
description: v.optional(v.string()),
aspectRatio: v.optional(v.string()),
theme: v.optional(v.string()),
filters: v.optional(v.any()),
layout: v.optional(v.array(gridLayoutItem)),
sections: v.optional(v.array(tvSection)),
tvIntervalSeconds: v.optional(v.number()),
readySelector: v.optional(v.string()),
createdBy: v.id("users"),
updatedBy: v.optional(v.id("users")),
createdAt: v.number(),
updatedAt: v.number(),
isArchived: v.optional(v.boolean()),
})
.index("by_tenant", ["tenantId"])
.index("by_tenant_created", ["tenantId", "createdAt"]),
dashboardWidgets: defineTable({
tenantId: v.string(),
dashboardId: v.id("dashboards"),
widgetKey: v.string(),
title: v.optional(v.string()),
type: v.string(),
config: v.any(),
layout: v.optional(widgetLayout),
order: v.number(),
createdBy: v.id("users"),
updatedBy: v.optional(v.id("users")),
createdAt: v.number(),
updatedAt: v.number(),
isHidden: v.optional(v.boolean()),
})
.index("by_dashboard", ["dashboardId"])
.index("by_dashboard_order", ["dashboardId", "order"])
.index("by_dashboard_key", ["dashboardId", "widgetKey"])
.index("by_tenant", ["tenantId"]),
metricDefinitions: defineTable({
tenantId: v.string(),
key: v.string(),
name: v.string(),
description: v.optional(v.string()),
version: v.number(),
definition: v.optional(v.any()),
createdBy: v.id("users"),
updatedBy: v.optional(v.id("users")),
createdAt: v.number(),
updatedAt: v.number(),
tags: v.optional(v.array(v.string())),
})
.index("by_tenant_key", ["tenantId", "key"])
.index("by_tenant", ["tenantId"]),
dashboardShares: defineTable({
tenantId: v.string(),
dashboardId: v.id("dashboards"),
audience: v.string(),
token: v.optional(v.string()),
expiresAt: v.optional(v.number()),
canEdit: v.boolean(),
createdBy: v.id("users"),
createdAt: v.number(),
lastAccessAt: v.optional(v.number()),
})
.index("by_dashboard", ["dashboardId"])
.index("by_token", ["token"])
.index("by_tenant", ["tenantId"]),
queues: defineTable({
tenantId: v.string(),
name: v.string(),