Aplicacao web para catalogo e contato da Artes da Fafa. O repositorio implementa um backend em Flask responsavel pela entrega da shell HTML, exposicao das rotas HTTP e integracao opcional com SMTP, enquanto a experiencia principal do cliente e entregue por uma SPA em Vue 3 compilada com Vite.
- Backend HTTP em Flask com rotas HTML e JSON.
- Frontend SPA em Vue 3 com Vue Router.
- Fallback server-rendered em
templates/app.htmlquando o bundle do frontend nao esta disponivel. - Catalogo de produtos mantido no backend como fonte primaria dos dados.
- Fluxo de contato com validacao de entrada e tentativa opcional de envio de e-mail de confirmacao.
O backend esta centralizado em app.py. As responsabilidades principais sao:
- configurar a aplicacao Flask;
- manter a lista
PRODUCTS, usada como source of truth do catalogo; - serializar produtos para o contrato da API;
- validar e processar requisicoes de contato;
- detectar se a interface deve ser entregue pelo Vite em desenvolvimento, pelo build estatico do frontend ou pelo fallback em template.
O frontend fica em frontend/ e usa:
Vue 3para composicao da interface;Vue Routerpara as rotas/e/galeria;Vitepara servidor de desenvolvimento e build de producao.
Pontos principais:
frontend/src/main.jsinicializa a aplicacao e registra o router.frontend/src/router/index.jsdefine as rotas da SPA.frontend/src/components/ImageGallery.vueconsome a API de produtos, aplica filtro por categoria e busca textual, e controla o modal de imagens.frontend/src/components/ContactForm.vueenvia o formulario para a API de contato sem recarregar a pagina.frontend/src/services/api.jsencapsula as chamadas HTTP do cliente.
O template templates/app.html funciona como shell de entrega. Em runtime, a rota principal segue esta ordem:
- Se
VITE_DEV_SERVERestiver definido, carrega os modulos do servidor Vite. - Se existir build em
static/frontend/assets/, carrega os assets compilados. - Caso contrario, usa o markup HTML com JavaScript embutido como fallback funcional.
Essa estrategia permite desenvolver a SPA de forma desacoplada sem perder a capacidade de servir uma versao funcional diretamente pelo Flask.
- Python
3.11+ - Node.js
18+recomendado - npm
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txtcd frontend
npm install
cd ..Terminal 1:
cd frontend
npm run devTerminal 2:
$env:VITE_DEV_SERVER="http://127.0.0.1:5173"
python app.pyEsse modo usa o fallback em template quando nenhum bundle do frontend estiver disponivel:
python app.pycd frontend
npm run build
cd ..
python app.pyAplicacao local:
http://127.0.0.1:5000
Variaveis reconhecidas pela aplicacao:
SECRET_KEY: chave de sessao do Flask.LOG_LEVEL: nivel de log usado emlogging.basicConfig.VITE_DEV_SERVER: origem do servidor Vite em desenvolvimento.SMTP_HOST: host SMTP.SMTP_PORT: porta SMTP.SMTP_USERNAME: usuario SMTP.SMTP_PASSWORD: senha SMTP.SMTP_FROM: remetente usado na confirmacao por e-mail.
Quando a configuracao SMTP esta incompleta, a API de contato continua respondendo com sucesso, mas retorna emailConfirmationSent: false e inclui uma mensagem informativa no payload.
Entrega a shell principal da aplicacao. Dependendo do ambiente, pode carregar:
- a SPA via Vite;
- a SPA compilada;
- o fallback HTML server-rendered.
Entrega a mesma shell da aplicacao para a rota de galeria. No modo SPA, o roteamento final e resolvido no cliente por Vue Router.
Retorna a lista completa de produtos serializados.
Query params suportados:
product: filtra por nome exato da categoria, com comparacao case-insensitive.
Exemplo:
GET /api/products?product=AmigurumiResposta:
{
"items": [
{
"id": "amigurumi",
"name": "Amigurumi",
"description": "Personagens fofos e personalizados para colecao, decoracao ou presente.",
"category": "Amigurumi",
"images": [
{
"src": "/static/images/amigurumi-1.jpg",
"alt": "Amigurumi - foto 1"
}
]
}
],
"categories": ["Croche fino", "Barbantes", "Bordados variados", "Amigurumi"],
"selectedCategory": "Amigurumi"
}Aceita application/json e tambem dados de formulario tradicionais. Campos esperados:
nameemailmessage
Regras de validacao:
namee obrigatorio;emaildeve obedecer ao regex definido emis_valid_email.
Resposta de sucesso:
{
"message": "Obrigada! Seu pedido foi recebido e entraremos em contato em breve.",
"emailConfirmationSent": false,
"info": "Nao foi possivel enviar a confirmacao por e-mail neste momento."
}Codigos retornados:
201para envio aceito;400para erro de validacao.
app.py
requirements.txt
README.md
frontend/
package.json
vite.config.js
src/
App.vue
main.js
router/
services/
views/
components/
assets/styles/
templates/
app.html
index.html
static/
styles.css
images/
tests/
test_app.py
Locais mais relevantes para manutencao:
app.py: rotas, serializacao, validacoes e SMTP.frontend/src/views/: composicao das paginas.frontend/src/components/: galeria, modal, feedback visual e formulario.frontend/src/services/api.js: camada de acesso HTTP no cliente.templates/app.html: shell de integracao entre Flask e frontend.static/images/: acervo de imagens.
A suite atual cobre disponibilidade da home, filtro da API, validacao de e-mail e comportamento sem SMTP.
Execucao:
python -m unittest discover -s tests -vResultado validado em 2026-08-06:
Ran 6 tests in 0.050s
OK
- O catalogo de produtos ainda esta hardcoded no backend.
requirements.txtlista apenas Flask; dependencias de desenvolvimento e frontend sao gerenciadas separadamente.- O fallback HTML embutido em
templates/app.htmlduplica parte do comportamento da SPA, o que aumenta o custo de manutencao caso as duas experiencias evoluam em paralelo.


