From 913bbf30604f684fc594f33bda95c522f394d171 Mon Sep 17 00:00:00 2001 From: Felipe Canin Novaes Date: Mon, 2 Mar 2026 21:09:45 -0300 Subject: [PATCH] =?UTF-8?q?atualiza=20vers=C3=A3o=20do=20PRD=20para=201.3?= =?UTF-8?q?=20e=20detalha=20configura=C3=A7=C3=B5es=20de=20importa=C3=A7?= =?UTF-8?q?=C3=A3o=20de=20arquivos=20CSV=20e=20XLSX?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PRD.md | 317 +++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 265 insertions(+), 52 deletions(-) diff --git a/PRD.md b/PRD.md index 7385b6f..ad54925 100644 --- a/PRD.md +++ b/PRD.md @@ -1,6 +1,6 @@ # PRD — Comparador de Notas -**Versão:** 1.1 +**Versão:** 1.3 **Data:** 02/03/2026 **Status:** Planejamento @@ -71,16 +71,19 @@ Permitir que o usuário importe uma planilha e obtenha automaticamente: * Importação de arquivos CSV * Importação de arquivos XLSX * Interface gráfica -* Configuração de colunas +* Configuração de colunas (CSV por índice numérico; XLSX por letra+linha) * Detecção de quebras de sequência * Detecção de duplicidades * Soma de valores * Agrupamento por série -* Relatório visual -* Salvar layouts personalizados +* Relatório visual com paginação +* Exportação de relatório para PDF +* Salvar layouts personalizados (exclusivos por tipo de arquivo) * Carregar layouts salvos * Selecionar layout por menu dropdown * Excluir layouts +* Exportar layout para JSON +* Importar layout de JSON ## 4.2 Não Incluído (MVP) @@ -102,7 +105,7 @@ O sistema trabalhará com os seguintes campos lógicos: | Valor | Não | Valor monetário da nota | | Data | Não | Data de emissão da nota | -Os campos serão mapeados pelo usuário via índice de coluna. +Os campos serão mapeados pelo usuário conforme o tipo de arquivo: via **índice numérico** (base 0) para CSV, e via **notação LetraLinha** (ex: `B3`) para XLSX. > **Identificador único de uma nota:** combinação de `Numero + Serie`. Duplicidade e sequência são sempre avaliadas dentro da mesma série. @@ -127,30 +130,58 @@ O sistema deve permitir importar arquivos: | Linhas em branco | Devem ser ignoradas silenciosamente | | Linhas malformadas| Devem ser ignoradas; o sistema deve reportar ao usuário quais linhas foram descartadas, sem interromper a importação | -### RF01.2 — Limite de Tamanho de Arquivo +### RF01.2 — Configurações de Importação XLSX + +| Parâmetro | Comportamento | +| ---------------------- | -------------------------------------------------------------------------------------------------- | +| Seleção de aba | Imediatamente após a seleção do arquivo, o sistema exibe a lista de abas disponíveis para o usuário selecionar, antes de qualquer configuração de campos | +| Coluna e linha de início | O usuário informa a posição inicial de cada campo no formato `LetraLinha` (ex: `B3`) | +| Linhas em branco | Devem ser ignoradas silenciosamente | +| Linhas malformadas | Devem ser ignoradas; o sistema deve reportar ao usuário quais linhas foram descartadas | +| Arquivo corrompido | Se o arquivo não puder ser lido, exibir mensagem de erro em modal e limpar o arquivo carregado; o estado anterior é descartado | + +### RF01.3 — Limite de Tamanho de Arquivo O sistema deve recusar arquivos maiores que **50 MB** e exibir mensagem de erro ao usuário. -> Base de cálculo: 100.000 registros com 5–10 colunas geram aproximadamente 5–15 MB em CSV e até 30 MB em XLSX. O limite de 50 MB oferece margem adequada. +> O limite refere-se ao **tamanho do arquivo no disco** (tamanho comprimido para XLSX, que é um arquivo ZIP internamente). Base de cálculo: 100.000 registros com 5–10 colunas geram aproximadamente 5–15 MB em CSV e até 30 MB em XLSX. O limite de 50 MB oferece margem adequada. --- ## RF02 — Configuração de Colunas -O sistema deve permitir ao usuário definir, via **índice numérico** (posição da coluna), qual coluna representa cada campo: +O mapeamento de colunas varia conforme o tipo de arquivo. -* Qual coluna representa o número (obrigatório) -* Qual coluna representa a série (obrigatório) -* Qual coluna representa o valor (opcional) -* Qual coluna representa a data (opcional) +### RF02.1 — Mapeamento CSV (índice numérico) + +O usuário define, via **índice numérico** (posição da coluna, base 0), qual coluna representa cada campo: + +* Qual índice representa o número (obrigatório) +* Qual índice representa a série (obrigatório) +* Qual índice representa o valor (opcional) +* Qual índice representa a data (opcional) + +### RF02.2 — Mapeamento XLSX (letra + linha) + +O usuário define, no formato `LetraLinha`, a posição inicial de cada campo na planilha: + +* Ex: `B3` indica coluna B a partir da linha 3 +* Os campos mapeáveis são os mesmos: Numero (obrigatório), Serie (obrigatório), Valor (opcional) e Data (opcional) + +> A linha informada é a **linha de início dos dados** (não o cabeçalho). O cabeçalho, se existir, é a linha imediatamente anterior. + +### Comportamento de Memória + +Após a importação, o arquivo permanece em memória e o usuário pode alterar o mapeamento de colunas e reprocessar sem selecionar o arquivo novamente. Ao importar um novo arquivo, os dados do arquivo anterior são descartados da memória. ### Tratamento de Erros de Configuração -| Situação | Comportamento | -| ----------------------------------------------------- | --------------------------------------------------------------- | -| Índice configurado não existe no arquivo importado | Exibir erro ao usuário identificando qual campo está inválido | -| Campo obrigatório (Numero ou Serie) não mapeado | Bloquear execução da análise e solicitar configuração | -| Campo opcional não mapeado | Ignorar o campo; funcionalidades dependentes ficam desabilitadas| +| Situação | Comportamento | +| ----------------------------------------------------------- | ---------------------------------------------------------------- | +| Índice/posição configurado não existe no arquivo importado | Exibir erro ao usuário identificando qual campo está inválido | +| Campo obrigatório (Numero ou Serie) não mapeado | Bloquear execução da análise e solicitar configuração | +| Campo opcional não mapeado | Ignorar o campo; funcionalidades dependentes ficam desabilitadas | +| Dois campos mapeados para o mesmo índice/posição | Bloquear e exibir erro de validação imediatamente, antes de executar a análise | --- @@ -167,6 +198,29 @@ O formato JSON é utilizado exclusivamente para importação e exportação de l O armazenamento interno dos layouts é realizado via SQLite (ver Seção 10). +### Tipo de Layout + +Cada layout é exclusivo de um tipo de arquivo: **CSV** ou **XLSX**. Um layout CSV armazena configurações específicas de CSV (delimitador, encoding, índices de coluna). Um layout XLSX armazena configurações específicas de XLSX (aba, posições no formato `LetraLinha`). + +### Conflito ao Importar Layout JSON + +Se o usuário importar um arquivo JSON com o nome de um layout já existente no banco, o sistema deve perguntar ao usuário o que fazer, oferecendo as opções: + +* Sobrescrever o layout existente +* Salvar com novo nome + +### Erros na Importação de Layout JSON + +Se o arquivo JSON estiver malformado ou com campos obrigatórios ausentes, o sistema deve exibir mensagem de erro descrevendo o problema e cancelar a importação. Nenhum dado parcial deve ser salvo. + +### Nome do Arquivo ao Exportar Layout + +Ao exportar um layout para JSON, o sistema deve sugerir o nome do arquivo com base no nome do layout (ex: layout `Padrão CSV` → `Padrão CSV.json`). O usuário pode alterar o nome antes de salvar. + +### Limite de Layouts + +Não há limite no número de layouts que podem ser armazenados. + --- ## RF04 — Detecção de Sequência @@ -191,10 +245,33 @@ Se o valor de um campo Numero não for numérico (ex: `NF-001`, `ABC`): 3. Se não restar valor numérico utilizável, descartar o registro 4. Em ambos os casos, reportar ao usuário quais registros foram afetados +### Número Zero + +Registros com o campo Numero igual a `0` devem ser descartados e reportados ao usuário. O valor `0` não é considerado um número de nota válido. + ### Escopo da Detecção Faltantes são detectados **por série**. Cada série possui sua própria sequência independente. +### Proteção contra Intervalos Anormalmente Grandes + +Se o intervalo de faltantes de qualquer série exceder **10.000 registros**, o sistema deve: + +1. Interromper o processamento dessa série +2. Exibir aviso informando o intervalo calculado (ex: "Série 001: intervalo de 999.996 faltantes detectado") +3. Solicitar confirmação do usuário antes de continuar + +Se o usuário confirmar, o sistema deve listar todos os faltantes normalmente, com paginação. Não há truncamento da lista após a confirmação. + +Esse comportamento protege contra mapeamentos incorretos de colunas que gerariam listas ilegíveis. + +### Tratamento de Série com Valor Inválido + +Se o campo Série de um registro estiver vazio ou contiver valor não utilizável: + +1. O registro deve ser descartado +2. O sistema deve reportar ao usuário quais linhas foram afetadas, sem interromper a importação + --- ## RF05 — Detecção de Duplicidade @@ -203,6 +280,14 @@ O sistema deve identificar registros duplicados. Um registro é considerado duplicado quando existe mais de uma ocorrência da mesma combinação **Numero + Serie** no arquivo importado. +### Exibição das Duplicatas + +A lista de duplicatas exibe o identificador (Numero + Serie) e a contagem de ocorrências por grupo. Exemplo: `NF 0004 / Série 001 — 3 ocorrências`. As ocorrências individuais não são listadas separadamente. + +### Impacto na Soma de Valores + +Todas as ocorrências de registros duplicados são incluídas na soma de valores, pois refletem os lançamentos reais presentes no arquivo. + --- ## RF06 — Soma de Valores @@ -212,15 +297,57 @@ O sistema deve calcular: * Soma total * Soma por série +### Formato de Valor Aceito + +O sistema deve aceitar valores numéricos com ponto **ou** vírgula como separador decimal, detectando o formato automaticamente por registro. + +| Exemplo de entrada | Resultado parseado | +| ------------------ | ------------------ | +| `1000.00` | 1000,00 | +| `1000,00` | 1000,00 | +| `1.000,00` | 1000,00 | +| `1,000.00` | 1000,00 | +| `1.000` | 1000,00 (ponto interpretado como separador de milhar quando seguido de exatamente 3 dígitos sem parte decimal subsequente) | + +Valores negativos (precedidos de `-`) devem ser rejeitados e reportados ao usuário como inválidos. + +Valores que não puderem ser interpretados como número devem ser descartados e reportados ao usuário. + +### Formato de Exibição de Valores + +Todos os valores monetários são exibidos com **2 casas decimais fixas** no formato brasileiro (ex: `1.234,56`). + --- ## RF07 — Exibição de Resultados O sistema deve exibir: -* Lista de notas faltantes -* Lista de duplicadas -* Totais +* Lista de notas faltantes agrupadas por série +* Lista de duplicadas agrupadas por série +* Totais (soma total e soma por série) + +### Organização dos Resultados + +| Aspecto | Comportamento | +| ------------- | ----------------------------------------------------- | +| Agrupamento | Resultados sempre agrupados por série | +| Listas longas | Paginação — o usuário navega entre páginas de resultados | +| Itens por página | Selecionável via dropdown com as opções: 50, 100, 200, 1000 | + +### RF07.1 — Exportação de Relatório + +O sistema deve permitir exportar o relatório de resultados para **PDF** utilizando a biblioteca `genpdf`. + +O PDF deve conter: +* Notas faltantes por série +* Duplicatas por série +* Totais por série e total geral + +**Metadados do relatório:** +* Nome do arquivo importado +* Data e hora da geração +* Nome do layout utilizado --- @@ -268,6 +395,18 @@ O sistema deve possuir interface simples. --- +## RNF05 — Idioma + +O idioma da interface é **Português do Brasil (PT-BR)**. + +--- + +## RNF06 — Mensagens de Erro e Aviso + +Todas as mensagens de erro e aviso devem ser exibidas em **modal/popup bloqueante**. O usuário deve fechar o modal explicitamente para continuar. + +--- + # 8. Fluxo do Usuário Fluxo principal: @@ -304,6 +443,7 @@ Sem dependências externas obrigatórias. | SQLite | rusqlite | Definido | | Leitura de CSV | csv | Definido | | Leitura de XLSX | calamine | Definido | +| Geração de PDF | genpdf | Definido | --- @@ -332,12 +472,33 @@ Motivos: - Multiplataforma - Alta confiabilidade -O banco de dados deve ser armazenado localmente no dispositivo do -usuário. +O banco de dados deve ser armazenado na **pasta de dados do usuário**, de acordo com o sistema operacional: -Exemplo: +| Sistema Operacional | Caminho | +| ------------------- | ---------------------------------------------------- | +| Linux | `~/.config/comparador-notas/config.db` | +| Windows | `%APPDATA%\comparador-notas\config.db` | +| macOS | `~/Library/Application Support/comparador-notas/config.db` | -config.db +O diretório e o arquivo devem ser **criados automaticamente** pelo sistema na primeira execução. + +------------------------------------------------------------------------ + +## 10.2.1 — Banco de Dados Corrompido + +Se o arquivo `config.db` estiver ilegível ou corrompido ao iniciar o programa, o sistema deve: + +1. Exibir aviso ao usuário informando que o banco de dados está corrompido e será recriado +2. Recriar o banco de dados vazio +3. Continuar a execução normalmente + +Os layouts salvos anteriormente serão perdidos neste cenário. + +------------------------------------------------------------------------ + +## 10.2.2 — Migração de Schema + +O banco de dados deve conter uma tabela de controle de versão (`schema_version`) com o número da versão atual do schema. A cada inicialização, o sistema deve verificar a versão e aplicar migrations automáticas quando necessário, garantindo compatibilidade com versões anteriores do banco. ------------------------------------------------------------------------ @@ -351,16 +512,37 @@ Layouts personalizados ## 10.4 Entidade: Layout -Campos: +Cada layout é exclusivo de um tipo de arquivo (`csv` ou `xlsx`). As configurações variam conforme o tipo. - Campo Tipo Descrição - --------------- --------- -------------------------- - id inteiro Identificador único - nome texto Nome do layout - coluna_numero texto Nome da coluna do número - coluna_serie texto Nome da coluna da série - coluna_valor texto Nome da coluna do valor - coluna_data texto Nome da coluna da data +**Campos comuns:** + +| Campo | Tipo | Descrição | +| ---------- | ------- | -------------------------------------- | +| id | inteiro | Identificador único | +| nome | texto | Nome do layout | +| tipo | texto | Tipo do arquivo: `csv` ou `xlsx` | + +**Campos exclusivos de layouts CSV:** + +| Campo | Tipo | Descrição | +| ------------------ | ------ | -------------------------------------------------- | +| delimitador | texto | Caractere delimitador (`,`, `;`, `\t`) | +| encoding | texto | Encoding do arquivo (`utf-8` ou `windows-1252`) | +| linha_cabecalho | inteiro | Número da linha do cabeçalho (base 1) | +| indice_numero | inteiro | Índice da coluna Numero (base 0) | +| indice_serie | inteiro | Índice da coluna Serie (base 0) | +| indice_valor | inteiro | Índice da coluna Valor (base 0, nulo se ausente) | +| indice_data | inteiro | Índice da coluna Data (base 0, nulo se ausente) | + +**Campos exclusivos de layouts XLSX:** + +| Campo | Tipo | Descrição | +| -------------- | ------ | ---------------------------------------------------------------- | +| aba | texto | Nome ou índice da aba a ser processada | +| pos_numero | texto | Posição inicial da coluna Numero no formato `LetraLinha` (ex: `D3`) | +| pos_serie | texto | Posição inicial da coluna Serie no formato `LetraLinha` (ex: `B3`) | +| pos_valor | texto | Posição inicial da coluna Valor (nulo se ausente) | +| pos_data | texto | Posição inicial da coluna Data (nulo se ausente) | ------------------------------------------------------------------------ @@ -424,15 +606,35 @@ Quando o usuário exportar ou importar um layout, o arquivo gerado será no form Esse formato é usado apenas para portabilidade entre dispositivos. O armazenamento interno é sempre via SQLite. -Exemplo de arquivo JSON exportado: +O campo `tipo` define qual conjunto de configurações está presente no arquivo. + +**Exemplo — layout CSV:** ```json { - "nome": "Layout Padrão", - "coluna_numero": "Nota", - "coluna_serie": "Serie", - "coluna_valor": "Valor", - "coluna_data": "Data" + "nome": "Layout Padrão CSV", + "tipo": "csv", + "delimitador": ";", + "encoding": "utf-8", + "linha_cabecalho": 1, + "indice_numero": 3, + "indice_serie": 1, + "indice_valor": 5, + "indice_data": null +} +``` + +**Exemplo — layout XLSX:** + +```json +{ + "nome": "Layout Padrão XLSX", + "tipo": "xlsx", + "aba": "Plan1", + "pos_numero": "D3", + "pos_serie": "B3", + "pos_valor": "F3", + "pos_data": null } ``` @@ -442,21 +644,32 @@ Exemplo de arquivo JSON exportado: O sistema será considerado funcional quando: -* Importar planilha -* Detectar notas faltantes corretamente -* Calcular totais corretamente -* Permitir configuração +* Importar planilha CSV com configurações de delimitador, encoding e linha de cabeçalho +* Importar planilha XLSX com seleção de aba e posicionamento por `LetraLinha` +* Detectar notas faltantes por série corretamente +* Detectar duplicatas por série corretamente +* Calcular soma total e soma por série corretamente +* Exibir resultados agrupados por série com paginação +* Exportar relatório de resultados para PDF +* Salvar, carregar, selecionar e excluir layouts +* Exportar e importar layouts via JSON +* Exibir aviso de confirmação quando intervalo de faltantes exceder 10.000 por série --- # 13. MVP — Versão Inicial -Escopo mínimo: +O MVP inclui o escopo completo descrito neste PRD: -* Importar CSV -* Mapear coluna Número -* Detectar faltantes -* Exibir resultado +* Importar CSV e XLSX +* Mapear colunas Numero, Serie, Valor e Data +* Detectar notas faltantes por série +* Detectar duplicatas por série +* Calcular soma total e por série +* Exibir resultados agrupados por série com paginação +* Exportar relatório para PDF +* Gerenciar layouts (salvar, carregar, excluir) +* Exportar e importar layouts via JSON --- @@ -464,11 +677,11 @@ Escopo mínimo: Possíveis melhorias: -* Exportação de relatório -* Exportação PDF * Integração com ERP -* Banco de dados -* Automação +* Histórico de análises +* Automação de importação (monitorar pasta) +* Exportação para CSV +* Multiusuário ---