Douglas Pinheiro (discussão | contribs)
 
(18 revisões intermediárias por 3 usuários não estão sendo mostradas)
Linha 168: Linha 168:


== Melhores práticas ==
== Melhores práticas ==
<br>
<p>
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:
</p>
<div>
<pre>
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 });
}
</pre>
</div>
<p>
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”.
</p>
<p>
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.
</p>
<p>
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.
</p>
<p>
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:
</p>
<pre>
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;
</pre>
<pre>
import prisma from './connection'
 
export const getLimitesMensaisByUser = async (userId: string) => {
    return prisma.limiteMensal.findMany({ where: { userId } });
    }
</pre>
<p>
Code review:
</p>
<p>
ValidaCadastro( )
</p>
<pre>
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');
 
}
</pre>
<p>
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.
</p>
<p>
ValidaLogin( )
</p>
<pre>
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');
 
}
</pre>
<p>
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/.
</p>


= Evolução do projeto =
= CRONOGRAMA =
<br>
<br>


Linha 177: Linha 345:
! Item !! Data !! Atividades Eden!! Realizado
! Item !! Data !! Atividades Eden!! Realizado
|-
|-
| 1 || 14/11/2025 || Documentar tópico Investigação || 0%
| 1 || 14/11/2025 || Documentar tópico Investigação || 100%
|-
|-
| 2 || 14/11/2025 || Documentar os Manuais || 50%
| 2 || 14/11/2025 || Documentar os Manuais || 100%
|-
|-
| 3 || 14/11/2025 || Validar Visão do Usuário || 0%
| 3 || 14/11/2025 || Validar Visão do Usuário || 100%
|-
|-
| 4 || 14/11/2025 || Definir Proposta de Projeto || 0%
| 4 || 14/11/2025 || Definir Proposta de Projeto || 100%
|-
|-
| 5 || 17/11/2025 || Especificar RFs e RNFs - Fase 2 || 100%
| 5 || 17/11/2025 || Especificar RFs e RNFs - Fase 2 || 100%
|-
|-
| 6 || 17/11/2025 || RF01: Criar o Dashboard || 50%
| 6 || 17/11/2025 || RF01: Criar o Dashboard || 100%
|-
|-
| x || 24/11/2025 || TeckWeek ||
| x || 24/11/2025 || TeckWeek ||
|-
|-
| 7 || 01/12/2025 || Melhores Práticas ||
| 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 || 100%
|-
|-
| 8 || 01/12/2025 || RF01: Criar o Dashboard ||
| 10 || 15/12/2025 || 2a.  Entrega - vídeo até 19/12 pelo Teams - RFs 1 e 2 || 100%
|-
|-
| 9 || || RF02:  Incrementar categoria metas com agrupamento ||
| 11 || 09/02/2026 || RF02:  Incrementar categoria metas com agrupamento || 100%
|-
|-
| 10 || || Incrementar diferencial tecnológico ||
| 12 || || Incrementar diferencial tecnológico ||
|-
| 13 || || RF03: Adicionar limite para categoria || 0%
|-
| 14 || 19/12/2025 || Cliente aguardando vídeo demo ||
|-
|}
 
