Fase 2


Escopo


  • Transformar a maneira como as pessoas gerenciam suas finanças pessoais, oferecendo uma plataforma intuitiva, moderna e inteligente se tornando um aliado estratégico para a construção de uma vida financeira equilibrada e próspera
  • Como parte da implementação, temos uma interface amigável com funcionalidades inovadoras, democratizando o controle financeiro, permitindo que qualquer pessoa, independentemente do seu nível de conhecimento, possa acompanhar gastos, estabelecer metas, visualizar relatórios e tomar decisões com segurança e confiança
  • Serão desenvolvidos recursos para o uso de inteligência artificial integrada oferecendo recomendações personalizadas, tornando o processo de gestão mais simples e eficiente
  • A proposta é otimizar o desafio do controle financeiro em uma experiência prática, prazerosa e acessível para todos
  • O nome Eden reflete o propósito do sistema de criar um ambiente onde o usuário possa cultivar uma vida financeira saudável e organizada.


Proposta de projeto


  • O objetivo é implementar a conectividade e aprimorar a experiência visual e organizacional para reter usuários e validar o modelo de crescimento, transformando a gestão financeira em um processo menos manual e mais intuitivo.


Requisitos Funcionais



Fase 1 - 2025-1


  • RF01 - Realizar login
    • O usuário deverá, ao abrir o sistema, realizar login no sistema colocando email e senha, previamente cadastrado.
      • Prioridade: Alta


  • RF02 - Cadastrar usuário
    • O usuário deverá, caso não tenha realizado o cadastro no sistema, se cadastrar para coleta de dados por parte do sistema.
      • Prioridade: Alta


  • RF03 - Alteração de dados pessoais
    • O usuário poderá alterar as suas informações pessoais por meio do sistema
      • Prioridade: Alta


  • RF04 – Selecionar um mês para gerenciamento
    • O usuário poderá selecionar um mês para gerenciá-lo
      • Prioridade: Muito Alta


  • RF05 - Adicionar Movimentação
    • Descrição: o usuário poderá adicionar uma movimentação em um dado mês informando obrigatoriamente: nome, categoria, valor e data de lançamento. Também será possível adicionar uma descrição, de maneira opcional.
      • Prioridade: Muito Alta


  • RF06 - Editar Movimentação
    • Ao selecionar uma movimentação o usuário poderá editá-la, alterando qualquer característica.
      • Prioridade: Muito Alta


  • RF07 - Excluir Movimentação
    • O usuário poderá excluir uma movimentação
      • Prioridade: Muito Alta


  • RF08 - Listar Movimentações
    • Ao abrir a página inicial, ou ao selecionar um mês em específico, deverá ser listado as movimentações do mês. Caso seja aberta a página inicial, deverá ser listada movimentações do mês corrente.
      • Prioridade: Muito Alta


  • RF09] – Exibir movimentação de forma detalhada
    • Ao selecionar uma movimentação em específico, o sistema deverá exibir as informações de maneira detalhada.
      • Prioridade: Muito Alta


  • RF10 - Resumir dados de um mês
    • O sistema deverá listar os meses com lançamento por parte do usuário exibindo informações resumidas, somando totais de ganhos e gastos do referido mês.
      • Prioridade: Alta


  • RF11 - Cadastrar meta financeira
    • o sistema deve possibilitar o usuário cadastrar uma meta financeira
      • Prioridade: Média



  • RF12 - Editar meta financeira
    • O usuário terá a possibilidade de editar as metas criadas
      • Prioridade: Média


  • RF13 - Excluir meta financeira
    • O usuário poderá excluir sua meta financeira, no entanto, ao excluir perderá todos os lançamentos referente à meta.
      • Prioridade: Média


  • RF14 - Listar histórico das metas financeiras
    • O sistema deve listar o histórico de colaborações de acordo com a meta financeira escolhida pelo usuário.
      • Prioridade: Alta


  • RF15 - Adicionar limite para categoria ou meta financeira
    • Ao selecionar um mês o usuário deverá ter a opção de planejar seus gastos limitando porcentagens às categorias em determinado mês.
      • Prioridade: Média


  • RF16 - Listar categorias que passaram do limite
    • O sistema deve permitir que o usuário veja as categorias que passaram do limite cadastrado em determinado mês
      • Prioridade: Média


  • RF17 - Gerar dados em formato de gráfico
    • Descrição: o sistema deverá possibilitar uma visão dos gastos, divididos em categorias, por meio de um gráfico que facilite a visão fragmentada das movimentações e o percentual em relação ao todo.
      • Prioridade: Alta


  • RF18 - Gerar dados em formato CSV
    • O sistema deverá listar o relatório de gastos, dado um mês, em formato .csv permitindo trabalho das informações em outros softwares.
      • Prioridade: Baixa


  • RF19 - Solicitar dados para IA
    • O sistema irá formatar os dados para que seja solicitado a análise de IA. Essa formatação molda os dados agrupando por categoria de movimentação financeira.
      • Prioridade: Baixa


  • RF20 - Comparar meses com IA
    • O sistema formatará os dados para dois meses solicitados para análise de IA. Será agrupado por categorias e meses e solicitará para IA a comparação entre os meses.
      • Prioridade: Baixa


