Files
sgse-app/packages/backend/convex/tables/flows.ts

133 lines
4.1 KiB
TypeScript

import { defineTable } from 'convex/server';
import { type Infer, v } from 'convex/values';
// Status de templates de fluxo
export const flowTemplateStatus = v.union(
v.literal('draft'),
v.literal('published'),
v.literal('archived')
);
export type FlowTemplateStatus = Infer<typeof flowTemplateStatus>;
// Status de instâncias de fluxo
export const flowInstanceStatus = v.union(
v.literal('active'),
v.literal('completed'),
v.literal('cancelled')
);
export type FlowInstanceStatus = Infer<typeof flowInstanceStatus>;
// Status de passos de instância de fluxo
export const flowInstanceStepStatus = v.union(
v.literal('pending'),
v.literal('in_progress'),
v.literal('completed'),
v.literal('blocked')
);
export type FlowInstanceStepStatus = Infer<typeof flowInstanceStepStatus>;
export const flowsTables = {
// Templates de fluxo
flowTemplates: defineTable({
name: v.string(),
description: v.optional(v.string()),
status: flowTemplateStatus,
createdBy: v.id('usuarios'),
createdAt: v.number()
})
.index('by_status', ['status'])
.index('by_createdBy', ['createdBy']),
// Passos de template de fluxo
flowSteps: defineTable({
flowTemplateId: v.id('flowTemplates'),
name: v.string(),
description: v.optional(v.string()),
position: v.number(),
expectedDuration: v.number(), // em dias
setorId: v.id('setores'),
defaultAssigneeId: v.optional(v.id('usuarios')),
requiredDocuments: v.optional(v.array(v.string()))
})
.index('by_flowTemplateId', ['flowTemplateId'])
.index('by_flowTemplateId_and_position', ['flowTemplateId', 'position']),
// Instâncias de fluxo
flowInstances: defineTable({
flowTemplateId: v.id('flowTemplates'),
contratoId: v.optional(v.id('contratos')),
managerId: v.id('usuarios'),
status: flowInstanceStatus,
startedAt: v.number(),
finishedAt: v.optional(v.number()),
currentStepId: v.optional(v.id('flowInstanceSteps'))
})
.index('by_flowTemplateId', ['flowTemplateId'])
.index('by_contratoId', ['contratoId'])
.index('by_managerId', ['managerId'])
.index('by_status', ['status']),
// Passos de instância de fluxo
flowInstanceSteps: defineTable({
flowInstanceId: v.id('flowInstances'),
flowStepId: v.id('flowSteps'),
setorId: v.id('setores'),
assignedToId: v.optional(v.id('usuarios')),
status: flowInstanceStepStatus,
startedAt: v.optional(v.number()),
finishedAt: v.optional(v.number()),
notes: v.optional(v.string()),
notesUpdatedBy: v.optional(v.id('usuarios')),
notesUpdatedAt: v.optional(v.number()),
dueDate: v.optional(v.number())
})
.index('by_flowInstanceId', ['flowInstanceId'])
.index('by_flowInstanceId_and_status', ['flowInstanceId', 'status'])
.index('by_setorId', ['setorId'])
.index('by_assignedToId', ['assignedToId']),
// Documentos de instância de fluxo
flowInstanceDocuments: defineTable({
flowInstanceStepId: v.id('flowInstanceSteps'),
uploadedById: v.id('usuarios'),
storageId: v.id('_storage'),
name: v.string(),
uploadedAt: v.number()
})
.index('by_flowInstanceStepId', ['flowInstanceStepId'])
.index('by_uploadedById', ['uploadedById']),
// Sub-etapas de fluxo (para templates e instâncias)
flowSubSteps: defineTable({
flowStepId: v.optional(v.id('flowSteps')), // Para templates
flowInstanceStepId: v.optional(v.id('flowInstanceSteps')), // Para instâncias
name: v.string(),
description: v.optional(v.string()),
status: v.union(
v.literal('pending'),
v.literal('in_progress'),
v.literal('completed'),
v.literal('blocked')
),
position: v.number(),
createdBy: v.id('usuarios'),
createdAt: v.number()
})
.index('by_flowStepId', ['flowStepId'])
.index('by_flowInstanceStepId', ['flowInstanceStepId']),
// Notas de steps e sub-etapas
flowStepNotes: defineTable({
flowStepId: v.optional(v.id('flowSteps')),
flowInstanceStepId: v.optional(v.id('flowInstanceSteps')),
flowSubStepId: v.optional(v.id('flowSubSteps')),
texto: v.string(),
criadoPor: v.id('usuarios'),
criadoEm: v.number(),
arquivos: v.array(v.id('_storage'))
})
.index('by_flowStepId', ['flowStepId'])
.index('by_flowInstanceStepId', ['flowInstanceStepId'])
.index('by_flowSubStepId', ['flowSubStepId'])
};