diff --git a/PLAN.md b/PLAN.md
deleted file mode 100644
index fe3c56e..0000000
--- a/PLAN.md
+++ /dev/null
@@ -1,806 +0,0 @@
----
-
-📊 Análise e Sugestões para OpenSheets
-
-🎯 Resumo Executivo
-
-O OpenSheets é uma aplicação financeira bem estruturada com 184 componentes, 15 widgets de dashboard, e um design system coeso baseado em cores terracota. A análise identificou pontos fortes significativos e
-oportunidades estratégicas para melhorias.
-
----
-
-✅ Pontos Fortes Identificados
-
-Arquitetura
-
-- ✨ Server-first com Next.js 15 App Router
-- 🚀 Fetching paralelo otimizado (18+ requests simultâneos)
-- 🔒 Modo privacidade bem implementado
-- 🎨 Design system consistente (OKLCH color space)
-
-Componentes
-
-- 📦 40+ componentes shadcn/ui bem organizados
-- ♻️ Alta reutilização de componentes
-- 🎭 Sistema de skeletons completo
-- 🌙 Suporte total a tema dark/light
-
----
-
-🚀 Sugestões de Novas Features
-
-1. Análise Preditiva e Forecasting 🔮
-
-Prioridade: Alta | Complexidade: Média
-
-// Nova página: app/(dashboard)/previsoes/
-
-Features:
-
-- Previsão de gastos mensais baseada em histórico
-- Alerta de contas a vencer na próxima semana
-- Projeção de saldo futuro considerando despesas recorrentes
-- Machine learning simples para detectar padrões de gasto
-
-Componentes sugeridos:
-
-- ForecastChart - Gráfico de linha com projeções
-- UpcomingBillsWidget - Widget de contas a vencer
-- SavingsGoalTracker - Acompanhamento de metas de economia
-
----
-
-2. Metas Financeiras (Goals) 🎯
-
-Prioridade: Alta | Complexidade: Média
-
-// Nova tabela no schema:
-export const metas = pgTable("metas", {
-id: uuid("id").primaryKey().defaultRandom(),
-userId: uuid("user_id").notNull().references(() => user.id),
-nome: text("nome").notNull(),
-valorAlvo: numeric("valor_alvo", { precision: 12, scale: 2 }).notNull(),
-valorAtual: numeric("valor_atual", { precision: 12, scale: 2 }).default("0"),
-prazo: timestamp("prazo"),
-categoriaId: uuid("categoria_id").references(() => categorias.id),
-tipo: text("tipo").notNull(), // 'economia', 'quitacao_divida', 'compra'
-});
-
-Features:
-
-- Criar metas de economia (ex: "Viagem para Europa - R$ 10.000")
-- Vincular transações às metas
-- Dashboard de progresso visual
-- Sugestões automáticas de quanto economizar mensalmente
-
----
-
-3. Relatórios Exportáveis 📄
-
-Prioridade: Média | Complexidade: Baixa
-
-Formatos:
-
-- PDF com gráficos (usando jsPDF + html2canvas)
-- Excel/CSV detalhado (usando xlsx)
-- JSON para backup completo
-
-Tipos de relatório:
-
-- Extrato mensal consolidado
-- Análise de gastos por categoria
-- Comparativo período a período
-- Resumo anual (imposto de renda)
-
-Código sugerido:
-// lib/reports/generate-pdf-report.ts
-import { jsPDF } from 'jspdf';
-
-export async function generateMonthlyReport(userId: string, period: string) {
-const data = await fetchMonthlyData(userId, period);
-const doc = new jsPDF();
-
- // Adicionar logo, gráficos, tabelas
- doc.save(`relatorio-${period}.pdf`);
-
-}
-
----
-
-4. Modo Comparativo de Períodos 📊
-
-Prioridade: Média | Complexidade: Baixa
-
-UI sugerida:
-
-
-Features:
-
-- Comparar dois meses lado a lado
-- Ver variação percentual por categoria
-- Identificar onde economizou/gastou mais
-- Gráficos de delta de gastos
-
----
-
-5. Tags/Etiquetas para Transações 🏷️
-
-Prioridade: Baixa | Complexidade: Baixa
-
-export const tags = pgTable("tags", {
-id: uuid("id").primaryKey(),
-userId: uuid("user_id").notNull(),
-nome: text("nome").notNull(),
-cor: text("cor").notNull(), // hex color
-});
-
-export const lancamento_tags = pgTable("lancamento_tags", {
-lancamentoId: uuid("lancamento_id").references(() => lancamentos.id),
-tagId: uuid("tag_id").references(() => tags.id),
-});
-
-Use cases:
-
-- Tag "Trabalho" para despesas dedutíveis
-- Tag "Emergência" para gastos não planejados
-- Tag "Investimento" para rastrear aplicações
-- Filtrar dashboard por tags
-
----
-
-6. Anexos e Comprovantes 📎
-
-Prioridade: Média | Complexidade: Alta
-
-Implementação:
-
-- Upload de imagens/PDFs de notas fiscais
-- Armazenamento em storage (S3-compatible ou local)
-- OCR para extrair dados automaticamente (Tesseract.js)
-- Galeria de comprovantes por transação
-
-export const anexos = pgTable("anexos", {
-id: uuid("id").primaryKey(),
-lancamentoId: uuid("lancamento_id").references(() => lancamentos.id),
-arquivo: text("arquivo_url").notNull(),
-tipo: text("tipo").notNull(), // 'imagem', 'pdf'
-tamanho: integer("tamanho_bytes"),
-});
-
----
-
-7. Investimentos Tracking 💹
-
-Prioridade: Baixa | Complexidade: Alta
-
-Escopo:
-
-- Registrar compra/venda de ações, FIIs, criptomoedas
-- Importação de extratos de corretoras
-- Gráfico de evolução patrimonial
-- Cálculo de rentabilidade
-
-Nova seção no sidebar:
-{
-title: "Investimentos",
-icon: RiLineChartLine,
-href: "/investimentos",
-}
-
----
-
-8. Gamificação e Conquistas 🏆
-
-Prioridade: Baixa | Complexidade: Média
-
-Conquistas sugeridas:
-
-- "Primeiro Mês no Azul" - Receitas > Despesas
-- "Economista" - Gastou menos que orçamento 3 meses seguidos
-- "Organizado" - Todas transações categorizadas
-- "Disciplinado" - 30 dias sem gastos em categoria específica
-
-Implementação:
-export const conquistas = pgTable("conquistas", {
-id: uuid("id").primaryKey(),
-codigo: text("codigo").notNull(), // 'primeiro_mes_azul'
-nome: text("nome").notNull(),
-descricao: text("descricao"),
-icone: text("icone"),
-});
-
-export const usuario_conquistas = pgTable("usuario_conquistas", {
-userId: uuid("user_id").references(() => user.id),
-conquistaId: uuid("conquista_id").references(() => conquistas.id),
-desbloqueadaEm: timestamp("desbloqueada_em").defaultNow(),
-});
-
----
-
-9. Notificações e Lembretes 🔔
-
-Prioridade: Alta | Complexidade: Média
-
-Tipos de notificação:
-
-- Lembrete de fatura vencendo em 3 dias
-- Orçamento atingindo 80% do limite
-- Despesa incomum detectada (> 2x média da categoria)
-- Cobrança recorrente não registrada este mês
-
-Implementação:
-
-- Cron job diário verificando condições
-- Sistema de notificações in-app
-- Opcional: Email notifications (Resend/Nodemailer)
-- Web Push Notifications (service worker)
-
----
-
-10. Importação Automática de Extratos 🔄
-
-Prioridade: Alta | Complexidade: Alta
-
-Métodos:
-
-1. Upload de OFX/CSV - Parser para formatos bancários
-2. API Open Banking - Integração com Pluggy/Belvo
-3. Email parsing - Ler extratos enviados por email
-4. OCR de PDFs - Extrair dados de PDFs bancários
-
-Fluxo sugerido:
-// app/(dashboard)/importacao/page.tsx
-
-1. Selecionar conta bancária de destino
-2. Upload de arquivo ou conectar via API
-3. Pré-visualização das transações
-4. Matching automático com categorias (ML)
-5. Revisão e confirmação
-6. Importação em lote
-
----
-
-🎨 Melhorias de UI/UX
-
-1. Redesign do Diálogo de Transação 💳
-
-Problema: Diálogo com muitos campos condicionais pode confundir usuários
-
-Solução:
-// Wizard multi-step com progresso visual
-
-
-{/_ Nome, valor, data _/}
-
-
-{/_ Método, conta, condição _/}
-
-
-{/_ Categoria, pagador, notas _/}
-
-
-
-Indicador de progresso:
-
-
- 1}>1
- 2}>2
- 3
-
-
----
-
-2. Tabela Responsiva com Card View 📱
-
-Problema: Tabelas complexas em mobile têm scroll horizontal
-
-Solução:
-// components/lancamentos/table/lancamentos-responsive-view.tsx
-export function LancamentosResponsiveView() {
-const isMobile = useIsMobile();
-
- if (isMobile) {
- return ;
- }
-
- return ;
-
-}
-
-// Card view para mobile
-function LancamentoCard({ lancamento }) {
-return (
-
-
-
-
{lancamento.nome}
-
-{lancamento.categoria}
-
-
-
-
-
-{lancamento.condicao}
-{lancamento.formaPagamento}
-
-
-);
-}
-
----
-
-3. Dashboard Personalizável 🔧
-
-Problema: Todos veem os mesmos 15 widgets
-
-Solução:
-// lib/dashboard/widgets/user-widget-preferences.ts
-export const widgetPreferences = pgTable("widget_preferences", {
-userId: uuid("user_id").references(() => user.id),
-widgetId: text("widget_id").notNull(),
-ordem: integer("ordem").notNull(),
-visivel: boolean("visivel").default(true),
-tamanho: text("tamanho"), // 'small', 'medium', 'large'
-});
-
-// Drag-and-drop com dnd-kit
-import { DndContext, closestCenter } from '@dnd-kit/core';
-
-
-
- {widgets.map(widget => (
-
- ))}
-
-
-
-Features:
-
-- Reordenar widgets via drag-and-drop
-- Ocultar/mostrar widgets
-- Redimensionar widgets (grid responsivo)
-- Salvar preferências no banco
-
----
-
-4. Busca Global (Command Palette) ⌘K
-
-Problema: Navegar entre muitas páginas é lento
-
-Solução:
-// components/command-palette.tsx
-import { RiSearchLine } from '@remixicon/react';
-
-export function CommandPalette() {
-const [open, setOpen] = useState(false);
-
- useEffect(() => {
- const down = (e: KeyboardEvent) => {
- if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {
- e.preventDefault();
- setOpen(true);
- }
- };
- document.addEventListener('keydown', down);
- return () => document.removeEventListener('keydown', down);
- }, []);
-
- return (
-
-
-
-
-
-
- Nova Transação
-
-
-
- {recentTransactions.map(t => (
- {t.nome}
- ))}
-
-
- router.push('/dashboard')}>
- Dashboard
-
-
-
-
- );
-
-}
-
-Ações rápidas:
-
-- Nova transação (Ctrl+K → "nova")
-- Ver conta específica
-- Buscar transação por nome/valor
-- Navegar para qualquer página
-- Executar ações (marcar como pago, editar, excluir)
-
----
-
-5. Onboarding Interativo 🎓
-
-Problema: Novos usuários podem se sentir perdidos
-
-Solução:
-// components/onboarding/onboarding-tour.tsx
-import { Joyride } from 'react-joyride';
-
-const steps = [
-{
-target: '.sidebar-nav',
-content: 'Aqui você navega entre as diferentes seções',
-},
-{
-target: '[data-tour="new-transaction"]',
-content: 'Clique aqui para adicionar sua primeira transação',
-},
-{
-target: '.month-picker',
-content: 'Use isto para navegar entre meses',
-},
-];
-
-export function OnboardingTour() {
-const { tourCompleted } = useUserPreferences();
-
- return (
-
- );
-
-}
-
-Checklist inicial:
-
-- Criar primeira conta bancária
-- Adicionar um cartão de crédito
-- Registrar primeira transação
-- Definir orçamento mensal
-- Explorar dashboard
-
----
-
-6. Modo Compacto / Densidade Ajustável 📏
-
-Problema: Algumas páginas têm muito espaço em branco
-
-Solução:
-// Adicionar ao contexto de preferências
-export const densitySettings = {
-comfortable: { gap: 6, padding: 6, fontSize: 'text-base' },
-normal: { gap: 4, padding: 4, fontSize: 'text-sm' },
-compact: { gap: 2, padding: 2, fontSize: 'text-xs' },
-};
-
-// Aplicar dinamicamente
-
-
-
-Controle:
-// Em ajustes/page.tsx
-
-
----
-
-7. Indicadores Visuais de Status 🚦
-
-Problema: Difícil ver rapidamente status de contas/faturas
-
-Solução:
-// components/status-indicator.tsx
-export function StatusIndicator({ status }: { status: string }) {
-const config = {
-'em-dia': { color: 'green', icon: RiCheckLine, label: 'Em dia' },
-'vencendo': { color: 'yellow', icon: RiTimeLine, label: 'Vencendo' },
-'atrasado': { color: 'red', icon: RiAlertLine, label: 'Atrasado' },
-};
-
- const { color, icon: Icon, label } = config[status];
-
- return (
-
-
- {label}
-
- );
-
-}
-
-Aplicar em:
-
-- Cards de faturas (verde = paga, amarelo = próxima, vermelho = vencida)
-- Boletos (status de pagamento)
-- Orçamentos (verde = dentro, amarelo = 80%, vermelho = estourou)
-
----
-
-8. Gráficos Interativos com Drill-Down 📊
-
-Problema: Gráficos mostram dados mas não permitem explorar
-
-Solução:
-// components/dashboard/interactive-category-chart.tsx
-
- {
-// Ao clicar em fatia, abrir modal com transações daquela categoria
-showCategoryDetails(data.categoryId);
-}}
-/>
-
-
-// Modal de drill-down
-function CategoryDetailsModal({ categoryId, period }) {
-const transactions = useCategoryTransactions(categoryId, period);
-
- return (
-
- );
-
-}
-
----
-
-9. Tema de Cores Personalizável 🎨
-
-Problema: Apenas uma cor primária (terracota)
-
-Solução:
-// lib/theme/color-themes.ts
-export const colorThemes = {
-terracotta: { primary: 'oklch(69.18% 0.18855 38.353)' },
-ocean: { primary: 'oklch(69.18% 0.18855 220)' },
-forest: { primary: 'oklch(69.18% 0.18855 140)' },
-sunset: { primary: 'oklch(69.18% 0.18855 25)' },
-lavender: { primary: 'oklch(69.18% 0.18855 280)' },
-};
-
-// Em ajustes/page.tsx
-export function ThemeColorPicker() {
-const { colorTheme, setColorTheme } = useTheme();
-
- return (
-
- {Object.entries(colorThemes).map(([name, colors]) => (
-
- );
-
-}
-
----
-
-10. Breadcrumbs e Page Headers Consistentes 🗺️
-
-Problema: Inconsistência em headers entre páginas
-
-Solução:
-// components/page-header.tsx
-interface PageHeaderProps {
-title: string;
-description?: string;
-breadcrumbs?: { label: string; href?: string }[];
-actions?: React.ReactNode;
-}
-
-export function PageHeader({
-title,
-description,
-breadcrumbs,
-actions
-}: PageHeaderProps) {
-return (
-
-{breadcrumbs && (
-
-{breadcrumbs.map((crumb, i) => (
-
-{crumb.href ? (
-
-{crumb.label}
-
-) : (
-{crumb.label}
-)}
-
-))}
-
-)}
-
-
-
{title}
-{description && (
-
{description}
-)}
-
-{actions &&
{actions}
}
-
-
-);
-}
-
-// Uso:
-
Nova Transação
-}
-/>
-
----
-
-🔧 Melhorias Técnicas
-
-1. Error Boundary Global
-
-// app/error.tsx
-'use client';
-
-export default function Error({
-error,
-reset,
-}: {
-error: Error & { digest?: string };
-reset: () => void;
-}) {
-return (
-
-
Algo deu errado!
-
-
-);
-}
-
-2. Analytics e Telemetria
-
-// lib/analytics.ts
-export function trackEvent(event: string, properties?: Record) {
-// Posthog, Mixpanel, ou custom
-console.log('[Analytics]', event, properties);
-}
-
-// Uso:
-trackEvent('transaction_created', { type: 'despesa', amount: 100 });
-
-3. Rate Limiting para Actions
-
-// lib/rate-limit.ts
-import { Ratelimit } from '@upstash/ratelimit';
-
-const ratelimit = new Ratelimit({
-redis: Redis.fromEnv(),
-limiter: Ratelimit.slidingWindow(10, '10 s'),
-});
-
-export async function checkRateLimit(userId: string) {
-const { success } = await ratelimit.limit(userId);
-if (!success) throw new Error('Rate limit exceeded');
-}
-
----
-
-📊 Priorização Sugerida
-
-🔥 Fase 1 - Quick Wins (1-2 semanas)
-
-1. ✅ Breadcrumbs e Page Headers consistentes
-2. ✅ Command Palette (⌘K)
-3. ✅ Indicadores visuais de status
-4. ✅ Modo card para tabelas em mobile
-5. ✅ Relatórios PDF básicos
-
-🚀 Fase 2 - Value Boost (1 mês)
-
-1. 🎯 Metas Financeiras
-2. 🔮 Análise Preditiva
-3. 🔔 Sistema de Notificações
-4. 📊 Gráficos interativos com drill-down
-5. 🎓 Onboarding interativo
-
-💎 Fase 3 - Diferenciais (2-3 meses)
-
-1. 🔄 Importação automática de extratos (OFX/CSV)
-2. 📎 Anexos e comprovantes com OCR
-3. 🎨 Temas personalizáveis
-4. 🏆 Gamificação e conquistas
-5. 💹 Tracking de investimentos
-
----
-
-🎯 Métricas de Sucesso
-
-Para medir o impacto das melhorias:
-
-1. Engajamento:
-
-
- - Tempo médio na aplicação
- - Frequência de uso (DAU/MAU)
- - Transações criadas por usuário/mês
-
-2. Usabilidade:
-
-
- - Taxa de conclusão de onboarding
- - Tempo para criar primeira transação
- - Taxa de erro em formulários
-
-3. Performance:
-
-
- - LCP (Largest Contentful Paint) < 2.5s
- - FID (First Input Delay) < 100ms
- - CLS (Cumulative Layout Shift) < 0.1
-
-4. Adoção de Features:
-
-
- - % de usuários usando metas
- - % de usuários que personalizam dashboard
- - Taxa de uso do command palette
-
----
-
-📝 Conclusão
-
-O OpenSheets já possui uma base sólida com excelente arquitetura e design. As sugestões focam em:
-
-1. Melhorar a experiência mobile (responsividade avançada)
-2. Adicionar inteligência (previsões, notificações, insights)
-3. Aumentar a eficiência (command palette, importação automática)
-4. Personalização (temas, dashboard, densidade)
-5. Gamificação (metas, conquistas) para engajamento
-
-Próximos Passos Recomendados:
-
-1. Validar com usuários quais features têm maior demanda
-2. Implementar quick wins da Fase 1
-3. A/B testing de novos designs
-4. Iteração baseada em feedback