Plataforma oficial do AgroHub - Hub de Inovação e Fomento da Universidade de Rio Verde (UniRV), destinada a promover o ecossistema de inovação através do gerenciamento de editais de fomento, incubação de startups e desenvolvimento tecnológico.
Status do Projeto: ✅ Produção Ready - Otimizado, seguro e pronto para deploy
O AgroHub é o Hub de Inovação e Fomento da Universidade de Rio Verde (UniRV), composto por dois ambientes principais:
-
YPETEC - Incubadora de startups da UniRV, voltada para o desenvolvimento e aceleração de novos negócios inovadores, especialmente no agronegócio e tecnologias relacionadas.
-
InovaLab - Ambiente de desenvolvimento tecnológico equipado com laboratório de software, impressoras 3D e outras ferramentas para prototipagem e desenvolvimento de soluções tecnológicas.
- Visão Geral
- Stack Tecnológica
- Pré-requisitos
- Instalação e Setup
- Configuração
- Estrutura do Projeto
- Funcionalidades
- Banco de Dados
- APIs e URLs
- Management Commands
- Desenvolvimento
- Testes
- Deploy
- Docker
- Performance e Otimização
- Segurança
- Troubleshooting
- Contribuindo
- Licença e Autores
O AgroHub é uma plataforma web desenvolvida para apresentar e gerenciar o ecossistema de inovação da UniRV. O sistema oferece:
- Gerenciamento de Editais: Divulgação e busca de oportunidades de fomento para startups e projetos de inovação
- Vitrine de Startups: Showcase das startups incubadas na YPETEC
- Ambientes de Inovação: Apresentação da YPETEC (incubadora) e do InovaLab (laboratório de desenvolvimento)
- 🎨 Interface Moderna: Design responsivo com Tailwind CSS v4
- 🔍 Busca Avançada: Sistema de busca full-text com PostgreSQL
- 📊 Dashboard Completo: Painel administrativo com estatísticas e gerenciamento
- 🔒 Segurança Robusta: Proteção XSS, CSRF, rate limiting e sanitização de dados
- ⚡ Performance Otimizada: Cache, queries otimizadas, minificação de assets
- 📱 Responsivo: Interface adaptável para desktop, tablet e mobile
- 🔐 Auditoria Completa: Histórico de alterações em todos os editais
- 🚀 Deploy Fácil: Configuração Docker pronta para produção
| Tecnologia | Versão | Finalidade |
|---|---|---|
| Python | 3.12+ | Linguagem principal |
| Django | >=5.2.8 | Framework web |
| PostgreSQL | 16+ | Banco de dados (todos os ambientes) |
| Redis | 7+ | Cache (todos os ambientes) |
| Tecnologia | Versão | Finalidade |
|---|---|---|
| Tailwind CSS | 4.1.16 | Framework CSS utilitário |
| PostCSS | 8.5.6 | Processamento de CSS |
| JavaScript (Vanilla) | ES6+ | Interatividade e animações |
| Terser | 5.36.0 | Minificação de JavaScript |
| Tecnologia | Versão | Finalidade |
|---|---|---|
| Gunicorn | >=23.0.0 | Servidor WSGI (produção) |
| WhiteNoise | >=6.11.0 | Servir arquivos estáticos |
| Docker | Latest | Containerização |
| Node.js | 20 LTS | Build de assets frontend |
| Nginx | Latest | Reverse proxy (opcional) |
- django-simple-history (>=3.11.0): Auditoria e histórico de alterações
- django-redis (>=6.0.0): Backend de cache Redis
- django-tailwind (>=3.8.0): Integração Tailwind CSS
- django-widget-tweaks (>=1.5.1): Customização de formulários
- bleach (>=6.3.0): Sanitização HTML (prevenção XSS)
- Pillow (>=11.0.0): Processamento de imagens
- psycopg2-binary (>=2.9.10): Driver PostgreSQL
- django-browser-reload (>=1.21.0): Auto-reload em desenvolvimento
- pip-audit (>=2.9.0): Auditoria de segurança de dependências
- @lhci/cli (^0.12.0): Lighthouse CI para auditorias de performance
- Python 3.12 ou superior
- pip (gerenciador de pacotes Python)
- Node.js 18+ e npm (para compilar Tailwind CSS)
- Git para versionamento
- PostgreSQL 16+ (todos os ambientes)
- Redis 7+ (todos os ambientes)
- Docker e Docker Compose (para containerização)
- Nginx (para reverse proxy)
- Certbot (para SSL/HTTPS)
# Verificar Python
python --version # Deve ser 3.12 ou superior
# Verificar pip
pip --version
# Verificar Node.js
node --version # Deve ser 18 ou superior
# Verificar npm
npm --version
# Verificar Git
git --versiongit clone <repository-url>
cd AgroHubWindows:
python -m venv .venv
.venv\Scripts\activateLinux/Mac:
python3 -m venv .venv
source .venv/bin/activateVerificar ativação:
O prompt deve mostrar (.venv) no início da linha.
pip install --upgrade pip
pip install -r requirements.txtcd theme/static_src
npm ci
cd ../..Alternativa usando django-tailwind:
python manage.py tailwind installcd theme/static_src
npm run build
cd ../..Isso irá:
- Limpar arquivos antigos de build
- Compilar Tailwind CSS para produção (minificado)
- Minificar arquivos JavaScript
Copie o arquivo de exemplo e configure:
# Windows
copy .env.production.example .env
# Linux/Mac
cp .env.production.example .envEdite o arquivo .env com suas configurações (veja seção Configuração).
python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"Copie o resultado e adicione ao .env:
SECRET_KEY=seu-secret-key-aqui
python manage.py migratepython manage.py createsuperuserSiga as instruções para criar o primeiro usuário administrador.
# Popular editais de exemplo
python manage.py seed_editais
# Popular startups de exemplo
python manage.py seed_startupspython manage.py collectstatic --noinputpython manage.py runserverAcesse: http://127.0.0.1:8000/
O projeto usa variáveis de ambiente para configuração. Todas as variáveis são opcionais exceto em produção (onde SECRET_KEY e ALLOWED_HOSTS são obrigatórias).
| Variável | Descrição | Exemplo |
|---|---|---|
SECRET_KEY |
Chave secreta do Django (obrigatória em produção) | Gerar com comando acima |
DJANGO_DEBUG |
Modo debug (False em produção) |
False |
ALLOWED_HOSTS |
Domínios permitidos (separados por vírgula) | example.com,www.example.com |
| Variável | Descrição | Padrão |
|---|---|---|
DB_NAME |
Nome do banco de dados | Obrigatório |
DB_USER |
Usuário do banco | postgres |
DB_PASSWORD |
Senha do banco | Obrigatório |
DB_HOST |
Host do banco | localhost |
DB_PORT |
Porta do banco | 5432 |
Nota: PostgreSQL é obrigatório para todos os ambientes. Use Docker para desenvolvimento local.
| Variável | Descrição | Padrão |
|---|---|---|
REDIS_HOST |
Host do Redis | Obrigatório |
REDIS_PORT |
Porta do Redis | 6379 |
Nota: Redis é obrigatório para todos os ambientes. Use Docker para desenvolvimento local.
| Variável | Descrição | Padrão |
|---|---|---|
EMAIL_BACKEND |
Backend de email | console (dev) |
EMAIL_HOST |
Servidor SMTP | localhost |
EMAIL_PORT |
Porta SMTP | 587 |
EMAIL_USE_TLS |
Usar TLS | True |
EMAIL_HOST_USER |
Usuário SMTP | - |
EMAIL_HOST_PASSWORD |
Senha SMTP | - |
DEFAULT_FROM_EMAIL |
Email remetente | noreply@agrohub.unirv.edu.br |
| Variável | Descrição | Padrão |
|---|---|---|
SITE_URL |
URL base do site | http://localhost:8000 |
DJANGO_LOG_LEVEL |
Nível de log | INFO |
DJANGO_LOG_TO_FILE |
Habilitar logs em arquivo | False |
DJANGO_LOG_DIR |
Diretório de logs | ./logs |
COOKIE_DOMAIN |
Domínio dos cookies | - |
WHITENOISE_MAX_AGE |
Cache de arquivos estáticos (segundos) | 3600 (dev) |
CDN_BASE_URL |
URL base do CDN para imagens | - |
Principais configurações em UniRV_Django/settings.py:
- Idioma: Português (pt-BR)
- Fuso Horário: America/Sao_Paulo
- Formato de Data: DD/MM/YYYY
- Editais por página: 12 itens
- Configurável via
EDITAIS_PER_PAGEem settings.py
- Desenvolvimento: LocMemCache (memória local)
- Produção: Redis (se configurado)
- TTL padrão: 5 minutos (300 segundos)
- Configurável via
EDITAIS_CACHE_TTL
- Desenvolvimento: Console
- Produção: Arquivos rotativos (opcional)
- Logs separados: Aplicação, segurança, performance
- Tamanho máximo: 10MB por arquivo
- Backup count: 5 arquivos
As configurações de segurança são habilitadas automaticamente quando DEBUG=False:
- SSL/HTTPS obrigatório
- Headers de segurança (HSTS, X-Frame-Options, etc.)
- Cookies seguros (HttpOnly, Secure, SameSite)
- CSRF protection
- XSS protection (sanitização HTML)
AgroHub/
├── editais/ # App principal de editais
│ ├── __init__.py
│ ├── apps.py # Configuração do app
│ ├── admin.py # Configuração do Django Admin
│ ├── models.py # Modelos de dados
│ ├── views.py # Views principais
│ ├── views/ # Views organizadas por módulo
│ │ ├── __init__.py
│ │ ├── public.py # Views públicas
│ │ ├── dashboard.py # Views do dashboard
│ │ ├── editais_crud.py # CRUD de editais
│ │ └── mixins.py # Mixins reutilizáveis
│ ├── forms.py # Formulários
│ ├── urls.py # URLs do app
│ ├── utils.py # Funções utilitárias
│ ├── services.py # Lógica de negócio
│ ├── decorators.py # Decoradores customizados
│ ├── exceptions.py # Exceções customizadas
│ ├── constants.py # Constantes do app
│ ├── constants/ # Módulos de constantes
│ │ ├── __init__.py
│ │ ├── cache.py # Constantes de cache
│ │ ├── limits.py # Limites e rate limiting
│ │ └── status.py # Status de editais
│ ├── cache_utils.py # Utilitários de cache
│ ├── templatetags/ # Template tags customizados
│ │ ├── __init__.py
│ │ ├── editais_filters.py # Filtros para templates
│ │ └── image_helpers.py # Helpers de imagem
│ ├── management/ # Management commands
│ │ └── commands/
│ │ ├── seed_editais.py # Popular editais de exemplo
│ │ ├── seed_startups.py # Popular startups de exemplo
│ │ ├── update_edital_status.py # Atualizar status automaticamente
│ │ ├── run_lighthouse.py # Auditorias Lighthouse
│ │ ├── run_lighthouse_audit.py
│ │ ├── get_auth_cookie.py # Utilitário de autenticação
│ │ └── populate_from_pdfs.py # Popular de PDFs
│ ├── migrations/ # Migrações do banco de dados
│ │ ├── 0001_initial.py
│ │ └── ... # Outras migrações
│ └── tests/ # Testes
│ ├── __init__.py
│ ├── test_admin.py # Testes do admin
│ ├── test_permissions.py # Testes de permissões
│ ├── test_public_views.py # Testes de views públicas
│ ├── test_dashboard_views.py # Testes do dashboard
│ ├── test_security.py # Testes de segurança
│ ├── test_cache.py # Testes de cache
│ ├── test_forms.py # Testes de formulários
│ └── ... # Outros testes
│
├── UniRV_Django/ # Configurações do projeto Django
│ ├── __init__.py
│ ├── settings.py # Configurações principais
│ ├── urls.py # URLs raiz do projeto
│ ├── wsgi.py # WSGI para produção
│ └── asgi.py # ASGI (não usado atualmente)
│
├── theme/ # App do tema Tailwind
│ ├── __init__.py
│ ├── apps.py
│ ├── static/ # Assets estáticos compilados
│ │ └── fonts/ # Fontes
│ └── static_src/ # Código fonte dos assets
│ ├── package.json # Dependências npm
│ ├── package-lock.json # Lock de dependências
│ ├── tailwind.config.js # Configuração Tailwind
│ ├── postcss.config.js # Configuração PostCSS
│ └── src/
│ ├── styles.css # CSS principal
│ └── fonts/ # Fontes fonte
│
├── templates/ # Templates HTML
│ ├── base.html # Template base
│ ├── home.html # Página inicial
│ ├── 403.html # Erro 403
│ ├── 404.html # Erro 404
│ ├── 500.html # Erro 500
│ ├── components/ # Componentes reutilizáveis
│ │ ├── button.html
│ │ ├── edital_skeleton_card.html
│ │ └── empty_state.html
│ ├── editais/ # Templates de editais
│ │ ├── index.html # Listagem
│ │ ├── detail.html # Detalhes
│ │ ├── create.html # Criar
│ │ ├── update.html # Editar
│ │ ├── delete.html # Excluir
│ │ ├── dashboard.html # Dashboard
│ │ └── index_partial.html # Partial para AJAX
│ ├── dashboard/ # Templates do dashboard
│ │ ├── base.html # Base do dashboard
│ │ ├── home.html # Home do dashboard
│ │ ├── editais.html # Lista de editais
│ │ ├── novo_edital.html # Novo edital
│ │ ├── startups.html # Lista de startups incubadas
│ │ ├── startup_update.html # Atualizar startup
│ │ ├── submeter_startup.html # Cadastrar startup
│ │ └── usuarios.html # Usuários
│ ├── registration/ # Templates de autenticação
│ │ ├── login.html
│ │ ├── register.html
│ │ ├── password_reset_*.html # Recuperação de senha
│ │ └── password_reset_subject.txt
│ ├── startups/ # Templates de startups
│ │ ├── index.html
│ │ └── detail.html
│ ├── ambientes_inovacao/ # Ambientes de inovação
│ │ └── index.html
│ └── admin/ # Templates do admin
│ └── login.html
│
├── static/ # Arquivos estáticos não compilados
│ ├── css/ # CSS adicional
│ │ ├── animations.css
│ │ ├── detail.css
│ │ └── print.css
│ ├── js/ # JavaScript
│ │ ├── main.js # JavaScript principal
│ │ ├── animations.js # Animações
│ │ ├── detail.js # Detalhes
│ │ └── *.min.js # Versões minificadas
│ ├── img/ # Imagens
│ │ ├── hero/ # Imagens hero
│ │ ├── favicon.svg
│ │ ├── logo-agrohub.svg
│ │ └── logo_inovalab.svg
│ └── fonts/ # Fontes (Montserrat)
│ ├── Montserrat-Regular.ttf
│ └── Montserrat-SemiBold.ttf
│
├── staticfiles/ # Coletados pelo collectstatic (gerado, não versionado)
│ └── ...
│
├── media/ # Arquivos de mídia (uploaded) (gerado)
│ └── ... # Uploads de usuários
│
├── logs/ # Logs da aplicação (gerado)
│ ├── django.log # Log principal
│ ├── security.log # Logs de segurança
│ └── performance.log # Logs de performance
│
├── scripts/ # Scripts utilitários
│ ├── generate_hero_images.py # Gerar imagens hero
│ └── track_lighthouse_scores.py # Rastreamento de scores
│
├── manage.py # Utilitário de gerenciamento Django
├── requirements.txt # Dependências Python
├── Dockerfile # Configuração Docker
├── docker-entrypoint.sh # Script de entrada Docker
├── .dockerignore # Arquivos ignorados pelo Docker
├── .gitignore # Arquivos ignorados pelo Git
├── .env.production.example # Exemplo de variáveis de ambiente
└── README.md # Este arquivo
App principal do Django contendo toda a lógica de negócio relacionada a editais e startups.
Configurações do projeto Django, incluindo settings, URLs principais e configurações WSGI.
App Django para o tema Tailwind CSS. Contém o código fonte dos assets frontend e a configuração de build.
Templates HTML organizados por funcionalidade. Usa herança de templates com base.html como template principal.
Arquivos estáticos não compilados (CSS adicional, JavaScript, imagens, fontes).
Diretório gerado pelo collectstatic contendo todos os arquivos estáticos coletados e processados.
- Criação: Criar novos editais com todos os campos necessários
- Edição: Editar editais existentes com validação
- Exclusão: Excluir editais (soft delete recomendado)
- Visualização: Visualizar editais com informações completas
- Status Automático: Atualização automática de status baseado em datas
- Busca Full-Text: Usa PostgreSQL full-text search quando disponível
- Busca por Múltiplos Campos: Busca em título, entidade, número, análise, etc.
- Ranking de Resultados: Resultados ordenados por relevância
- Sugestões de Busca: Sugestões usando trigram similarity (PostgreSQL)
- Full-Text Search: Busca avançada com PostgreSQL full-text search
- Home: Estatísticas e visão geral
- Editais: Gerenciamento completo de editais
- Startups: Gerenciamento de startups incubadas
- Usuários: Gerenciamento de usuários
- Relatórios: Estatísticas e relatórios (futuro)
- Registro de Usuários: Cadastro com validação de email
- Login/Logout: Autenticação segura
- Recuperação de Senha: Reset de senha via email
- Permissões: Controle de acesso baseado em roles (
is_staff)
- Home: Landing page com hero, estatísticas e features
- Listagem de Editais: Página com busca, filtros e paginação
- Detalhes do Edital: Página completa com todas as informações
- Vitrine de Startups: Listagem pública de startups incubadas
- Ambientes de Inovação: Informações sobre ambientes
- Passo a Passo: Guia para participação em editais
- Histórico de Alterações: Todas as mudanças em editais são rastreadas
- Rastreamento de Usuário: Registro de quem fez cada alteração
- Timestamps: Datas de criação e atualização
- Sanitização automática com
bleachem todos os campos HTML - Configuração de tags e atributos permitidos
- Proteção no Django Admin e nas views web
- Limitação de taxa de requisições por IP
- Proteção contra abuso de APIs e formulários
- Configurável por rota
- HSTS (HTTP Strict Transport Security)
- X-Frame-Options: DENY
- X-Content-Type-Options: nosniff
- Referrer-Policy
- Content-Security-Policy (futuro)
- Operações administrativas restritas a
is_staff - Editais em draft ocultos para não-autenticados
- Validação de permissões em todas as views
- Cache de Páginas: Cache de páginas de listagem
- Cache de Consultas: Cache de resultados de busca
- Cache de Sugestões: Cache de sugestões de busca
- TTL Configurável: Tempos de cache configuráveis
- select_related: Para relações ForeignKey
- prefetch_related: Para relações ManyToMany e Reverse ForeignKey
- QuerySets Customizados: Métodos otimizados para queries comuns
- CSS Minificado: Tailwind CSS compilado e minificado
- JavaScript Minificado: Terser para minificação JS
- Layout adaptável para mobile, tablet e desktop
- Breakpoints do Tailwind CSS
- Navegação otimizada para mobile
- Animações suaves para transições
- Loading states e skeletons
- Feedback visual para ações do usuário
- Suporte a leitores de tela
- Navegação por teclado
- Contraste adequado
- Labels e ARIA attributes
O AgroHub possui um painel administrativo completo para gerenciar editais e startups.
- Acesso: Faça login e navegue para
/dashboard/home/ - Dashboard: Visualize estatísticas gerais de editais e startups
-
Criar Edital:
- No Dashboard, clique em "Novo Edital" ou navegue para
/dashboard/editais/novo/ - Preencha o status inicial (Ex: "Rascunho")
- Adicione datas de abertura e encerramento
- No Dashboard, clique em "Novo Edital" ou navegue para
-
Cronograma:
- Após criar o edital, você pode adicionar etapas do cronograma
- Importante para manter os candidatos informados
-
Submissão:
- Usuários podem submeter startups via
/dashboard/startups/submeter/ - É necessário preencher nome, descrição, categoria e logo
- Usuários podem submeter startups via
-
Aprovação:
- Administradores revisam as submissões no Dashboard
- Status pode ser alterado para "Incubada" ou "Graduada"
Modelo principal representando um edital de fomento.
Campos Principais:
titulo: Título do editalslug: URL amigável (único)status: Status (draft, programado, aberto, fechado)numero_edital: Número do editalentidade_principal: Entidade responsávelurl: URL do edital originaldata_abertura: Data de aberturadata_encerramento: Data de encerramentoanalise: Análise do edital (HTML)objetivo: Objetivo (HTML)etapas: Etapas (HTML)recursos: Recursos disponíveis (HTML)- Campos de metadados:
created_by,updated_by,created_at,updated_at
Relações:
valores: Relacionamento 1:N com EditalValorcronogramas: Relacionamento 1:N com Cronogramacreated_by: ForeignKey para Userupdated_by: ForeignKey para User
Valores financeiros do edital.
Campos:
edital: ForeignKey para Editaltipo: Tipo de valor (total, por projeto, etc.)valor_total: Valor totalmoeda: Moeda (BRL, USD, etc.)
Cronograma de atividades do edital.
Campos:
edital: ForeignKey para Editalatividade: Nome da atividadedata: Data da atividadeobservacoes: Observações adicionais
Startup incubada no AgroHub.
Campos:
name: Nome da startupslug: URL amigávelcategory: Categoria da startupdescription: Descrição (HTML)logo: Logo da startupstatus: Fase de maturidade (Ideação, MVP, Escala, Suspensa)contato: Informações de contatosubmitted_on: Data de entradaproponente: ForeignKey para User
- Índices GIN: Para busca full-text
- Índices Trigram: Para sugestões de busca (pg_trgm)
- Índices B-tree: Para campos frequentemente consultados (status, data_atualizacao)
0018_enable_pg_trgm_extension.py: Habilita extensão pg_trgm0019_add_trigram_indexes.py: Adiciona índices trigram0020_add_fulltext_search_index.py: Adiciona índice full-text search
# PostgreSQL
pg_dump -U usuario -d nome_banco > backup.sql
# PostgreSQL
pg_dump -U agrohub_user agrohub_dev > backup_$(date +%Y%m%d).sql# PostgreSQL
psql -U usuario -d nome_banco < backup.sql
# PostgreSQL
psql -U agrohub_user agrohub_dev < backup.sql| URL | Nome | Descrição |
|---|---|---|
/ |
home |
Página inicial |
/editais/ |
editais_index |
Listagem de editais |
/edital/<slug>/ |
edital_detail_slug |
Detalhes do edital (por slug) |
/edital/<int:pk>/ |
edital_detail |
Detalhes do edital (por ID, redireciona) |
/startups/ |
startups_showcase |
Vitrine de startups |
/startup/<slug>/ |
startup_detail_slug |
Detalhes da startup |
/projetos-aprovados/ |
(redirect) | Redireciona para /startups/ |
/ambientes-inovacao/ |
ambientes_inovacao |
Ambientes de inovação |
/register/ |
register |
Registro de usuário |
/login/ |
login |
Login |
/logout/ |
logout |
Logout |
| URL | Nome | Descrição |
|---|---|---|
/password-reset/ |
password_reset |
Solicitar reset de senha |
/password-reset/done/ |
password_reset_done |
Confirmação de solicitação |
/password-reset-confirm/<uidb64>/<token>/ |
password_reset_confirm |
Confirmar reset |
/password-reset-complete/ |
password_reset_complete |
Reset completo |
| URL | Nome | Descrição | Permissão |
|---|---|---|---|
/dashboard/home/ |
dashboard_home |
Home do dashboard | Autenticado |
/dashboard/editais/ |
dashboard_editais |
Lista de editais | Autenticado |
/dashboard/editais/novo/ |
dashboard_novo_edital |
Novo edital | is_staff |
/dashboard/startups/ |
dashboard_startups |
Startups incubadas | Autenticado |
/dashboard/startups/submeter/ |
dashboard_submeter_startup |
Cadastrar startup | Autenticado |
/dashboard/startups/<pk>/editar/ |
dashboard_startup_update |
Editar startup | Autenticado |
/dashboard/usuarios/ |
dashboard_usuarios |
Usuários | is_staff |
| URL | Nome | Descrição |
|---|---|---|
/cadastrar/ |
edital_create |
Criar edital |
/edital/<pk>/editar/ |
edital_update |
Editar edital |
/edital/<pk>/excluir/ |
edital_delete |
Excluir edital |
/admin/ |
- | Django Admin |
| URL | Nome | Descrição |
|---|---|---|
/health/ |
health_check |
Health check da aplicação |
Popula o banco de dados com editais de exemplo.
python manage.py seed_editaisOpções:
--count N: Número de editais a criar (padrão: 10)
Popula o banco de dados com startups de exemplo.
python manage.py seed_startupsOpções:
--count N: Número de startups a criar (padrão: 5)
Atualiza automaticamente o status dos editais baseado nas datas.
python manage.py update_edital_statusOpções:
--dry-run: Executa sem fazer alterações (apenas mostra)--verbose: Mostra informações detalhadas
Uso em Produção: Configure no cron para executar diariamente:
# Crontab (Linux)
0 0 * * * cd /path/to/AgroHub && /path/to/venv/bin/python manage.py update_edital_statusExecuta auditorias Lighthouse CI.
python manage.py run_lighthouseOpções:
--all-pages: Auditar todas as páginas (incluindo protegidas)--url URL: URL específica para auditar (pode repetir)--output-dir DIR: Diretório de saída (padrão:./lighthouse_reports)--thresholds KEY=VALUE: Thresholds customizados--port PORT: Porta do servidor (padrão: 7000)--no-server: Não iniciar servidor (já está rodando)--no-auth: Pular autenticação
- Crie um arquivo em
editais/management/commands/ - Estenda
BaseCommanddo Django - Implemente o método
handle()
Exemplo:
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help = 'Descrição do comando'
def add_arguments(self, parser):
parser.add_argument('--option', type=str, help='Descrição')
def handle(self, *args, **options):
# Lógica do comando
pass- Criar branch:
git checkout -b feature/nova-funcionalidade - Fazer alterações: Desenvolver a funcionalidade
- Rodar testes:
python manage.py test - Verificar lint: Verificar código
- Commit:
git commit -m "Adiciona nova funcionalidade" - Push:
git push origin feature/nova-funcionalidade - Pull Request: Abrir PR para revisão
cd theme/static_src
npm run devIsso compila Tailwind CSS em modo watch, recarregando automaticamente ao salvar.
cd theme/static_src
npm run buildIsso:
- Limpa arquivos antigos
- Compila Tailwind CSS minificado
- Minifica JavaScript
- Copia Font Awesome e GSAP para
static/vendor/(uso local, sem CDN)
theme/static_src/
├── src/styles.css # CSS fonte
└── (build) → ../../static/css/dist/styles.css # CSS compilado
static/js/
├── main.js # JS fonte
└── main.min.js # JS minificado (build)
static/js/
├── animations.js # JS fonte
└── animations.min.js # JS minificado (build)
Em desenvolvimento (DEBUG=True), o django-browser-reload está habilitado para auto-reload do navegador ao salvar arquivos Python ou templates.
URL: http://localhost:8000/__reload__/
Para instalar:
pip install django-debug-toolbarAdicionar ao INSTALLED_APPS e MIDDLEWARE em desenvolvimento.
Os logs são exibidos no console. Para logs mais detalhados:
export DJANGO_LOG_LEVEL=DEBUG
python manage.py runserverpython manage.py test editais# Teste específico
python manage.py test editais.tests.test_public_views.EditaisIndexTest
# Módulo de testes
python manage.py test editais.tests.test_permissions
# Arquivo de testes
python manage.py test editais.tests.test_admin# Instalar coverage
pip install coverage
# Executar testes com cobertura
coverage run --source='editais' --omit='*/migrations/*' manage.py test editais
# Relatório no terminal
coverage report
# Relatório HTML
coverage html
# Abrir htmlcov/index.html no navegadoreditais/tests/
├── test_admin.py # Testes do Django Admin
├── test_permissions.py # Testes de permissões
├── test_public_views.py # Testes de views públicas
├── test_dashboard_views.py # Testes do dashboard
├── test_security.py # Testes de segurança
├── test_cache.py # Testes de cache
├── test_forms.py # Testes de formulários
├── test_integration.py # Testes de integração
└── ...
Status: 69% (Meta: 85%)
Testes Implementados:
- ✅ CRUD de editais (7 testes)
- ✅ Busca e filtros (6 testes)
- ✅ Detalhes e redirecionamento (4 testes)
- ✅ Modelos (slug, validação, status) (5 testes)
- ✅ Formulários (6 testes)
- ✅ Permissões (12 testes)
- ✅ Management commands (8 testes)
- ✅ Admin interface (15 testes)
Áreas que Precisam de Mais Testes:
⚠️ Viewadmin_dashboard()⚠️ Métodosave_model()no Admin⚠️ Edge cases em views e models
Para testar performance de queries:
python manage.py test editais.tests.test_performance- Todas as variáveis de ambiente configuradas
-
DEBUG=Falseem produção -
SECRET_KEYúnica e segura -
ALLOWED_HOSTSconfigurado - Banco de dados PostgreSQL configurado
- Redis configurado (recomendado)
- Email SMTP configurado
- SSL/HTTPS configurado
- Arquivos estáticos coletados
- Migrações aplicadas
- Superusuário criado
- Logs configurados
- Backup do banco de dados configurado
-
Coletar arquivos estáticos:
python manage.py collectstatic --noinput
-
Aplicar migrações:
python manage.py migrate
-
Criar superusuário:
python manage.py createsuperuser
-
Verificar configurações:
python manage.py check --deploy
docker build -t agrohub:latest .docker run -d \
--name agrohub \
-p 8000:8000 \
-e SECRET_KEY="sua-secret-key" \
-e DJANGO_DEBUG=False \
-e ALLOWED_HOSTS="seu-dominio.com" \
-e DB_NAME="nome_banco" \
-e DB_USER="usuario" \
-e DB_PASSWORD="senha" \
-e DB_HOST="host" \
agrohub:latestCrie um arquivo docker-compose.yml:
version: '3.8'
services:
web:
build: .
ports:
- "8000:8000"
environment:
- SECRET_KEY=${SECRET_KEY}
- DJANGO_DEBUG=False
- ALLOWED_HOSTS=${ALLOWED_HOSTS}
- DB_NAME=${DB_NAME}
- DB_USER=${DB_USER}
- DB_PASSWORD=${DB_PASSWORD}
- DB_HOST=db
- REDIS_HOST=redis
depends_on:
- db
- redis
volumes:
- ./media:/app/media
- ./staticfiles:/app/staticfiles
db:
image: postgres:15
environment:
- POSTGRES_DB=${DB_NAME}
- POSTGRES_USER=${DB_USER}
- POSTGRES_PASSWORD=${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
volumes:
postgres_data:
redis_data:Execute:
docker-compose up -dsudo apt update
sudo apt install -y python3.12 python3-pip python3-venv nginx redis-server postgresql postgresql-contribsudo -u postgres psql
# No PostgreSQL:
CREATE DATABASE nome_banco;
CREATE USER usuario WITH PASSWORD 'senha';
ALTER ROLE usuario SET client_encoding TO 'utf8';
ALTER ROLE usuario SET default_transaction_isolation TO 'read committed';
ALTER ROLE usuario SET timezone TO 'America/Sao_Paulo';
GRANT ALL PRIVILEGES ON DATABASE nome_banco TO usuario;
\q# Clonar repositório
cd /var/www
sudo git clone <repository-url> agrohub
cd agrohub
# Criar ambiente virtual
sudo python3.12 -m venv .venv
sudo chown -R $USER:$USER .
# Ativar e instalar dependências
source .venv/bin/activate
pip install -r requirements.txt
# Configurar variáveis de ambiente
cp .env.production.example .env
nano .env # Editar configurações
# Coletar estáticos e migrar
python manage.py collectstatic --noinput
python manage.py migrate
python manage.py createsuperuserCriar arquivo /etc/systemd/system/agrohub.service:
[Unit]
Description=AgroHub Gunicorn daemon
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/agrohub
ExecStart=/var/www/agrohub/.venv/bin/gunicorn \
--bind 127.0.0.1:8000 \
--workers 3 \
--timeout 120 \
UniRV_Django.wsgi:application
Restart=always
[Install]
WantedBy=multi-user.targetAtivar serviço:
sudo systemctl daemon-reload
sudo systemctl enable agrohub
sudo systemctl start agrohub
sudo systemctl status agrohubCriar arquivo /etc/nginx/sites-available/agrohub:
server {
listen 80;
server_name seu-dominio.com www.seu-dominio.com;
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;
}
location /static/ {
alias /var/www/agrohub/staticfiles/;
expires 1y;
add_header Cache-Control "public, immutable";
}
location /media/ {
alias /var/www/agrohub/media/;
expires 1y;
add_header Cache-Control "public";
}
}Ativar site:
sudo ln -s /etc/nginx/sites-available/agrohub /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginxsudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d seu-dominio.com -d www.seu-dominio.comO Certbot irá configurar SSL automaticamente e renovação automática.
# Instalar Heroku CLI
# Fazer login
heroku login
# Criar app
heroku create seu-app-name
# Configurar variáveis
heroku config:set SECRET_KEY="sua-secret-key"
heroku config:set DJANGO_DEBUG=False
heroku config:set ALLOWED_HOSTS="seu-app-name.herokuapp.com"
# Adicionar add-ons
heroku addons:create heroku-postgresql:mini
heroku addons:create heroku-redis:mini
# Deploy
git push heroku main
# Migrar banco
heroku run python manage.py migrate
heroku run python manage.py createsuperuser- Conectar repositório GitHub
- Configurar variáveis de ambiente no painel
- Definir build command:
pip install -r requirements.txt && cd theme/static_src && npm ci && npm run build && cd ../.. && python manage.py collectstatic --noinput - Definir start command:
gunicorn UniRV_Django.wsgi:application - Deploy automático
- Conectar repositório
- Configurar variáveis de ambiente
- Adicionar serviços PostgreSQL e Redis
- Deploy automático
O Dockerfile usa multi-stage build com 3 estágios:
- node-builder: Compila assets frontend (Tailwind CSS, JavaScript)
- python-builder: Instala dependências Python e coleta arquivos estáticos
- runtime: Imagem final otimizada apenas com runtime
docker build -t agrohub:latest .docker run -d \
--name agrohub \
-p 8000:8000 \
-e SECRET_KEY="sua-secret-key" \
-e DJANGO_DEBUG=False \
-e ALLOWED_HOSTS="localhost" \
agrohub:latestPasse variáveis via -e ou use arquivo .env:
docker run -d \
--env-file .env \
-p 8000:8000 \
agrohub:latestVeja exemplo completo na seção Deploy com Docker.
O Dockerfile usa docker-entrypoint.sh que:
- Executa migrações automaticamente
- Fornece mensagens de erro claras
- Inicia o servidor Gunicorn
- Cache de páginas de listagem de editais
- TTL: 5 minutos (configurável)
- Invalidação automática ao criar/editar editais
- Cache de resultados de busca
- Cache de sugestões de busca
- Cache de estatísticas
# Cache manual
from django.core.cache import cache
cache.set('key', 'value', 300) # 5 minutos
value = cache.get('key')editais = Edital.objects.select_related('created_by', 'updated_by')editais = Edital.objects.prefetch_related('valores', 'cronogramas')# Usar métodos otimizados
editais = Edital.objects.with_related().with_prefetch().active()- Tailwind CSS compilado e minificado via PostCSS
- Minificação via Terser
- GZip compression habilitado
- Configurável via middleware
- GIN indexes: Para busca full-text
- Trigram indexes: Para sugestões de busca
- B-tree indexes: Para campos frequentemente consultados
- Query time logging (quando
DEBUG=True) - Logs de cache hits/misses
- Logs de tempo de resposta
- Django Debug Toolbar (desenvolvimento)
- Django Silk (profiling)
- Lighthouse CI (auditorias automatizadas)
- Biblioteca:
bleach - Aplicação: Todos os campos HTML em editais
- Configuração: Tags e atributos permitidos definidos
# Em utils.py
ALLOWED_TAGS = ['p', 'br', 'strong', 'em', ...]
ALLOWED_ATTRIBUTES = {'a': ['href', 'title'], ...}- Implementação: Decorator customizado usando cache do Django (
editais/decorators.py) - Aplicação: Views de login, criação de editais, registro
- Configuração: 5 requisições por minuto por IP
- Design: Fail-open — requisições são permitidas quando o cache está indisponível
- Habilitado por padrão no Django
- Tokens CSRF em todos os formulários
- Verificação automática em requisições POST
- Django ORM previne SQL injection automaticamente
- Queries parametrizadas
- Nunca usar strings SQL diretas
Habilitados automaticamente quando DEBUG=False:
- HSTS: HTTP Strict Transport Security (1 ano)
- X-Frame-Options: DENY
- X-Content-Type-Options: nosniff
- Referrer-Policy: strict-origin-when-cross-origin
- X-XSS-Protection: Enabled
- HttpOnly: Impede acesso JavaScript
- Secure: Apenas HTTPS (produção)
- SameSite: Lax (proteção CSRF)
- Expiração: 1 hora ou ao fechar navegador
- Senhas hasheadas com algoritmo seguro (PBKDF2)
- Validação de senha forte
- Proteção contra brute force (rate limiting)
- Operações administrativas restritas a
is_staff - Editais em draft ocultos para não-autenticados
- Validação de permissões em todas as views
Antes de deploy em produção:
-
DEBUG=False -
SECRET_KEYúnica e segura -
ALLOWED_HOSTSconfigurado - HTTPS habilitado
- Senhas fortes para banco de dados
- Firewall configurado
- Backup do banco de dados
- Logs monitorados
- Dependências atualizadas (
pip-audit) - Usuários com permissões mínimas necessárias
pip-audit -r requirements.txtcd theme/static_src
npm audit# Verificar dependências desatualizadas
pip list --outdated
# Atualizar (cuidado com breaking changes)
pip install --upgrade package-nameSolução:
# Verificar se ambiente virtual está ativado
which python # Deve apontar para .venv
# Reinstalar dependências
pip install -r requirements.txtSolução:
# Verificar se templates estão no diretório correto
# Verificar INSTALLED_APPS em settings.py
# Verificar TEMPLATES['DIRS'] em settings.pySolução:
# Coletar arquivos estáticos
python manage.py collectstatic --noinput
# Verificar STATIC_ROOT e STATIC_URL em settings.py
# Verificar se WhiteNoise está no MIDDLEWARESolução:
# Verificar estado das migrações
python manage.py showmigrations
# Fazer fake migration (cuidado!)
python manage.py migrate --fake
# Ou resetar migrações (desenvolvimento apenas)
# Deletar arquivos de migração (exceto __init__.py)
# python manage.py makemigrations
# python manage.py migrateSolução:
# Verificar se PostgreSQL está rodando
sudo systemctl status postgresql
# Verificar credenciais no .env
# Verificar se banco existe
psql -U usuario -d nome_bancoSolução:
# Limpar node_modules e reinstalar
cd theme/static_src
rm -rf node_modules package-lock.json
npm ci
npm run buildSolução:
# Limpar cache
python manage.py shell
>>> from django.core.cache import cache
>>> cache.clear()
# Verificar configuração de cache em settings.py
# Verificar se Redis está rodando (se usando)Solução:
# Verificar logs
tail -f logs/django.log
# Verificar variáveis de ambiente
# Verificar DEBUG=False
# Verificar ALLOWED_HOSTS
# Verificar permissões de arquivos- Desenvolvimento: Console
- Produção:
logs/(seDJANGO_LOG_TO_FILE=true)logs/django.log: Log principallogs/security.log: Logs de segurançalogs/performance.log: Logs de performance
# Últimas 100 linhas
tail -n 100 logs/django.log
# Seguir logs em tempo real
tail -f logs/django.log
# Filtrar erros
grep ERROR logs/django.logNunca deixe DEBUG=True em produção!
Para debug em desenvolvimento:
export DJANGO_DEBUG=True
export DJANGO_LOG_LEVEL=DEBUG
python manage.py runserverPara problemas não resolvidos:
- Verificar logs
- Verificar documentação do Django
- Abrir issue no repositório
- Contatar equipe de desenvolvimento
Windows:
python -m venv .venv
.venv\Scripts\activateLinux/Mac:
python3 -m venv .venv
source .venv/bin/activateSolução:
- Verifique se o ambiente virtual está ativado (deve mostrar
(.venv)no prompt) - Reinstale as dependências:
pip install -r requirements.txt
Solução:
cd theme/static_src
rm -rf node_modules package-lock.json
npm ci
npm run buildSolução:
- Verifique se Node.js 18+ está instalado:
node --version - Limpe o cache:
npm cache clean --force - Tente novamente:
npm ci
python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"Copie o resultado e adicione ao arquivo .env:
SECRET_KEY=sua-secret-key-aqui
- Crie o banco de dados:
sudo -u postgres psql
CREATE DATABASE nome_banco;
CREATE USER usuario WITH PASSWORD 'senha';
GRANT ALL PRIVILEGES ON DATABASE nome_banco TO usuario;- Configure no
.env:
DB_NAME=nome_banco
DB_USER=usuario
DB_PASSWORD=senha
DB_HOST=localhost
DB_PORT=5432
Solução:
- Verifique se PostgreSQL está rodando:
sudo systemctl status postgresql - Verifique credenciais no
.env - Teste a conexão:
psql -U usuario -d nome_banco
# Todos os testes
python manage.py test editais
# Teste específico
python manage.py test editais.tests.test_public_views
# Com cobertura
coverage run --source='editais' manage.py test editais
coverage report- Ative o modo debug:
export DJANGO_DEBUG=True
export DJANGO_LOG_LEVEL=DEBUG
python manage.py runserver-
Verifique os logs em
logs/django.log -
Use Django Debug Toolbar (opcional):
pip install django-debug-toolbar# Verificar configurações
python manage.py check
# Verificar para produção
python manage.py check --deploy
# Verificar migrações
python manage.py showmigrations# Aplicar todas as migrações
python manage.py migrate
# Aplicar migração específica
python manage.py migrate editais 0024
# Ver estado das migrações
python manage.py showmigrationsSolução:
- Verifique o estado:
python manage.py showmigrations - Se necessário, faça backup do banco
- Tente fazer fake migration (cuidado!):
python manage.py migrate --fake - Ou resetar migrações (apenas desenvolvimento):
- Delete arquivos de migração (exceto
__init__.py) python manage.py makemigrationspython manage.py migrate
- Delete arquivos de migração (exceto
PostgreSQL:
pg_dump -U usuario -d nome_banco > backup_$(date +%Y%m%d).sqlSolução:
# Coletar arquivos estáticos
python manage.py collectstatic --noinput
# Verificar STATIC_ROOT e STATIC_URL em settings.py
# Verificar se WhiteNoise está no MIDDLEWARESolução:
- Verifique logs:
tail -f logs/django.log - Verifique
DEBUG=Falseno.env - Verifique
ALLOWED_HOSTSconfigurado - Verifique permissões de arquivos
- Verifique variáveis de ambiente
Use Let's Encrypt com Certbot:
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d seu-dominio.com -d www.seu-dominio.comSolução:
- Verifique logs:
docker logs agrohub - Verifique variáveis de ambiente
- Verifique se as portas estão disponíveis
- Rebuild a imagem:
docker build -t agrohub:latest .
Solução:
# Limpar cache
python manage.py shell
>>> from django.core.cache import cache
>>> cache.clear()
# Verificar configuração de cache em settings.py
# Verificar se Redis está rodando (se usando)Solução:
- Use
select_related()para ForeignKey - Use
prefetch_related()para ManyToMany - Verifique índices no banco de dados
- Use Django Debug Toolbar para identificar N+1 queries
# Python dependencies
pip-audit -r requirements.txt
# Node.js dependencies
cd theme/static_src
npm audit# Verificar dependências desatualizadas
pip list --outdated
# Atualizar (cuidado com breaking changes)
pip install --upgrade package-nameSolução:
- Verifique se o template está no diretório correto
- Verifique
INSTALLED_APPSemsettings.py - Verifique
TEMPLATES['DIRS']emsettings.py
Solução:
- Verifique se o ambiente virtual está ativado
- Verifique se o módulo está no
PYTHONPATH - Verifique
INSTALLED_APPSemsettings.py
Solução:
- O projeto usa
America/Sao_Paulo - Verifique
TIME_ZONEemsettings.py - Use
USE_TZ = Truepara timezone-aware datetimes
- Consulte a documentação do Django
- Consulte a documentação de arquitetura
- Consulte a revisão do banco de dados
- Abra uma issue no repositório
- Verifique se o bug já foi reportado
- Crie uma issue com:
- Descrição clara do problema
- Passos para reproduzir
- Comportamento esperado vs. atual
- Versão do Python, Django, etc.
- Logs relevantes
- Fork o projeto
- Crie uma branch:
git checkout -b feature/nova-funcionalidade - Desenvolva: Implemente sua funcionalidade
- Teste: Certifique-se de que os testes passam
- Commit:
git commit -m "Adiciona nova funcionalidade" - Push:
git push origin feature/nova-funcionalidade - Pull Request: Abra um PR para revisão
- Seguir PEP 8
- Usar type hints quando possível
- Documentar funções e classes
- Máximo 120 caracteres por linha
- Seguir convenções do Django
- Usar class-based views quando apropriado
- Separar lógica de negócio em services.py
- Validar dados em forms.py
- Usar Tailwind CSS para estilização
- JavaScript vanilla (sem frameworks)
- Seguir convenções de nomenclatura
- Comentar código complexo
- Escrever testes para novas funcionalidades
- Manter cobertura acima de 85%
- Testar casos de erro e edge cases
- Usar nomes descritivos para testes
- Atualizar README.md se necessário
- Documentar novas funcionalidades
- Adicionar comentários em código complexo
- Atualizar docstrings
- PRs são revisados antes de merge
- Responder a comentários de revisão
- Fazer alterações solicitadas
- Manter PRs pequenos e focados
Este projeto é propriedade da Universidade de Rio Verde (UniRV) e está destinado ao uso do AgroHub - Hub de Inovação e Fomento.
UniRV - Universidade de Rio Verde
- AgroHub - Hub de Inovação e Fomento
- YPETEC - Incubadora de Startups UniRV
- InovaLab - Laboratório de Desenvolvimento Tecnológico
- Comunidade Django
- Desenvolvedores de todas as bibliotecas utilizadas
- Contribuidores do projeto
- Documentação do Django
- Documentação do Tailwind CSS
- Índice da Documentação - Índice completo de toda a documentação
- Arquitetura do Sistema - Visão geral da arquitetura
- Schema do Banco de Dados - Diagrama do schema
- Arquitetura de Deploy - Arquitetura de deployment
- Revisão do Banco de Dados - Análise detalhada da estrutura do banco de dados
- Revisão das Migrações - Análise completa das migrações do Django
- Documentação de Testes - Guia completo para testes
- CHANGELOG - Histórico de versões e mudanças
Para dúvidas, sugestões ou problemas:
- Email: Entre em contato através do departamento de tecnologia da UniRV
- Repositório: Consulte o repositório Git do projeto
- Documentação: Consulte este README e os documentos de revisão (DATABASE_REVIEW.md, MIGRATION_REVIEW.md)
Última atualização: 2025-01-15
Versão: 1.0.0
Desenvolvido com ❤️ pela equipe UniRV