Fase 2 - 2025-2



  • RF01: Criar Dashboard que mostre ??
  • RF02: Incrementar a categoria metas com agrupamento

Requisitos Não-Funcionais


  • RNF01 - Sistema fluido:
      • Os tempos de carregamento e processamento de informações não devem ultrapassar 2 segundos, exceto nos casos de geração de relatórios.


  • RNF02 - Autenticação de usuário:
    • Descrição: Para a autenticação de usuário, será utilizado um e-mail e uma senha. A senha deve conter pelo menos uma letra, um número, um caractere especial, e ter no mínimo 8 e no máximo 16 caracteres.


  • RNF03 - Proteção das informações dos usuários:
    • As informações pessoais dos usuários não devem ser acessíveis por terceiros, exceto pelo próprio dono dessas informações. Deve ser adotado um nível de criptografia suficiente para impedir a associação entre dados considerados não sensíveis (como valores) e seus respectivos usuários.


  • RNF04 - Consentimento para uso de dados:
    • Os usuários devem poder autorizar e revogar a autorização para o uso de seus dados nas funcionalidades de inteligência artificial.


  • RNF05 - Sistema escalável:
    • O sistema deve ser escalável, suportando um grande número de usuários simultâneos sem perda de desempenho ou fluidez.


  • RNF06] - Alta disponibilidade:
    • O sistema deve apresentar alta disponibilidade, com tempo de inatividade reduzido ao mínimo.


  • RNF07] - Sistema portátil:
    • O sistema deve funcionar corretamente em dispositivos com diferentes tamanhos de tela (como tablets e smartphones), mantendo a qualidade das interfaces. Também deve ser compatível com os principais navegadores (Google Chrome, Microsoft Edge, Safari e Mozilla Firefox).


  • RNF08 - Cálculos precisos:
    • Os cálculos realizados pelo sistema não podem conter erros.

Melhores práticas

Simple Responsability Principle (Princípio da Responsabilidade Única): Para evidenciar tal característica em nosso sistema podemos citar as models de nosso projeto. Como buscamos usar o padrão MVC (Model-View-Controler) durante o desenvolvimento, as classes que representam nossas models exemplificam uma aplicação do princípio em questão. Como exemplo a seguir:

import prisma from './connection'
export const getCategoriaByUser = async (userId: string) => {
  return prisma.categoria.findMany({ where: { userId } });
};

export const getCategoriaById = async (id: string) => {
    return prisma.categoria.findUnique({ where: { id } });
}

export const updateCategoria = async (id: string, data: { name?: string; description?: string; desconto?: boolean}) => {
    return prisma.categoria.update({ where: { id }, data: data });
}

export const deleteCategoria = async (id: string) => {
    return prisma.categoria.delete({ where: { id } });
}

export const createCategoria = async (data: { userId: string; name: string; description: string; valor: number, desconto: boolean }) =>
{
    //Todo: confirir os valores iniciais de concluido e desconto
    return prisma.categoria.create({ data: data });
}

As funções que compõem o arquivo acima buscam, unicamente, alterar a entidade “Categoria”, chamando interações com o banco de dados que afetam unicamente a tabela “categoria”.

Open/Closed Principle (Aberto para extensão, fechado para modificação): Para evidenciar o uso do princípio aberto/fechado podemos usar, também, as models de nosso projeto. Tal característica se torna evidente quando observamos que, para adicionar novas funcionalidades a uma determinada entidade do projeto, dada a estrutura, não é necessário alterar as demais funcionalidades existentes. Como exemplo o exemplo acima.

Interface Segregation Principle (Segregação de Interfaces): Para demonstrar a Segregação de Interface temos a interação das models com as controlers, onde as controlers importam apenas as models necessários para sua execução, de modo separado. Portanto, a controler não precisa importar uma grande interface com “funções inúteis” para o seu contexto.

