Appearance
Workflows Module - Módulo de Fluxos de Trabalho
Visão Geral
O módulo de Workflows permite criar configurações predefinidas de fluxos de trabalho para contratos. Um workflow define quais etapas estarão ativas e suas configurações, podendo ser aplicado na criação de novos contratos.
Status do Workflow
typescript
type WorkflowStatus = 'draft' | 'published'| Status | Descrição |
|---|---|
draft | Rascunho - workflow em edição |
published | Publicado - workflow ativo para uso |
Etapas do Workflow (Steps)
O sistema possui 6 etapas predefinidas que correspondem ao fluxo de criação de contratos:
| Ordem | Key | Nome | Obrigatória | Posição Fixa | Descrição |
|---|---|---|---|---|---|
| 1 | parts | Partes | Sim | Primeira | Definição das partes do contrato |
| 2 | model | Modelo | Sim | Segunda | Seleção do template/modelo |
| 3 | documents | Documentos | Não | Variável | Configuração de documentos para upload/download |
| 4 | revision | Revisão | Não | Variável | Configuração de revisores internos |
| 5 | upload | Upload | Auto | Variável | Upload de documentos pelas partes (auto-gerenciado) |
| 6 | signature | Assinatura | Sim | Última | Coleta de assinaturas |
Regras de Posicionamento
parts: Sempre na primeira posiçãomodel: Sempre na segunda posiçãosignature: Sempre na última posiçãoupload: Step auto-gerenciado - aparece automaticamente quando há documentos para upload configurados emdocumentsConfig
Types do Domain
Tipos Principais
typescript
// src/domain/workflow/types.ts
type WorkflowStatus = 'draft' | 'published'
type StepKey = 'parts' | 'model' | 'documents' | 'revision' | 'upload' | 'signature'
type PartFieldKey = 'name' | 'email' | 'document' | 'phone' | 'cnpj' | 'razao_social' | 'cpf'
type VariableSourceType = 'part_field' | 'predefined'
type StepPropertyType = 'boolean' | 'select' | 'number' | 'text'
type FixedPosition = 'first' | 'second' | 'last'
type SignatureGroupType = 'parts' | 'internal' | 'custom'Workflow
typescript
type Workflow = BaseEntity & {
name: string
description?: string
status: WorkflowStatus
steps: WorkflowStep[]
documentsConfig?: DocumentRequirement[]
modelConfig?: ModelStepConfig
revisionConfig?: RevisionStepConfig
signatureConfig?: SignatureStepConfig
}WorkflowStep
typescript
type WorkflowStep = {
id: string // UUID
key: StepKey
name: string
order: number
parentId: string // ID do step anterior
isEnabled: boolean
isRequired: boolean
properties: StepProperty[]
}
type StepProperty = {
key: string
label: string // Chave de i18n
type: StepPropertyType
value: boolean | string | number
options?: StepPropertyOption[]
}Configurações por Etapa
ModelStepConfig
Configuração do template e mapeamento de variáveis:
typescript
type ModelStepConfig = {
templateId: string // ID do template selecionado
partGroups: PartGroup[] // Grupos de partes
variableAssignments: VariableAssignment[] // Mapeamento de variáveis
}
type PartGroup = {
id: string
name: string
members: PartGroupMember[]
}
type PartGroupMember = {
id: string
name: string
avatar?: string
}
type VariableAssignment = {
variableName: string // Nome da variável no template
sourceType: VariableSourceType // 'part_field' ou 'predefined'
partGroupId?: string // Se sourceType = 'part_field'
partField?: PartFieldKey // Campo do grupo (name, email, cpf, etc.)
predefinedValue?: string // Se sourceType = 'predefined'
}DocumentsStepConfig
Configuração de documentos para upload/download:
typescript
type DocumentRequirement = {
id: string // UUID
name: string
description?: string
isRequired: boolean
isDownload: boolean // true = documento para download, false = para upload
downloadFile?: DocumentFile // Se isDownload = true
acceptedFormats: string[] // ['pdf', 'jpg', 'png', etc.]
maxFileSize: number // Em MB
}
type DocumentFile = {
fileName: string
fileId?: string
fileUrl?: string
}RevisionStepConfig
Configuração de revisores internos:
typescript
type RevisionStepConfig = {
reviewers: ReviewerMember[]
}
type ReviewerMember = {
id: string
userId: string // ID do funcionário
name: string
email: string
avatar?: string
isRequired: boolean
order: number
}SignatureStepConfig
Configuração de grupos de assinatura:
typescript
type SignatureStepConfig = {
groups: SignatureGroup[]
signatureOrder: 'internal_first' | 'parts_first' | 'custom'
}
type SignatureGroup = {
id: string
name: string
type: SignatureGroupType // 'parts' | 'internal' | 'custom'
order: number
isFixed: boolean
members: SignerMember[]
}
type SignerMember = {
id: string
userId?: string // Somente para type 'internal'
name: string
email: string
avatar?: string
order: number
}Endpoints da API
Listagem e CRUD
| Endpoint | Método | Descrição |
|---|---|---|
/workflows | GET | Lista workflows com filtros opcionais |
/workflows/:id | GET | Retorna um workflow pelo ID |
/workflows | POST | Cria um novo workflow |
/workflows/:id | PUT | Atualiza um workflow existente |
/workflows/:id | DELETE | Remove um workflow |
Query Parameters para GET /workflows
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
search | string | Não | Filtro por nome (case insensitive) |
status | WorkflowStatus | Não | Filtro por status: draft, published |
Payloads
typescript
type CreateWorkflowPayload = {
name: string
description?: string
status?: WorkflowStatus
steps: Omit<WorkflowStep, 'id'>[]
documentsConfig?: DocumentRequirement[]
modelConfig?: ModelStepConfig
revisionConfig?: RevisionStepConfig
signatureConfig?: SignatureStepConfig
}
type UpdateWorkflowPayload = Partial<CreateWorkflowPayload> & {
id: string
}Services
typescript
// src/modules/workflows/services/workflows.ts
// Listagem
getWorkflowsService(params?: Partial<WorkflowFilter>)
// CRUD
getWorkflowByIdService(id: string)
createWorkflowService(payload: CreateWorkflowPayload)
updateWorkflowService({ id, ...payload }: UpdateWorkflowPayload)
deleteWorkflowService(id: string)Stores
Store de Listagem
typescript
// src/modules/workflows/stores/workflows.ts
// Estado
items: Workflow[]
total: number
loading: boolean
search: string
status: WorkflowStatus | 'all'
// Métodos
loadWorkflows(params?: WorkflowFilter)
setSearch(filters: WorkflowFilter)
deleteWorkflow(id: string)
reset()Store do Editor
typescript
// src/modules/workflows/stores/workflowEditor.ts
// Estado Principal
isLoading: boolean
isSaving: boolean
workflowId: string | undefined
workflowName: string
workflowDescription: string
workflowStatus: WorkflowStatus
// Steps
flowSteps: WorkflowStep[] // Steps no fluxo
availableSteps: WorkflowStep[] // Steps disponíveis para adicionar
selectedStepKey: StepKey | null
showPropertiesPanel: boolean
// Configurações
selectedTemplate: Template | null
modelStepConfig: ModelStepConfig
documentsConfig: DocumentRequirement[]
revisionConfig: RevisionStepConfig
signatureConfig: SignatureStepConfig
// Computed
isEditing: boolean
canSave: boolean
selectedStep: WorkflowStep | undefined
flowStepsCount: number
uploadRequiredDocuments: DocumentRequirement[] // Documentos para upload
shouldShowUploadStep: boolean // Se deve exibir step de upload
// Métodos de Steps
initializeSteps() // Inicializa com steps padrão
selectStep(stepKey) // Abre painel de propriedades
closePropertiesPanel() // Fecha painel
addStepToFlow(stepKey, position?) // Adiciona step ao fluxo
removeStepFromFlow(stepKey) // Remove step do fluxo
reorderFlowSteps(newOrder) // Reordena steps
updateStepProperty(stepKey, key, value)
// Métodos de Template/Model
setSelectedTemplate(template)
openTemplateSelector()
closeTemplateSelector()
refreshTemplate()
addPartGroup(name?)
duplicatePartGroup(groupId)
refreshPartGroup(groupId)
removePartGroup(groupId)
setVariableAssignment(groupId, variableName, sourceType, partField?, predefinedValue?)
removeVariableAssignment(groupId, variableName)
// Métodos de Documentos
updateDocumentsConfig(documents) // Atualiza e sincroniza upload step
syncUploadStepVisibility() // Adiciona/remove upload step automaticamente
// Persistência
loadWorkflow(id) // Carrega workflow existente
saveWorkflow() // Salva (cria ou atualiza)
activateWorkflow() // Muda status para 'published' e salva
reset() // Limpa estadoMocks (MSW)
Os mocks utilizam MSW (Mock Service Worker). Os dados estão em:
src/mocks/
├── data/
│ └── workflows.ts # Array de workflows mockados
└── handlers/
└── workflows.ts # Handlers MSW para endpointsExemplo de Workflow Mockado
typescript
{
id: 'a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d',
name: 'Contratação de Prestador PJ',
description: 'Fluxo padrão para contratação de prestadores de serviço pessoa jurídica',
status: 'published',
steps: [
{
id: 'f1e2d3c4-b5a6-4789-0123-456789abcdef',
key: 'parts',
name: 'Partes',
order: 1,
parentId: '',
isEnabled: true,
isRequired: true,
properties: []
},
// ... outros steps
],
modelConfig: {
templateId: 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
partGroups: [
{ id: 'pg-pj-001', name: 'Empresa Contratante', members: [] },
{ id: 'pg-pj-002', name: 'Prestador PJ', members: [] }
],
variableAssignments: [
{ variableName: 'razao_social_contratante', sourceType: 'part_field', partGroupId: 'pg-pj-001', partField: 'razao_social' },
{ variableName: 'valor_mensal', sourceType: 'predefined', predefinedValue: 'R$ 5.000,00' }
]
},
documentsConfig: [
{
id: 'd1c2b3a4-9876-4fed-cba9-876543210fed',
name: 'Contrato Social',
description: 'Última alteração do contrato social da empresa',
isRequired: true,
isDownload: false,
acceptedFormats: ['pdf'],
maxFileSize: 10
}
],
revisionConfig: {
reviewers: [
{
id: 'rv-pj-001',
userId: 's4t5a6f7-f8i9-4d01-2345-678901234abc',
name: 'Ana Paula Silva',
email: 'ana.silva@empresa.com',
isRequired: true,
order: 1
}
]
},
signatureConfig: {
groups: [
{
id: 'sg-pj-001',
name: 'Diretoria',
type: 'internal',
order: 1,
isFixed: true,
members: [
{ id: 'sm-pj-001', userId: 's6t7a8f9-f0i1-4d23-4567-890123456cde', name: 'Diretor Executivo', email: 'diretor@empresa.com', order: 1 }
]
},
{
id: 'sg-pj-002',
name: 'Partes Contratantes',
type: 'parts',
order: 2,
isFixed: true,
members: []
}
],
signatureOrder: 'internal_first'
},
createdAt: new Date('2024-01-15'),
updatedAt: new Date('2024-03-10')
}Componentes
Páginas
| Componente | Path | Descrição |
|---|---|---|
ListWorkflows.vue | /workflows/list | Listagem com tabela e filtros |
EditWorkflow.vue | /workflows/new, /workflows/:id | Editor com timeline |
Componentes de Listagem
| Componente | Descrição |
|---|---|
TableHeader.vue | Filtros e botão "Novo Fluxo" |
WorkflowFilters.vue | Select de status |
WorkflowTableList.vue | Tabela com n-data-table |
Componentes do Editor
| Componente | Descrição |
|---|---|
WorkflowToolbar.vue | Nome, status e ações (salvar, publicar, excluir) |
WorkflowTimeline.vue | Timeline horizontal com steps |
TimelineStepCard.vue | Card individual de cada step |
StepPropertiesPanel.vue | Drawer lateral para configurar propriedades |
Componentes de Configuração por Step
| Componente | Step | Descrição |
|---|---|---|
ModelStepConfig.vue | model | Seleção de template e mapeamento de variáveis |
DocumentsStepConfig.vue | documents | Lista e formulário de documentos |
RevisionStepConfig.vue | revision | Configuração de revisores |
UploadStepConfig.vue | upload | Exibe documentos configurados (read-only) |
SignatureStepConfig.vue | signature | Configuração de grupos de assinatura |
StepCommonProperties.vue | todos | Propriedades comuns (requirePreviousCompletion) |
Composables
typescript
// src/modules/workflows/composables/
useModelStepConfig() // Lógica do ModelStepConfig
useDocumentsStepConfig() // Lógica do DocumentsStepConfig
useRevisionStepConfig() // Lógica do RevisionStepConfig
useSignatureStepConfig() // Lógica do SignatureStepConfig
useStepCommonProperties() // Propriedades comuns entre stepsExemplo: useDocumentsStepConfig
typescript
const {
viewMode, // 'list' | 'form'
requirements, // DocumentRequirement[]
formData, // Dados do formulário
isEditing, // Se está editando documento
hasRequirements,
canSaveForm,
canSaveDownloadForm,
requiredCount,
optionalCount,
formatOptions,
showList,
openAddForm,
openEditForm,
saveForm,
handleFileUpload,
removeUploadedFile,
removeRequirement,
duplicateRequirement,
handleSave,
formatFileSize,
formatAcceptedFormats,
initializeFromStore, // Carrega dados do store ao montar
} = useDocumentsStepConfig()Rotas
typescript
// src/modules/workflows/router/index.ts
{
path: '/workflows/list',
name: 'list-workflow',
meta: { menuKey: 'workflow', isListPage: true }
},
{
path: '/workflows/new',
name: 'new-workflow',
meta: { menuKey: 'workflow' }
},
{
path: '/workflows/:id',
name: 'edit-workflow',
meta: { menuKey: 'workflow' }
}Permissões: Apenas role borrower tem acesso ao módulo de workflows.
Constantes
typescript
// src/domain/workflow/constants.ts
export const WORKFLOW_STATUS = {
draft: 'draft',
published: 'published',
}
export const STEP_KEYS = {
parts: 'parts',
model: 'model',
documents: 'documents',
revision: 'revision',
upload: 'upload',
signature: 'signature',
}
export const FIXED_POSITION_STEPS = {
parts: 'first',
model: 'second',
signature: 'last',
}
export const STEPS_WITH_CONFIG: StepKey[] = ['model', 'documents', 'revision', 'upload', 'signature']
export const AUTO_MANAGED_STEPS: StepKey[] = ['upload']
export const DOCUMENT_FORMATS = [
{ label: 'PDF', value: 'pdf' },
{ label: 'JPG', value: 'jpg' },
{ label: 'JPEG', value: 'jpeg' },
{ label: 'PNG', value: 'png' },
{ label: 'DOC', value: 'doc' },
{ label: 'DOCX', value: 'docx' },
]
export const DEFAULT_DOCUMENT_FORMATS = ['pdf', 'jpg', 'jpeg', 'png']
export const DEFAULT_MAX_FILE_SIZE = 10 // MBPropriedades por Step (STEP_PROPERTIES_CONFIG)
Model
| Propriedade | Tipo | Default | Descrição |
|---|---|---|---|
requirePreviousCompletion | boolean | true | Exigir conclusão da etapa anterior |
allowCustomTemplate | boolean | true | Permitir template personalizado |
defaultTemplateId | select | "" | Template padrão pré-selecionado |
Documents
| Propriedade | Tipo | Default | Descrição |
|---|---|---|---|
requirePreviousCompletion | boolean | true | Exigir conclusão da etapa anterior |
requiredDocuments | number | 0 | Quantidade de documentos obrigatórios |
allowOptional | boolean | true | Permitir documentos opcionais |
Revision
| Propriedade | Tipo | Default | Descrição |
|---|---|---|---|
requirePreviousCompletion | boolean | true | Exigir conclusão da etapa anterior |
minReviewers | number | 1 | Mínimo de revisores |
requireApproval | boolean | true | Exigir aprovação dos revisores |
Upload
| Propriedade | Tipo | Default | Descrição |
|---|---|---|---|
requirePreviousCompletion | boolean | true | Exigir conclusão da etapa anterior |
overdueDays | number | 0 | Dias para vencimento (0 = sem prazo) |
maxFileSize | number | 10 | Tamanho máximo de arquivo (MB) |
allowedFormats | text | "pdf,doc,docx" | Formatos permitidos |
Signature
| Propriedade | Tipo | Default | Descrição |
|---|---|---|---|
requirePreviousCompletion | boolean | true | Exigir conclusão da etapa anterior |
overdueDays | number | 0 | Dias para vencimento (0 = sem prazo) |
signatureType | select | "electronic" | Tipo: electronic ou digital (ICP-Brasil) |
requireOrder | boolean | false | Exigir ordem de assinatura |
Formato de IDs
Todos os IDs seguem o formato UUID v4:
a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d