Este projeto é uma implementação de um planner virtual, desenvolvido para a disciplina de Paradigmas de Linguagens de Programação da Universidade Federal do Agreste de Pernambuco (UFAPE). O sistema foi construído utilizando a linguagem de programação Rust e o framework web Rocket.
Acesse a aplicação em produção: https://agenda98.duckdns.org
💡 A aplicação está hospedada em um servidor próprio com Docker, PostgreSQL, Nginx e certificado SSL.
Gabriel Silva |
Raylandson Cesário |
Jorge Ribeiro |
Clívisson Barbosa |
|---|
O objetivo principal é criar um sistema de planner que permita aos usuários organizar suas metas e tarefas diárias de forma eficiente. O planner oferece funcionalidades para criação, acompanhamento e análise de produtividade, com os dados sendo armazenados de forma persistente.
# Clone o repositório
git clone https://github.com/AgendaRust/Agenda.git
cd Agenda
# Configure as variáveis de ambiente
cat > .env << EOF
JWT_SECRET_KEY=your-super-secret-jwt-key-here-must-be-32-chars-minimum
DB_USER=agenda_user
DB_PASSWORD=secure_password_change_me
DB_NAME=agenda_db
DB_HOST=db
DB_PORT=5432
DATABASE_URL=postgresql://\${DB_USER}:\${DB_PASSWORD}@\${DB_HOST}:\${DB_PORT}/\${DB_NAME}
EOF
# Compile o frontend
cd frontend
trunk build --release
cd ..
# Inicie todos os serviços com Docker
docker compose up --buildURLs:
- Frontend: http://localhost:8000
- Backend API: http://localhost:8000/api
- Adminer (Database UI): http://localhost:8080 (only with
--profile debug)
# Clone o repositório
git clone https://github.com/AgendaRust/Agenda.git
cd Agenda
# Inicie o PostgreSQL (backend)
cd backend
docker-compose up -d
# Configure e execute as migrações
echo "DATABASE_URL=postgresql://agenda_user:secure_password_change_me@localhost:5432/agenda_db" > .env
echo "JWT_SECRET_KEY=your-super-secret-jwt-key-here-must-be-32-chars-minimum" >> .env
cargo install sea-orm-cli
cd migration
cargo run
cd ..
# Execute o backend
cargo run
# Em outro terminal, execute o frontend
cd ../frontend
trunk serve --port 8081URLs:
- Backend API: http://localhost:8000
- Frontend: http://localhost:8081
- Adminer (Database UI): http://localhost:8080
Para executar com Docker (Recomendado):
Para desenvolvimento local:
- Rust (versão mais recente)
- Docker (apenas para PostgreSQL)
- Trunk para build do frontend
- cargo-watch (opcional) para desenvolvimento com hot reload
- Compilador C (Clang ou GCC): O frontend possui dependências (como a crate ring usada para criptografia em jsonwebtoken) que necessitam de um compilador C para serem compiladas.
-
Clone o repositório
git clone https://github.com/AgendaRust/Agenda.git cd Agenda -
Configure as variáveis de ambiente
Crie o arquivo
.envna raiz do projeto:cat > .env << EOF JWT_SECRET_KEY=your-super-secret-jwt-key-here-must-be-32-chars-minimum DB_USER=agenda_user DB_PASSWORD=secure_password_change_me DB_NAME=agenda_db DB_HOST=db DB_PORT=5432 DATABASE_URL=postgresql://\${DB_USER}:\${DB_PASSWORD}@\${DB_HOST}:\${DB_PORT}/\${DB_NAME} EOF
-
Compile o frontend
⚠️ IMPORTANTE: Sempre use--releasepara produção!cd frontend rustup target add wasm32-unknown-unknown cargo install trunk trunk build --release # NÃO use apenas "trunk build" cd ..
Por quê
--releaseé obrigatório?trunk build(sem --release) = build de desenvolvimento com WebSocket para hot-reloadtrunk build --release= build otimizado para produção sem código de desenvolvimento
Se você usar apenas
trunk build, verá erros de WebSocket no navegador. -
Inicie todos os serviços
docker compose up --build
Isso irá:
- Criar e iniciar o banco de dados PostgreSQL
- Executar as migrações automaticamente
- Iniciar o backend (API Rust/Rocket)
- Servir o frontend compilado
- Iniciar o Adminer (interface web para gerenciar o banco)
-
Acesse a aplicação
- Frontend: http://localhost:8000
- Backend API: http://localhost:8000/api
- Adminer: http://localhost:8080 (opcional, apenas para debug)
Nota: Por padrão, o Adminer não é iniciado. Para usá-lo, execute:
docker compose --profile debug up -d adminer
-
Clone o repositório
git clone https://github.com/AgendaRust/Agenda.git cd Agenda -
Inicie o PostgreSQL
cd backend docker-compose up -dIsso irá iniciar:
- PostgreSQL na porta 5432
- Adminer na porta 8080
-
Configure o backend
cd backendCrie o arquivo .env:
cat > .env << EOF DATABASE_URL=postgresql://agenda_user:secure_password_change_me@localhost:5432/agenda_db JWT_SECRET_KEY=your-super-secret-jwt-key-here-must-be-32-chars-minimum DB_USER=agenda_user DB_PASSWORD=secure_password_change_me DB_NAME=agenda_db EOF
Instale o SeaORM CLI:
cargo install sea-orm-cli
Execute as migrations:
cd migration cargo run cd ..
-
Execute o backend
Para desenvolvimento (com auto-reload):
cargo install cargo-watch # se ainda não tiver cargo watch -x runPara execução simples:
cargo run
-
Execute o frontend (em outro terminal)
cd frontend rustup target add wasm32-unknown-unknown cargo install trunk trunk serve --port 8081 -
Acesse a aplicação
- Backend API: http://localhost:8000
- Frontend: http://localhost:8081
- Adminer: http://localhost:8080
Nota: O frontend em modo de desenvolvimento (trunk serve --port 8081) automaticamente se conectará ao backend em http://localhost:8000/api. Em produção (Docker), usa o caminho relativo /api.
- Servidor Linux com Docker e Docker Compose instalados
- Domínio configurado (exemplo: DuckDNS)
- Nginx instalado como reverse proxy
- Certificado SSL (Let's Encrypt recomendado)
-
Clone o repositório no servidor
ssh user@your-server git clone https://github.com/AgendaRust/Agenda.git cd Agenda -
Configure variáveis de ambiente de produção
⚠️ IMPORTANTE: Gere senhas fortes e únicas!# Gere um JWT secret forte JWT_SECRET=$(openssl rand -base64 32) # Gere uma senha forte para o banco DB_PASSWORD=$(openssl rand -base64 24) # Crie o arquivo .env cat > .env << EOF JWT_SECRET_KEY=${JWT_SECRET} DB_USER=agenda_user DB_PASSWORD=${DB_PASSWORD} DB_NAME=agenda_db DB_HOST=db DB_PORT=5432 DATABASE_URL=postgresql://\${DB_USER}:\${DB_PASSWORD}@\${DB_HOST}:\${DB_PORT}/\${DB_NAME} EOF # Proteja o arquivo chmod 600 .env
-
Compile o frontend no servidor (ou em sua máquina local)
cd frontend rustup target add wasm32-unknown-unknown cargo install trunk trunk build --release cd ..
-
Configure o Nginx como reverse proxy
sudo nano /etc/nginx/sites-available/agenda
Cole a seguinte configuração:
server { listen 80; server_name seu-dominio.duckdns.org; # Redirect HTTP to HTTPS return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name seu-dominio.duckdns.org; # SSL Configuration (Let's Encrypt) ssl_certificate /etc/letsencrypt/live/seu-dominio.duckdns.org/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/seu-dominio.duckdns.org/privkey.pem; # Strong SSL settings ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; # Security headers add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # WebSocket support (if needed) proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }
Ative o site:
sudo ln -s /etc/nginx/sites-available/agenda /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx
-
Obtenha certificado SSL com Let's Encrypt
sudo apt update sudo apt install certbot python3-certbot-nginx sudo certbot --nginx -d seu-dominio.duckdns.org
O certbot irá:
- Gerar o certificado SSL
- Configurar renovação automática
- Atualizar sua configuração do Nginx
-
Inicie a aplicação
docker compose up -d --build
-
Verifique os logs
docker compose logs -f
-
Acesse sua aplicação
https://seu-dominio.duckdns.org
Certifique-se de que as seguintes portas estão abertas no seu roteador:
- Porta 80 (HTTP - para redirecionamento e Let's Encrypt)
- Porta 443 (HTTPS - para acesso seguro)
# Ver logs em tempo real
docker compose logs -f app
# Reiniciar apenas o backend
docker compose restart app
# Parar tudo
docker compose down
# Parar e remover volumes (cuidado! apaga dados)
docker compose down -v
# Backup do banco de dados
docker compose exec db pg_dump -U agenda_user agenda_db > backup_$(date +%Y%m%d).sql
# Restaurar backup
cat backup_20231025.sql | docker compose exec -T db psql -U agenda_user -d agenda_db
# Atualizar aplicação
git pull
cd frontend && trunk build --release && cd ..
docker compose up -d --build✅ Checklist de Segurança:
- JWT_SECRET_KEY com pelo menos 32 caracteres aleatórios
- Senha forte do banco de dados (DB_PASSWORD)
- Arquivo
.envcom permissões restritas (chmod 600 .env) - HTTPS configurado com certificado válido
- Adminer desabilitado (não inicie com
--profile debugem produção) - Firewall configurado (apenas portas 80, 443 e SSH abertas)
- Backups automáticos do banco de dados configurados
- Monitoramento de logs ativo
Renovação automática do SSL: O certbot configura automaticamente a renovação. Teste com:
sudo certbot renew --dry-runBackup automático: Crie um cron job para backup diário:
crontab -eAdicione:
0 2 * * * cd /caminho/para/Agenda && docker compose exec -T db pg_dump -U agenda_user agenda_db > backup_$(date +\%Y\%m\%d).sqlEste projeto utiliza PostgreSQL com SeaORM para gerenciamento do banco de dados e migrations.
O arquivo .env deve conter as seguintes variáveis:
Para Docker (raiz do projeto - .env):
JWT_SECRET_KEY=your-super-secret-jwt-key-here-must-be-32-chars-minimum
DB_USER=agenda_user
DB_PASSWORD=secure_password_change_me
DB_NAME=agenda_db
DB_HOST=db
DB_PORT=5432
DATABASE_URL=postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}Para desenvolvimento local (backend/.env):
DATABASE_URL=postgresql://agenda_user:secure_password_change_me@localhost:5432/agenda_db
JWT_SECRET_KEY=your-super-secret-jwt-key-here-must-be-32-chars-minimum
DB_USER=agenda_user
DB_PASSWORD=secure_password_change_me
DB_NAME=agenda_db
DB_HOST=localhost
DB_PORT=5432Importante:
DATABASE_URL: String de conexão com PostgreSQLJWT_SECRET_KEY: Chave secreta para assinatura de tokens JWT (deve ter pelo menos 32 caracteres para segurança)DB_HOST: Usedbpara Docker oulocalhostpara desenvolvimento local
# Aplicar todas as migrations pendentes (via Docker)
docker compose run migrations ./migration-cli up
# Aplicar migrations localmente
cd backend/migration
cargo run
# Verificar status das migrations
sea-orm-cli migrate status
# Reverter a última migration
sea-orm-cli migrate down
# Resetar o banco (cuidado! apaga todos os dados)
sea-orm-cli migrate reset
# Gerar uma nova migration
sea-orm-cli migrate generate nome_da_migration
# Criar as entidades
sea-orm-cli generate entity -u postgresql://user:password@localhost:5432/agenda_db -o src/entityTabelas principais:
user- Usuários do sistematask- Tarefas diárias (begin_date, complete_date, category, type)goal- Metas (date_start, date_end, category, type)reminder- Lembretes semanais (date_end, category)notes- Notas (created_at)
Nota: Todas as colunas de data/hora utilizam TIMESTAMPTZ (timestamp with timezone) para compatibilidade com DateTimeUtc do Rust.
Via Adminer (Interface Web):
- Acesse http://localhost:8080
- Faça login com:
- System:
PostgreSQL - Server:
db(Docker) oulocalhost(local) - Username: valor de
DB_USER - Password: valor de
DB_PASSWORD - Database: valor de
DB_NAME
- System:
Via linha de comando:
# Usando Docker
docker compose exec db psql -U agenda_user -d agenda_db
# Localmente (se PostgreSQL estiver instalado)
psql postgresql://agenda_user:secure_password_change_me@localhost:5432/agenda_dbErro de conexão com PostgreSQL:
- Verifique se o Docker está rodando:
docker ps - Confirme que o PostgreSQL está ativo:
docker compose ps - Verifique se as variáveis de ambiente estão corretas no
.env - Para Docker, use
DB_HOST=db; para local, useDB_HOST=localhost
Migration não funciona:
- Certifique-se de que o PostgreSQL está rodando
- Verifique a string de conexão em
DATABASE_URL - Execute
cargo install sea-orm-clipara instalar a CLI - No Docker, as migrations são executadas automaticamente no serviço
migrations
Erros de WebSocket no frontend ({{__TRUNK_ADDRESS__}} etc.):
- Certifique-se de usar
trunk build --release(não apenastrunk build) - O build de desenvolvimento não deve ser usado no Docker
- Verifique se não há placeholders Trunk no
frontend/dist/index.html:grep -c "{{__TRUNK" frontend/dist/index.html # Deve retornar 0
Resetar o banco de dados completamente:
# Parar containers e remover volumes
docker compose down -v
# Reiniciar tudo do zero
docker compose up --build.env, precisa remover o volume antigo:
docker compose down -v # O -v remove os volumes
docker compose up --buildAcessar Adminer para debug:
# Iniciar Adminer
docker compose --profile debug up -d adminer
# Acessar em http://localhost:8080
# Server: db
# Username: valor de DB_USER
# Password: valor de DB_PASSWORD
# Database: valor de DB_NAME
# Parar Adminer
docker compose --profile debug downAgenda/
├── backend/ # API em Rust com Rocket
│ ├── src/
│ │ ├── main.rs
│ │ ├── routes/
│ │ ├── entity/
│ │ ├── dto/
│ │ └── service/
│ ├── migration/ # Migrations do banco de dados
│ ├── docker-compose.yml # PostgreSQL + Adminer (dev local)
│ └── Cargo.toml
├── frontend/ # Interface web em Yew (WebAssembly)
│ ├── src/
│ │ ├── main.rs
│ │ ├── components/
│ │ ├── pages/
│ │ └── services/
│ ├── dist/ # Build de produção (gerado pelo Trunk)
│ ├── index.html
│ └── Cargo.toml
├── .dockerfile # Multi-stage build para produção
├── docker-compose.yml # Orquestração completa da aplicação
├── .env # Variáveis de ambiente
└── README.md
- Criação de Metas: O usuário pode criar metas para a semana, mês e ano.
- Detalhes da Meta: Cada meta é composta por uma descrição e uma categoria.
- Acompanhamento: É possível selecionar se as metas foram atingidas com sucesso, parcialmente atingidas ou não atingidas.
- Agendamento Diário: Permite criar um planejamento de atividades para um dia específico.
- Duração da Tarefa: As tarefas podem ser alocadas em blocos de tempo de meia hora, uma hora ou um turno do dia (manhã, tarde, noite).
- Detalhes da Tarefa: Assim como as metas, uma tarefa também possui uma descrição e uma categoria.
- Status da Tarefa: O usuário pode marcar as tarefas como executadas, parcialmente executadas ou adiadas.
- Destaque por Categoria: Tarefas e metas podem ser destacadas por categoria, como por exemplo, exibindo itens da mesma categoria com a mesma cor para facilitar a visualização.
- O sistema permite a criação de lembretes semanais para atividades recorrentes, tais como:
- Ligações importantes.
- Reuniões.
- Compras.
- Geração de Relatórios: O usuário pode gerar relatórios de desempenho semanais, mensais ou anuais.
- Análise de Desempenho: Os relatórios incluem:
- Quantidade e porcentagem de metas cumpridas.
- Quantidade e porcentagem de tarefas executadas.
- Destaque para as semanas e os meses mais produtivos.
- Identificação dos turnos do dia mais produtivos.
- As categorias de tarefas e metas mais realizadas.
- Persistência de Dados: Todos os dados do usuário, como metas e tarefas, são armazenados de maneira persistente, seja em arquivos ou em um banco de dados.
|
Rust |
Rocket |
Yew |
SeaORM |
PostgreSQL |
Docker |
- Backend: Rust + Rocket (Web Framework)
- Frontend: Rust + Yew (WebAssembly Framework)
- ORM: SeaORM (Migrations e Query Builder)
- Banco de Dados: PostgreSQL 16
- Containerização: Docker + Docker Compose
- Admin DB: Adminer (Interface web para PostgreSQL)
- Projeto acadêmico desenvolvido para a disciplina de Paradigmas de Linguagens de Programação.
- Professor: Dimas Cassimiro do Nascimento Filho.
- Instituição: Universidade Federal do Agreste de Pernambuco.
Concluído ✅