Dependency Inversion Principle (Princípio da Inversão de Dependência): Como exemplo para tal princípio temos nosso Cliente “Prisma”, usando para intermediar nossas interações com o banco de dados. Ele é um framework que, por meio da especificação de uma entidade, é construído a tabela em nosso banco de dados e feito os métodos de consulta e alteração de informações. Portanto, se enquadra em uma classe abstrata, onde tem o seu caráter de classe mas também possui características de interface (definição de funções para uso geral e padronizado). Dado isso, as figuras a seguir mostram a criação da entidade e uso nas classes:

import { PrismaClient } from '@prisma/client';

declare global {
  var prisma: PrismaClient | undefined;
}

const prisma = globalThis.prisma || new PrismaClient();

if (process.env.NODE_ENV !== 'production') {
  globalThis.prisma = prisma;
}

// A única coisa que este arquivo faz é exportar
// a instância única do Prisma.
export default prisma;
import prisma from './connection'

export const getLimitesMensaisByUser = async (userId: string) => {
    return prisma.limiteMensal.findMany({ where: { userId } });
    }

Code review:

ValidaCadastro( )

export async function validaCadastro(name:string,email:string,password:string):Promise<string>{
    if (!email || !email.includes('@'))
        return "Email invalido"
    if(password.length<1)
        return "Senha nao pode ser vazia"
    if(name.length<1)
        return "Nome nao pode ser vazio"
    try {
    // 3. Buscar o usuário no banco de dados
    let user = await getUserByEmail(email)

    // 4. Verificar se o usuário existe 
    if (user) {
      return "O email ja possui uma conta" 
    }
    user = await registerUser(name,email,password)
    if (!user) {
      return "Falha ao registrar"
    }
    // Geração do Token JWT
    const token = jwt.sign(
        { userId: user.id, email: user.email },
        process.env.JWT_SECRET!,
        { expiresIn: '1h' }
        );

        // Criação do Cookie

      const cookieStore = await cookies();
      cookieStore.set('authToken', token, {
        httpOnly: true,
        secure: process.env.NODE_ENV === 'production',
        sameSite: 'strict',
        maxAge: 3600,
        path: '/',
      })

  } catch (error) {
    console.error(error);
    return "Ocorreu um erro no servidor. Tente novamente mais tarde." ;
  }
  redirect('/dashboard');

}

Podemos extrair a validação (linhas 10:15) para uma função que ficaria responsável apenas por isso, tornando a adição de validações no futuro mais assertiva sem que haja modificação na função de validação do cadastro.

ValidaLogin( )

export async function validaLogin(email:string,password:string):Promise<string>{
    if (!email || !email.includes('@'))
        return "Email invalido"
    if(password.length<1)
        return "Senha nao pode ser vazia"
    try {
    // 3. Buscar o usuário no banco de dados
    const user = await getUserByEmail(email)

    // 4. Verificar se o usuário existe 
    if (!user) {
      return "Email ou senha incorretos" 
    }
    const passwordsMatch = await bcrypt.compare(password, user.password);
    if (!passwordsMatch) 
      return "Email ou senha incorretos" 
    // Geração do Token JWT
    const token = jwt.sign(
        { userId: user.id, email: user.email },
        process.env.JWT_SECRET!,
        { expiresIn: '1h' }
        );

        // Criação do Cookie

      const cookieStore = await cookies();
      cookieStore.set('authToken', token, {
        httpOnly: true,
        secure: process.env.NODE_ENV === 'production',
        sameSite: 'strict',
        maxAge: 3600,
        path: '/',
      })

  } catch (error) {
    console.error(error);
    return "Ocorreu um erro no servidor. Tente novamente mais tarde." ;
  }
  redirect('/dashboard');

}

A função validaLogin está muito carregada, necessário separar as responsabilidades em funções menores, e os erros informam exatamente o que deu errado, em um login as exceções devem manter oculto o que aconteceu, isso facilita ataques de força bruta/.

Evolução do projeto


Item Data Atividades Eden Realizado
1 14/11/2025 Documentar tópico Investigação 100%
2 14/11/2025 Documentar os Manuais 100%
3 14/11/2025 Validar Visão do Usuário 100%
4 14/11/2025 Definir Proposta de Projeto 100%
5 17/11/2025 Especificar RFs e RNFs - Fase 2 100%
6 17/11/2025 RF01: Criar o Dashboard 50%
x 24/11/2025 TeckWeek
7 01/12/2025 Melhores Práticas 100%
8 01/12/2025 RF01: Criar o Dashboard 75%
9 08/12/2025 RF01: Criar o Dashboard
10 15/12/2025 2a. Entrega - vídeo até 19/12 pelo Teams - RFs 1 e 2
11 RF02: Incrementar categoria metas com agrupamento
12 Incrementar diferencial tecnológico
13 Desenvolver 3o RF