{| class="wikitable"
|-
|-
| 11 || || Desenvolver 3o RF ||
! Item !! Data !! Atividades Eden!! Responsável
|-
|-
| 1 || 09/02/2026 || i) Organização cronograma || i) Todos Integrantes;
|-
| 2 || 09/02/2026 || ii)RF03: Adicionar limite para categoria; || ii) Douglas;
|-
| 3 || 09/02/2026 || iii) Projeto - Documentação; || iii) Enzo;
|-
| 4 || 09/02/2026 || iv) Q&A - Documentação; || iv) Sara;
|-
| 5 || 09/02/2026 || v) Melhores Práticas - Documentação; || v) Maycon;
|-
| 6 || 09/02/2026 || vi) Segurança - Documentação; || vi) Tavares;
|-
| 7 || 23/02/2026 || i)RF03: Adicionar limite para categoria; || i) Douglas;
|-
| 8 || 23/02/2026 || ii) Requisitos - Documentação; || ii) Douglas;
|-
| 9 || 23/02/2026 || iii) Usabilidade - Documentação; || iii) Douglas;
|-
| 10 || 23/02/2026 || iv) Projeto - Documentação; || iv) Enzo;
|-
| 11 || 23/02/2026 || v) Q&A - Documentação; || v) Sara;
|-
| 12 || 23/02/2026 || vi) Deploy - Documentação; || vi) Maycon;
|-
| 13 || 23/02/2026 || vii) Segurança - Documentação; || vii) Tavares
|-
| 14 || 02/03/2026 || i) Requisitos - Documentação; || i) Douglas;
|-
| 15 || 02/03/2026 || ii) Projeto - Documentação; || ii) Enzo;
|-
| 16 || 02/03/2026 || iii) Versionamento - Documentação; || iii) Douglas;
|-
| 17 || 02/03/2026 || iv) Deploy - Documentação; || iv) Maycon;
|-
| 18 || 02/03/2026 || v) Q&A - Documentação; || v) Sara;
|-
| 19 || 02/03/2026 || vi) Segurança - Documentação; || vi) Tavares;
|-
| 20 || 02/03/2026 || vii) Melhores Práticas - Documentação; || vii) Maycon;
|-
| 21 || 02/03/2026 || viii) Usabilidade - Documentação || viii) Douglas;
|-
| 4 || 09/03/2026 || xx ||
|-
| 5 || 16/03/2026 || xx ||
|-
|}
|}

Edição atual tal como às 00h00min de 10 de fevereiro de 2026

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/.

CRONOGRAMA


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 100%
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 100%
10 15/12/2025 2a. Entrega - vídeo até 19/12 pelo Teams - RFs 1 e 2 100%
11 09/02/2026 RF02: Incrementar categoria metas com agrupamento 100%
12 Incrementar diferencial tecnológico
13 RF03: Adicionar limite para categoria 0%
14 19/12/2025 Cliente aguardando vídeo demo
Item Data Atividades Eden Responsável
1 09/02/2026 i) Organização cronograma i) Todos Integrantes;
2 09/02/2026 ii)RF03: Adicionar limite para categoria; ii) Douglas;
3 09/02/2026 iii) Projeto - Documentação; iii) Enzo;
4 09/02/2026 iv) Q&A - Documentação; iv) Sara;
5 09/02/2026 v) Melhores Práticas - Documentação; v) Maycon;
6 09/02/2026 vi) Segurança - Documentação; vi) Tavares;
7 23/02/2026 i)RF03: Adicionar limite para categoria; i) Douglas;
8 23/02/2026 ii) Requisitos - Documentação; ii) Douglas;
9 23/02/2026 iii) Usabilidade - Documentação; iii) Douglas;
10 23/02/2026 iv) Projeto - Documentação; iv) Enzo;
11 23/02/2026 v) Q&A - Documentação; v) Sara;
12 23/02/2026 vi) Deploy - Documentação; vi) Maycon;
13 23/02/2026 vii) Segurança - Documentação; vii) Tavares
14 02/03/2026 i) Requisitos - Documentação; i) Douglas;
15 02/03/2026 ii) Projeto - Documentação; ii) Enzo;
16 02/03/2026 iii) Versionamento - Documentação; iii) Douglas;
17 02/03/2026 iv) Deploy - Documentação; iv) Maycon;
18 02/03/2026 v) Q&A - Documentação; v) Sara;
19 02/03/2026 vi) Segurança - Documentação; vi) Tavares;
20 02/03/2026 vii) Melhores Práticas - Documentação; vii) Maycon;
21 02/03/2026 viii) Usabilidade - Documentação viii) Douglas;
4 09/03/2026 xx
5 16/03/2026 xx