Repository navigation
Arquitetura
Visão geral de como o website é montado e de onde vêm os dados. Para rodar o projeto, veja Setup local.
┌────────────────────────── website (Next.js 12) ──────────────────────────┐
navegador ───────► │ pages/*.js ── getStaticProps / getServerSideProps │
(basedosdados.org, │ │ │
data-basis.org, │ ├── importa funções de pages/api/* (no servidor, sem HTTP) │
basedelosdatos) │ │ │
│ componentes ── fetch("/api/...") ──► pages/api/* (rotas Next) │
└──────────────────────────────────────┬───────────────────────────────────┘
│
┌───────────────────────────────────┼─────────────────────────┐
▼ ▼ ▼
backend (Django/GraphQL) API do chatbot Google Cloud Storage
${NEXT_PUBLIC_API_URL}/api/v1/graphql ${CHATBOT_URL} (download de tabelas)
-
Front-end: Next.js 12 com pages router, React 17 e Chakra UI v1. O build usa
output: "standalone"e roda num container Node 20. -
Dados: quase tudo vem do backend, via GraphQL em
${NEXT_PUBLIC_API_URL}/api/v1/graphql. -
Conteúdo estático: blog (
next/blog/{pt,en,es}), documentação, FAQ, termos e guias de uso (next/content/) ficam no próprio repositório.
| Pasta | O que tem |
|---|---|
pages/ |
Páginas (uma rota por arquivo) e as rotas de API em pages/api/
|
pages/api/ |
Rotas Next que falam com o backend, o chatbot ou o GCS. Organizadas por domínio: user, datasets, tables, stripe, chatbot, blog, team, etc. |
components/ |
Componentes em atomic design: atoms, molecules, organisms, templates
|
hooks/ |
Hooks React (chatbot, testes A/B, checkout, detecção de mobile) |
context/ |
Contextos React (ChatbotContext) |
lib/ |
Autenticação no servidor (authCookie.js, requireChatbotAuth.js) |
content/ |
Conteúdo em JS/markdown: docs, FAQ, termos, guias, case studies, BD Pro |
blog/ |
Posts do blog em markdown, um diretório por idioma |
public/ |
Imagens, ícones e as traduções em public/locales/{pt,en,es}
|
styles/ |
globals.css e CSS modules |
utils.js |
Funções compartilhadas (domínio atual, cookie do usuário, campanhas) |
Existem dois caminhos, e ambos passam por pages/api/:
-
No servidor (build ou request): a página importa a função exportada pelo arquivo de
pages/api/e chama direto, sem HTTP. Exemplo:pages/dataset/[dataset].jsimportagetUserGuidedepages/api/datasets/getUserGuide. -
No navegador: o componente faz
fetch("/api/...")e a rota Next repassa ao backend, anexando o token do cookie.
As rotas montam a query GraphQL e chamam o backend com axios ou graphql-request. Por exemplo, pages/api/stripe/createSubscription.js chama a mutation createStripeSubscription.
| Estratégia | Páginas |
|---|---|
ISR (revalidate: 30) |
index, dataset/[dataset] (com fallback: "blocking"), case-studies/[id], bdpro, services, faq, chatbot-lp
|
| SSG |
blog/*, docs/[slug], search, prices, contact, terms, user/login, user/register, entre outras |
SSR (getServerSideProps) |
user/index, user/[username], user/activate-account, user/password-recovery, about-us, invited-researchers
|
Todas as páginas chamam serverSideTranslations para carregar as traduções. Veja Internacionalização.
O padrão é useState/useEffect com fetch. O React Query (@tanstack/react-query, configurado em pages/_app.js com staleTime de 5 min) hoje só é usado pelo chatbot (useThreads, useChatbotAuth).
O backend emite um JWT. O website guarda esse token num cookie httpOnly e todas as chamadas autenticadas passam pelas rotas pages/api/.
login ──► /api/user/getToken ──► mutation authToken ──► Set-Cookie: token (httpOnly, 7 dias)
+ cookie userBD (dados do usuário, legível no JS)
requisição autenticada ──► /api/... ──► getTokenFromRequest(req) ──► Authorization: Bearer <token> ──► backend
-
lib/authCookie.js: cria e limpa o cookietoken(httpOnly,sameSite: lax,secureem produção).getTokenFromRequestlê o token, nesta ordem, do headerAuthorization: Bearer, do cookietokenou do corpo da requisição. -
Rotas de sessão:
getToken(login),refreshToken,setSession,clearSessionevalidateToken, empages/api/user/. -
validateToken: valida o token com a mutationverifyTokendo backend e devolvehas_chatbot_access. -
Páginas protegidas: as páginas SSR, como
user/index.js, leemreq.cookies, chamam/api/user/validateTokene redirecionam para o login se o token for inválido. -
Chatbot: as rotas
pages/api/chatbot/*usamrequireChatbotAuth(req), que retorna 401 sem token válido e 403 semhas_chatbot_access. -
No cliente:
getUserFromCookie()eclearClientSession(), emutils.js, leem e limpam o cookieuserBD.
middlewares/authUser.jsecontext/user.jsnão são importados por nenhuma página. São código legado.
-
next-i18next, com a configuração emnext-i18next.config.js. Os locales sãopt(padrão),enees, e cada idioma tem seu próprio domínio (i18n.domains). - As traduções ficam em
public/locales/<idioma>/<namespace>.json. - Cada imagem Docker é construída com um
NEXT_PUBLIC_DOMAIN.getDomain()eisBasedosdadosDomain(), emutils.js, usam esse valor para mostrar conteúdo específico de cada domínio. Por exemplo, consultoria só aparece embasedosdados.org. - Em
next.config.js, o produto Pro se chama/bdproempt/ese/dbproemen, por meio de rewrite e redirect.
| Serviço | Onde | Variável |
|---|---|---|
| Backend GraphQL | quase todas as rotas de pages/api/
|
NEXT_PUBLIC_API_URL |
| Stripe |
components/organisms/PaymentSystem.js + pages/api/stripe/*
|
NEXT_PUBLIC_KEY_STRIPE |
| API do chatbot | pages/api/chatbot/* |
CHATBOT_URL |
| Google Cloud Storage | pages/api/tables/downloadTable.js |
URL_DOWNLOAD_OPEN, URL_DOWNLOAD_CLOSED
|
| Google Tag Manager / Meta Pixel |
pages/_app.js, carregados conforme o ambiente |
— |
A lista completa de variáveis está no README.